my python program consist of a server socket and a GUI. If a new client connects to the server, a new slider should be added to the GUI. The received data of the client should change the position of the slider.
My problem is, that the call of the method "addSlider" makes the GUI freeze. I noticed that it freezes as long as the server thread, which called the method, stops.
To make it simpler I made a Test thread instead of the server thread
Do you have any suggestion how I can add the slider properly?
Main Thread:
g = GUI()
t = Test(g.addSlider)
g.start()
t.start()
Test Class:
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:
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)
class Window(wx.Frame):
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()
ControlPanel Class:
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()
The problem is almost certainly that you are starting the wx.App
from within a Python thread. This is backwards. The App object should be the main thread and spawn off all other threads as needed. Create a sub-class of wx.App
instead and then create a different thread if you need one.
Note that when using threads, you must use wxPython's thread-safe methods to communicate from the thread back to wxPython. The following methods are thread-safe:
Here are a few links with more information: