Qt Designer - avoiding 'different thread' type errors
-
Am trying to create a simple Python dashboard with a bar chart using Qt Designer (output saved as levels.ui) but am getting 'Timers cannot be started from another thread' and similar errors when attempting to display the dashboard window.
The dashboard uses a few standard display widgets, with a QWidget promoted as a pyqtgraph in order to display a bar chart. This is referenced in the Ui_MainWindow class that is generated buy Qt Designer with the name graphWidget, e.g. self.graphWidget = PlotWidget(self.centralwidget)The class in the application used to display the dashboard starts with:
from PyQt5 import QtCore, QtGui, QtWidgets, uic
import pyqtgraph as pgapp = QtWidgets.QApplication(sys.argv)
class MyApp(QtWidgets.QMainWindow):
def init(self, *args, **kwargs):
super(MyApp, self).init(*args, **kwargs)
uic.loadUi("/media/sam/venvs/tankdisplay/levels.ui",self)
bargraph = pg.BarGraphItem(x=list(range(-2,-62,-2)), height=[0]*30, width=1.5, brush='b')
self.graphWidget.addItem(bargraph)
self.graphWidget.setXRange(-60,-2, padding = 0.1)
self.graphWidget.setYRange(0,10, padding = 0.1)
self.graphWidget.setTitle("Bucket Tips")
self.graphWidget.setLabel('left', 'Tips')
self.graphWidget.setLabel('bottom', 'Minutes')
self.graphWidget.setBackground((138,69,19))def plotvals(self,y):
bargraph = pg.BarGraphItem(x=list(range(-2,-62,-2)), height=y, width=1.5, brush='b')
self.graphWidget.addItem(bargraph).
.
.
uim = MyApp()
uim.show()The dashboard displays but 'Timers cannot be started from another thread' type errors occur when plotvals(data) method of MyApp is invoked from another part of the Python script (responding to MQTT data received), e.g. uim.plotvals(rainlist). Also if code is added to plotvals that changes some of the bar chart properties it causes segmentation fault crashes due to 'Cannot create children for a parent that is in a different thread' errors.
Is there some way to avoid these errors by avoiding multiple threads, or some other simple approach?
Am very new to PyQt5, really just trying to use it simply to create a simple data display, without getting too deeply into its operation.
Hope the above make sense.
Thanks. -
@kiwironnie
You cannot create/access/use Qt objects like UI elements or timers from a thread other than where they were created (or possibly moved to), which is what the runtime error message is telling you. So where do your secondary threads come into play and why are they trying to access objects from a different thread? Qt Designer does not cause this, -
Thanks JonB,
That's helpful to know that Qt Designer is not itself creating multiple threads.So the problem then must be due to uim.plotvals(rainlist) being called from another Python thread rather than my tunnel vision assumption of a threading issue in the UI! As follows:
def on_message_lh(mqtt_lasthoursrain, obj, msg):
print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
data = json.loads(msg.payload.decode('utf-8'))
if data is not None:
rainlist = []
for i in range(len(data)):
rainlist.append(data[i])
uim.plotvals(rainlist)where on_message_lh(mqtt_lasthoursrain, obj, msg) is in a different paho-mqtt loop, or thread than the UI.
So to get this working going to have to familiarise with how to pass data to PyQt objects across threads.
-
Hi and welcome to devnet,
The most simple is the worker object approached and use signals and slots to transmit your data.
-
@SGaist said in Qt Designer - avoiding 'different thread' type errors:
worker object approached and use signals and slots to transmit your data
Thanks, am searching for some good tutorials to familiarise with workers, signals and slots.
-
The QThread documentation is now a pretty good starting point.
-
@SGaist
My intent was to provide the working code here from the results of my familiarising with signals, connect, emits, possibly to help others with a probably not very well coded but working example, but I've now run into a different problem. Have opened a new forum topic for this.
'Multiple Threads (with Paho MQTT) - UI Window now not refreshing'.