I've written a program that uses tkinter to create a GUI, and in the GUI I have a button that starts a program that connects to a socket and reads in messages with signal information. I needed this to happen constantly in the background, because I had other functionality I needed accessible on the GUI, but the GUI would be locked.
So I wrote code that would run that button in a new thread.
# Run everything after connect in a separate thread, so the GUI is not locked
def _start_connect_thread(self, event):
HOST = self.ip_e.get()
PORT = int(self.port_e.get())
global connect_thread
connect_thread = threading.Thread(target=self.connect, kwargs={'host': HOST, 'port': PORT})
connect_thread.daemon = True
connect_thread.start()
# Connect TaskTCS and StreamingDataService to AIMS
def connect(self, host=None, port=None):
print("Connecting sensor tasking program to AIMS...")
self.tt = TaskTCS(host, port)
print("Connecting streaming data program to AIMS...")
self.sd = StreamingData(host, port)
# Run Streaming Data Service, which will pull all streaming data from sensor
self.sd.run()
With this code, my GUI is free to perform other tasks. Most importantly, I can press a button that plots the data coming in from the sensor. When I press the plot button, a flag is toggled in the sd class, and it uses the information coming from the sensor to plot it with matplotlib. Inside the sd class is a function that is running on a while loop, unpacking information from the sensor and checking if the flag is toggled in order to know when to plot it.
Is this not thread safe?
The reason I ask is this program works perfectly fine on the machine I'm working on. However, when I try to run this with anaconda3 python, I get these errors.
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
I'm not sure if these errors are from anaconda, or if it's from non-thread-safe coding.
When this program was attempted to run on a machine that had python 2.6, it got this error when clicking the connect button:
Exception in thread Thread-1:
Trackback (most recent call last):
File .usr/lib64/python2.6/threading.py line 532 in _bootstart_inner self.run()
File /usr/lib64/python2.6/threading.py, line 484, in run self._target(*self._args, **self._kwargs)
File “WaterfallGUI.py”, line 282 in connect HOST = self.ip_e.get()
File “/usr/lib64/python2.6/lib-tk/Tkinter.py”, line 2372, in get return self.tk.call(self._w,’get’)
TclError: out of stack space (infinite loop?)
So can a program somehow not have issues with threads on one machine but it can on others?
Note: In an attempt to solve the second error, I moved the .get() functions in the _start_connect_thread function to before actually starting the thread. Before, I was calling those functions in connect. Because I'm calling tkinter getters in a different thread, could that have been the issue in that case? If so, why wouldn't it cause an error on my machine on python 2.7? This was the old code:
def _start_connect_thread(self, event):
global connect_thread
connect_thread = threading.Thread(target=self.connect)
connect_thread.daemon = True
connect_thread.start()
def connect(self):
HOST = self.ip_e.get()
PORT = int(self.port_e.get())
...
I don't believe I'm calling anything tkinter GUI related outside of the main loop in the rest of my code. I see stuff about queues but I can't tell if I need to implement that in my code.