简体   繁体   English

QObject:无法为不同线程中的父级创建子级。 PyQt5

[英]QObject: Cannot create children for a parent that is in a different thread. PyQt5

When I try to change the text of a text browser which is inside a scroll area I get this PyQt5 threading error:当我尝试更改滚动区域内的文本浏览器的文本时,出现此 PyQt5 线程错误:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x212e3bb1f50), parent's thread is QThread(0x212e171e220), current thread is QThread(0x212e41dc7e0)

I assume it is because of the scroll area and that I don't have access to it from the thread I am trying to change this from and it works if I put the same bit of code...我认为这是因为滚动区域,我无法从我试图更改它的线程访问它,如果我输入相同的代码,它就可以工作......

filepath = "..."
with open(filepath, "r") as f:
    contents = f.read()
    #print(contents)
    self.log_1.setText(contents)

(and yes I am aware that the filepath is "...", used for file security.)...inside the thread that the scrollarea is created inside it works completely fine. (是的,我知道文件路径是“...”,用于文件安全性。)...在创建滚动区域的线程内部完全可以正常工作。

The only thing I don't know is how to fix this.我唯一不知道的是如何解决这个问题。 I think you might be able to inherit the thread to the scroll area in someway, idk.我认为您可能能够以某种方式将线程继承到滚动区域,idk。

My code, but simplified:我的代码,但简化了:

from PyQt5 import QtCore, QtGui, QtWidgets
from mcstatus import MinecraftServer
import threading

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1379, 523)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.scrollArea_1 = QtWidgets.QScrollArea(self.S1)
        self.scrollArea_1.setGeometry(QtCore.QRect(0, 20, 981, 341))
        self.scrollArea_1.setWidgetResizable(True)
        self.scrollArea_1.setObjectName("scrollArea_1")
        self.scrollAreaWidgetContents_1 = QtWidgets.QWidget()
        self.scrollAreaWidgetContents_1.setGeometry(QtCore.QRect(0, 0, 979, 339))
        self.scrollAreaWidgetContents_1.setObjectName("scrollAreaWidgetContents_1")
        self.log_1 = QtWidgets.QTextBrowser(self.scrollAreaWidgetContents_1)
        self.log_1.setGeometry(QtCore.QRect(0, 0, 981, 341))
        self.log_1.setMinimumSize(QtCore.QSize(981, 341))
        self.log_1.viewport().setProperty("cursor", 
        QtGui.QCursor(QtCore.Qt.IBeamCursor))
        self.log_1.setObjectName("log_1")
        self.scrollArea_1.setWidget(self.scrollAreaWidgetContents_1)

    def update1(self, MainWindow):

        threading.Timer(0.2, self.update1, {MainWindow: MainWindow}).start()

        ip = "..."
        port = 25565 #Server 1
        server = MinecraftServer(ip, port)

        try:



            filepath = "..."
            with open(filepath, "r") as f:
                contents = f.read()
                #print(contents)
                self.log_1.setText(contents)



        except IOError as e:

            self.StatusL_1.setText(self.translate("MainWindow", "<html><head/><body><p><span style=\" font-size:18pt;\">Status: Off</span></p></body></html>"))
        else:
            self.StatusL_1.setText(self.translate("MainWindow", "<html><head/><body><p><span style=\" font-size:18pt;\">Status: On</span></p></body></html>"))

You should not directly modify the GUI from another thread, one way to modify the GUI indirectly from another thread is to use the Qt signals:您不应该直接从另一个线程修改 GUI,从另一个线程间接修改 GUI 的一种方法是使用 Qt 信号:

import threading
from PyQt5 import QtCore, QtGui, QtWidgets
from mcstatus import MinecraftServer


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        # ...


class Worker(QtCore.QObject):
    logged = QtCore.pyqtSignal(str)
    statusChanged = QtCore.pyqtSignal(bool)

    def start(self):
        threading.Timer(0.2, self._execute, daemon=True).start()

    def _execute(self):
        threading.Timer(0.2, self._execute, daemon=True).start()
        ip = "..."
        port = 25565  # Server 1
        server = MinecraftServer(ip, port)

        try:
            filepath = "..."
            with open(filepath, "r") as f:
                contents = f.read()
                self.logged.emit(contents)
        except IOError as e:
            self.statusChanged.emit(False)
        else:
            self.statusChanged.emit(True)


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        self.worker = Worker()
        self.worker.logged.connect(self.log_1.setText)
        self.worker.statusChanged.connect(self.on_status_changed)
        self.worker.start()

    @QtCore.pyqtSlot(bool)
    def on_status_changed(self, status):
        text = '<html><head/><body><p><span style=" font-size:18pt;">Status: {}</span></p></body></html>'.format(
            "On" if status else "Off"
        )
        self.StatusL_1.setText(text)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 PyQt5 QObject:无法为处于不同线程中的父级创建子级 - PyQt5 QObject: Cannot create children for a parent that is in a different thread Python PyQt5 线程 QObject:无法为不同线程中的父级创建子级 - Python PyQt5 threading QObject: Cannot create children for a parent that is in a different thread PyQt5 无法从线程更新进度条并收到错误“无法为不同线程中的父级创建子级” - PyQt5 cannot update progress bar from thread and received the error “Cannot create children for a parent that is in a different thread” 使用pyqt5和sqlite的python程序出错,无法为不同线程中的父级创建子级 - Error with python program with pyqt5 and sqlite, Cannot create children for a parent that is in a different thread PyQt4和flask:无法为处于不同线程中的父级创建子级 - PyQt4 & flask : Cannot create children for a parent that is in a different thread QObject:无法为处于不同线程中的父级创建子级。父级是QTextDocument,父级的线程是QThread,当前线程是QThread - QObject:Cannot create children for a parent that is in different thread.Parent is QTextDocument,parent's thread is QThread,current thread is QThread PyQt5:如何将QObject移动到主线程? - PyQt5: How to move a QObject to the main thread? QObject::setParent:无法设置父级,新父级在 Python 中的不同线程中 - QObject::setParent: Cannot set parent, new parent is in a different thread in Python PyQt多线程,无法为父级创建子级 - PyQt Multi Threading, Cannot create children for a parent PyQt5中的QObject,pyqtSignal - QObject, pyqtSignal in PyQt5
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM