-1

I'm a newbie, so excuses before... I deliberately wanted to create objects (widgets) from a different thread, but pyqt5 doesn't let me do that, here's the error I'm getting,

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)

Here's my code... Is there a way to resolve this ?

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_())

Thanks in advance :)

Arjun S
  • 40
  • 5
  • 1
    Why do you want to create widgets from a different thread? – Heike Aug 21 '20 at 10:00
  • @Heike I wanted to create a Chat application only in LAN, so when a new user created an account, a new QpushButton has to created for all other existing clients that would link to a new textBrowser, so the message from the server about the new client will be sent through a seperate thread, when i try to create a button from this thread, it shoots out this error (even calling another function (actually method) to do this task doesn't help) – Arjun S Aug 21 '20 at 10:27
  • 1
    The usual way to communicate between threads is to use signals and slots. So what you could do is to create a listnerer class that sends a signal whenever a new client is detected and connect this signal to a slot in your main ui class that will actually create the button. – Heike Aug 21 '20 at 10:44

1 Answers1

0

Only I changed threading to QThread and I did a test with the label and it works correctly, see if it works for you now:

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_())
  • This will not execute `func` on the other thread. – Heike Aug 21 '20 at 10:06
  • Hey, @Danixx25 thanks for your time, The script you made changes the text of the label from "hello" to "bye" but does not create a new object from a different thread, but what i needed was a way to create (not edit) new objects from different thread. (i need a way to create the label object from another thread) – Arjun S Aug 21 '20 at 10:34
  • Then explain why it works for me. – Danixx25 Aug 21 '20 at 10:36
  • are you able to see the text browser? I'm able to see only the label when i run your script, after a delay of about 2-3 seconds – Arjun S Aug 21 '20 at 10:41