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