Qthread中父类的Python访问小部件

Qthread中父类的Python访问小部件,python,pyqt,pyqt5,qthread,Python,Pyqt,Pyqt5,Qthread,我想访问QThread类中的父类小部件 此行给出了挂起GUI“示例().setWindowTitle(“窗口”)” 我该怎么做 class Example(QWidget): def __init__(self): super().__init__() self.myclass2 = myclass2() self.myclass2.start() self.initUI() def initUI(self):

我想访问
QThread
类中的父类小部件

此行给出了挂起GUI“示例().setWindowTitle(“窗口”)”

我该怎么做

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()
,该对象正在创建另一个
myclass2
对象,而另一个
myclass2
对象正在创建另一个示例,显然正在创建一个无限循环


将来可能会给您带来问题的另一件事是为不同的事物建立相同的名称,虽然在这种情况下这不是问题,但在将来的情况下它可能会给您带来问题,我所指的代码是:

self.myclass2 = myclass2()
例如,建议类以大写字母开头


另一个仅在Qt中有效的错误是不能在主线程以外的线程中创建或操作GUI。因此,您不能在其他线程中直接更改标题,但有两种方法:

1. <代码>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"))
2.信号和插槽 加号:

您不应直接从线程修改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_())
导入系统 从PyQt5导入QtCore、QtGui、QtWidgets 类示例(qtwidts.QWidget): 定义初始化(自): super()。\uuuu init\uuuuu() lay=qtwidts.QVBoxLayout(self) le=QtWidgets.QLineEdit() lay.addWidget(le) self.myclass2=MyClass() self.myclass2.titleChanged.connect(self.setWindowTitle)
self.myclass2.infoChanged.connect(le.setText)#实际上,我想使用新线程来更新类的小部件,是否可以通过基本的python线程呢?实际上,我想知道由类示例创建的新线程,在这个线程中,我想运行一个while循环,这个循环必须在一个fix intervalI更新一个lineEdit,我不知道如何获得这个访问权限来修改这个新的GUI中的lineEditthread@aditya我已经添加了一个例子,说明您应该如何从另一个线程更新QLineEdit,阅读我的答案,理解它,练习它,修改它。如果我的答案对您有帮助,请不要忘记将其标记为正确,如果您不知道如何做,请回顾,这是感谢我为帮助您所做工作的最好方式。谢谢您的回答,我很困惑,但谢谢您的指导
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_())