我想访问QThread
类中的父类窗口小部件
这一行给出了挂起的GUI“Example()。setWindowTitle(”Window“)”
我怎样才能做到这一点?
class Example(QWidget):
def __init__(self):
super().__init__()
self.myclass2 = myclass2()
self.myclass2.start()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('web.png'))
self.show()
class myclass2(QThread):
def __init__(self, parent=None):
super(myclass2, self).__init__(parent)
def run(self):
while True:
time.sleep(.1)
print(" in thread \n")
Example().setWindowTitle("Window")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
您必须了解以下表达式:
Example().setWindowTitle("Window")
它相当于:
obj = Example()
obj.setWindowTitle("Window")
也就是说,您正在创建除ex = Example()
之外的另一个Example对象,并且该对象正在创建另一个myclass2
对象,而其他myclass2
对象正在创建另一个示例,并且显然正在创建无限循环。
将来可能导致问题的另一件事是为不同的事物建立相同的名称,虽然在这种情况下它不是问题,但在将来的情况下它可能会给你带来问题,我所指的代码是:
self.myclass2 = myclass2()
例如,建议类应以大写字母开头。
另一个仅在Qt中有效的错误是无法在主线程以外的线程中创建或操作GUI。所以你不能直接在另一个线程中更改标题,但有两种方法:
QMetaObject::invokeMethod(...)
但为此我们必须通过属性传递GUI:
class Example(QWidget):
def __init__(self):
super().__init__()
self.myclass2 = MyClass()
self.myclass2.gui = self
self.myclass2.start()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('web.png'))
self.show()
class MyClass(QThread):
def run(self):
while True:
time.sleep(.1)
print(" in thread \n")
QMetaObject.invokeMethod(self.gui, "setWindowTitle", Qt.QueuedConnection, Q_ARG(str, "Window"))
class Example(QWidget):
def __init__(self):
super().__init__()
self.myclass2 = MyClass()
self.myclass2.titleChanged.connect(self.setWindowTitle)
self.myclass2.start()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('web.png'))
self.show()
class MyClass(QThread):
titleChanged = pyqtSignal(str)
def run(self):
while True:
time.sleep(.1)
print(" in thread \n")
self.titleChanged.emit("Window")
更多:
您不应该直接从线程修改GUI,而是通过信号发送数据:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Example(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()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QtGui.QIcon('web.png'))
self.show()
class MyClass(QtCore.QThread):
titleChanged = QtCore.pyqtSignal(str)
infoChanged = QtCore.pyqtSignal(str) # <-- create signal
def run(self):
counter = 0
while True:
QtCore.QThread.msleep(100)
print(" in thread \n")
self.titleChanged.emit("Window")
self.infoChanged.emit("{}".format(counter)) # <-- emit signal
counter += 1
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())