Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt - Modify GUI from another thread

I'm trying to modify my main layout from another thread. But the function run() is never called and i'm having the error:

QObject::setParent: Cannot set parent, new parent is in a different thread

Here's my code:

class FeedRetrievingThread(QtCore.QThread):
    def __init__(self, parent=None):
        super(FeedRetrievingThread, self).__init__(parent)
        self.mainLayout = parent.mainLayout
    def run(self):
        # Do things with self.mainLayout

class MainWindow(QtGui.QDialog):
    def __init__(self, parent=None):  
        super(MainWindow, self).__init__(parent)
        self.mainLayout = QtGui.QGridLayout() 
        self.setLayout(self.mainLayout)  
        self.feedRetrievingThread = FeedRetrievingThread(self)
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.updateFeed)
        self.timer.start(1000)

    def updateFeed(self):
        if not self.feedRetrievingThread.isRunning():
            print 'Running thread.'
            self.feedRetrievingThread.start()

if __name__ == '__main__':  
    app = QtGui.QApplication(sys.argv)  
    mainWindow = MainWindow()  
    mainWindow.show()
    sys.exit(app.exec_())

I really don't get it, why is it so difficult to access the GUI with PyQt? In C# you have Invoke. Is there anything of the kind in PyQt?

I tried creating the thread directly from MainWindow.__init__ (without using the timer) but it didn't work either.

like image 446
prgDevelop Avatar asked Nov 16 '12 16:11

prgDevelop


1 Answers

In Qt you should never attempt to directly update the GUI from outside of the GUI thread.

Instead, have your threads emit signals and connect them to slots which do the necessary updating from within the GUI thread.

See the Qt documentation regarding Threads and QObjects.

like image 123
ekhumoro Avatar answered Oct 09 '22 18:10

ekhumoro