Python Access Widgets Of Parent Class In Qthread
Solution 1:
You must understand the following expression:
Example().setWindowTitle("Window")
it is equivalent to:
obj = Example()
obj.setWindowTitle("Window")
That is, you are creating another Example object other than ex = Example()
, and that object is creating another myclass2
object, and that other myclass2
object is creating another Example, and an infinite loop is clearly being created.
Another thing that in the future could cause you problems is to establish the same name for different things, although in this case it is not a problem but in future occasions it could bring you problems, the code to which I refer is:
self.myclass2 = myclass2()
For example, it is recommended that classes should start with capital letters.
Another error that is valid only in Qt is that the GUI can not be created or manipulated in a thread other than the main thread. So you can not change the title directly in the other thread but there are 2 methods:
1. QMetaObject::invokeMethod(...)
But for this we must pass the GUI through a property:
classExample(QWidget):
def__init__(self):
super().__init__()
self.myclass2 = MyClass()
self.myclass2.gui = self
self.myclass2.start()
self.initUI()
definitUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('web.png'))
self.show()
classMyClass(QThread):
defrun(self):
whileTrue:
time.sleep(.1)
print(" in thread \n")
QMetaObject.invokeMethod(self.gui, "setWindowTitle", Qt.QueuedConnection, Q_ARG(str, "Window"))
2. signals & slots
classExample(QWidget):
def__init__(self):
super().__init__()
self.myclass2 = MyClass()
self.myclass2.titleChanged.connect(self.setWindowTitle)
self.myclass2.start()
self.initUI()
definitUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('web.png'))
self.show()
classMyClass(QThread):
titleChanged = pyqtSignal(str)
defrun(self):
whileTrue:
time.sleep(.1)
print(" in thread \n")
self.titleChanged.emit("Window")
PLUS:
You should not modify the GUI from the thread directly but send the data through a signal:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
classExample(QtWidgets.QWidget):
def__init__(self):
super().__init__()
lay = QtWidgets.QVBoxLayout(self)
le = QtWidgets.QLineEdit()
lay.addWidget(le)
self.myclass2 = MyClass()
self.myclass2.titleChanged.connect(self.setWindowTitle)
self.myclass2.infoChanged.connect(le.setText) # <-- connect signal
self.myclass2.start()
self.initUI()
definitUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QtGui.QIcon('web.png'))
self.show()
classMyClass(QtCore.QThread):
titleChanged = QtCore.pyqtSignal(str)
infoChanged = QtCore.pyqtSignal(str) # <-- create signaldefrun(self):
counter = 0whileTrue:
QtCore.QThread.msleep(100)
print(" in thread \n")
self.titleChanged.emit("Window")
self.infoChanged.emit("{}".format(counter)) # <-- emit signal
counter += 1if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Post a Comment for "Python Access Widgets Of Parent Class In Qthread"