Mark
Mark

Reputation: 6321

Multithreading with pyqt - Can't get the separate threads running at the same time?

I am trying to get a PyQT GUI running ontop of my python application and I have tried to get it separated into 2 threads so the GUI would be responsive while my main running loop goes, but I have not been able to get it going. Maybe I am misunderstanding it. Here is what I've tried:

My Window and Worker thread are defined as follows:

class Window(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.thread = Worker()

        start = QPushButton("Start", self)
        QObject.connect(start, SIGNAL("clicked()"), MAIN_WORLD.begin)

        hbox = QVBoxLayout(self)
        hbox.addStretch(4)

class Worker(QThread):
    def __init__(self, parent = None):
        QThread.__init__(self, parent)

if __name__ == '__main__':
    MAIN_WORLD = World()
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

which seems to follow very closely to online examples. My World class is running a loop that is infinite once the user clicks "Start" until it's clicked again. Here is part of the definition of it.

class World(QThread):
    def __init__(self, parent = None):
        QThread.__init__(self, parent)
        self.currentlyRunning = False
        //snip

    def begin(self):
        if self.currentlyRunning:
            self.currentlyRunning = False
        else:
            self.currentlyRunning = True
            self.MethodThatDoesUsefulStuff()

edit: I have noticed that I'm not really "using" my worker thread. How do I create my world thread as a worker thread?

Upvotes: 4

Views: 1833

Answers (2)

marqueed
marqueed

Reputation: 1123

Granted that is PyQt and not PySide, but:

  • Don't subclass QThread, subclass QObject (see http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/).
  • Then the basic workflow is to create a new thread, move your worker into the thread, start the thread and your worker. Your problem may be that you never actually start your new thread, initialization won't do that - then both your GUI and your worker are running the same thread, as others have commented. The GIL doesn't really enter into the picture. Check out the QThread docs: http://doc.qt.io/qt-4.8/qthread.html.

Upvotes: 0

Kaleb Pederson
Kaleb Pederson

Reputation: 46479

After looking more closely at your code, you have MAIN_WORLD started before QApplication, which isn't what you want.

You want to do something like this:

if __name__ == '__main__':
    app = QApplication(sys.argv)
    sys.exit(app.exec_())

And, in your Window class:

class Window(QWidget):
    def __init__(self, *args):
        self.world_thread = World();
        # ...

The above will allow the main thread to control the gui and allow the worker threads to work in the background.

Upvotes: 1

Related Questions