【问题标题】:PyQt5 assigning objects from different threads [duplicate]PyQt5从不同线程分配对象[重复]
【发布时间】:2020-12-10 16:23:02
【问题描述】:

我是新手,所以请原谅... 我故意想从不同的线程创建对象(小部件),但 pyqt5 不允许我这样做,这是我得到的错误,

QObject::setParent: Cannot set parent, new parent is in a different thread
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QApplication(0x1ce1e54e590), parent's thread is QThread(0x1ce1e457a50), current thread is QThread(0x1ce1fee2e50)

这是我的代码...有没有办法解决这个问题?

from PyQt5 import QtCore, QtGui, QtWidgets
import threading
import sys

class Ui_MainWindow(object):

    def __init__(self):
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.thread = threading.Thread(target = self.func)

    def func(self):
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(170, 160, 256, 192))
        self.textBrowser.setObjectName("textBrowser")

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)
        
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.thread.start()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

提前致谢:)

【问题讨论】:

  • 为什么要从不同的线程创建小部件?
  • @Heike 我只想在局域网中创建一个聊天应用程序,所以当一个新用户创建一个帐户时,必须为所有其他将链接到新 textBrowser 的现有客户端创建一个新的 QpushButton,所以来自服务器的有关新客户端的消息将通过单独的线程发送,当我尝试从该线程创建按钮时,它会发出此错误(甚至调用另一个函数(实际上是方法)来执行此任务也无济于事)
  • 线程间通信的常用方式是使用信号和槽。因此,您可以做的是创建一个侦听器类,该类在检测到新客户端时发送一个信号,并将该信号连接到您的主 ui 类中的一个插槽,该插槽将实际创建按钮。

标签: python multithreading user-interface pyqt5


【解决方案1】:

只有我将线程更改为 QThread 并使用标签进行了测试,它可以正常工作,看看它现在是否适合您:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys


class Ui_MainWindow(object):

     def __init__(self):
         self.centralwidget = QtWidgets.QWidget(MainWindow)
         self.thread = QtCore.QThread()

     def func(self):
         self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
         self.textBrowser.setGeometry(QtCore.QRect(170, 160, 256, 192))
         self.textBrowser.setObjectName("textBrowser")
         self.label.setText("Bye")

     def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)


        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setText("hello")
        self.label.setObjectName("label")
        self.label.setGeometry(QtCore.QRect(160, 120, 231, 16))


        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.thread.started.connect(self.func)
        self.thread.start()

     def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


if __name__ == '__main__':
     app = QtWidgets.QApplication(sys.argv)
     MainWindow = QtWidgets.QMainWindow()
     ui = Ui_MainWindow()
     ui.setupUi(MainWindow)
     MainWindow.show()
     sys.exit(app.exec_())

【讨论】:

  • 这不会在另一个线程上执行func
  • 嘿,@Danixx25 感谢您抽出宝贵时间,您制作的脚本将标签文本从“hello”更改为“bye”,但不会从不同的线程创建新对象,但我需要一种从不同线程创建(而不是编辑)新对象的方法。 (我需要一种从另一个线程创建标签对象的方法)
  • 然后解释为什么它对我有用。
  • 你能看到文本浏览器吗?当我运行你的脚本时,我只能看到标签,延迟大约 2-3 秒
猜你喜欢
  • 1970-01-01
  • 2016-07-09
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
相关资源
最近更新 更多