Skip to content Skip to sidebar Skip to footer

How To Stop Qt App From Freezing The Main Program?

For example: #!/usr/bin/env python3 import sys from PySide import QtCore, QtGui class Dialog(QtGui.QDialog): def __init__(self): QtGui.QDialog.__init__(self)

Solution 1:

This is not possible. Qt documentation states:

Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread. As noted earlier, QCoreApplication::exec() must also be called from that thread.

This answer suggests on the other hand that in reality this is not true :) However it seems that PySide sticks to the official version:

This can be verified by the following code sample:

import sys
import threading
from PySide import QtCore, QtGui

class Dialog(QtGui.QDialog):
    def __init__(self):
        QtGui.QDialog.__init__(self)
        button = QtGui.QPushButton("test")
        layout = QtGui.QVBoxLayout()
        layout.addWidget(button)
        self.setLayout(layout)

app = QtGui.QApplication(sys.argv)
toast = Dialog()
toast.show()

t = threading.Thread(target = lambda: app.exec_())
t.daemon = True
t.start()
print("App freezes the main process!")
input()

which produces the following output:

App freezes the main process!
QApplication::exec: Must be calledfrom the main thread

(and a crash, on my machine). I have also verified the option with creating the app within the other thread - it works, but crashes on exit.


So the solution seems to let Qt have the main thread, and organize your processing in a separate thread. This shouldn't really be a problem: if you'll separate your concerns well it won't make a difference for your console-app part on which thread it's running.

Solution 2:

I'm not sure if the PySide imposes any restrictions, but here's how it's done in C++:

  1. Instantiate QApplication in a secondary thread.
  2. Create your dialog in that same thread.
  3. Call either QDialog::exec() OR {QApplication::exec() plus QDialog::show()} in that same thread.
  4. Make sure that your secondary thread has fully shut down before you quit your app.

Yes, the Qt documentation currently says that only the main thread is allowed. However, there is nothing in the Qt source code that forbids creating QApplication in a secondary thread and then using GUI classes in that thread (for Windows and Linux). The documentation should be changed.

Mac OS X is different though -- the Cocoa framework only allows GUI operations in the main thread.

Post a Comment for "How To Stop Qt App From Freezing The Main Program?"