WxPython-GUI冻结

WxPython-GUI冻结,wxpython,Wxpython,我的python程序由一个服务器套接字和一个GUI组成。 如果新的客户端连接到服务器,则应在GUI中添加新的滑块。 接收到的客户端数据应更改滑块的位置 我的问题是,调用“addSlider”方法会使GUI冻结。 我注意到,只要调用该方法的服务器线程停止,它就会冻结 为了简化,我制作了一个测试线程,而不是服务器线程 你对如何正确添加滑块有什么建议吗 主线程: g = GUI() t = Test(g.addSlider) g.start() t.start() 测试等级: class Test(

我的python程序由一个服务器套接字和一个GUI组成。 如果新的客户端连接到服务器,则应在GUI中添加新的滑块。 接收到的客户端数据应更改滑块的位置

我的问题是,调用“addSlider”方法会使GUI冻结。 我注意到,只要调用该方法的服务器线程停止,它就会冻结

为了简化,我制作了一个测试线程,而不是服务器线程

你对如何正确添加滑块有什么建议吗

主线程:

g = GUI()
t = Test(g.addSlider)
g.start()
t.start()
测试等级:

class Test(threading.Thread):
    def __init__(self, addFunction):
            threading.Thread.__init__(self)
            self.add = True
            self.addFunction = addFunction

    def run(self):
            while True:
                    if self.add:
                            self.addFunction(10)
                            self.add = False
GUI类:

class GUI(threading.Thread):
    def __init__(self, title='New Window'):
        threading.Thread.__init__(self)
        self.ex = wx.App(False)
        self.title = title
        self.window = Window(None, self.title)

    def loop(self):
        self.ex.MainLoop()

    def addSlider(self, newId):
        self.window.addSlider(newId)
类窗口(wx.Frame):


问题几乎可以肯定,您是从Python线程中启动
wx.App
。这是倒退。应用程序对象应该是主线程,并根据需要派生出所有其他线程。改为创建
wx.App
的子类,然后根据需要创建不同的线程

请注意,在使用线程时,必须使用wxPython的线程安全方法从线程通信回wxPython。以下方法是线程安全的:

  • wx.CallAfter
  • wx.CallLater
  • wx.PostEvent
以下是一些链接,提供了更多信息:


您能在单个块中发布整个程序吗?
class Window(wx.Frame):
    def __init__(self, parent, title):
        super(Window, self).__init__(parent, title = title, style= wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.SetSize(wx.Size(300, 500))
        self.SetMinSize(wx.Size(300, 500))
        self.SetBackgroundColour('RED')

        self.rootPanel = wx.Panel(self)
        self.rootPanel.Fit()
        self.rootPanel.SetBackgroundColour('YELLOW')

        self.panelList = []
        self.panelIdList = []

        self.vbox = wx.BoxSizer(wx.HORIZONTAL)
        self.vbox.Fit(self)

        self.rootPanel.SetSizer(self.vbox)

        self.Centre()
        self.Show(True)

    def addSlider(self, sldId):
        minSize = 130 * (len(self.panelList)+1)

        if minSize < 300:
            minSize = 300

        self.SetSize(wx.Size(minSize, 500))
        self.SetMinSize(wx.Size(minSize, 500))

        cpnl = ControlPanel(self.rootPanel, 500, sldId)

        self.panelIdList.append(sldId)
        self.panelList.append(cpnl)

        self.vbox.Add(self.panelList[len(self.panelList)-1], 1, wx.ALL|wx.ALIGN_CENTER)
        self.vbox.Layout()
        self.vbox.Fit(self)

        self.rootPanel.Layout()
        self.Layout()
class ControlPanel(wx.Panel):
    def __init__(self, parent, newHeight, newId):
        wx.Panel.__init__(self, parent, -1, size=wx.Size(100, newHeight), style=wx.ALIGN_CENTER)
        self.id = newId

        self.lbl = wx.StaticText(self, label = ("ID = " + str(newId)), name = ("ID = " + str(newId)), style = wx.ALIGN_CENTRE_HORIZONTAL)

        self.sld = wx.Slider(self, value = 10, size = wx.Size(100, newHeight-100), minValue = 0, maxValue = 255, style = wx.SL_VERTICAL|wx.SL_MIN_MAX_LABELS|wx.SL_INVERSE)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.lbl, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM | wx.TOP, 20)
        self.sizer.Add(self.sld, 1, wx.ALIGN_CENTER | wx.LEFT, 30)

        self.sizer.Fit(parent)
        self.SetSizer(self.sizer)

        self.sizer.Layout()
        self.Layout()