Pyqt QThread blocking the main thread

I am trying to create a simple multi-threaded program in which I have a method that does some long processing and a widget that displays a loading bar and a cancel button.

My problem is that no matter how I implement the threads, they are not really threads - the user interface is blocked after the thread starts working. I read every tutorial and posted about it, and now I resort to asking the community to try to solve my problem, because I'm at a loss!

I initially tried to subclass QThread until the internet said it was wrong. Then I tried to use the moveToThread method, but it made a null difference.

Initialization Code:

loadingThreadObject = LoadThread(arg1)
loadingThread = PythonThread()
loadingThreadObject.moveToThread(loadingThread)
loadingThread.started.connect(loadingThreadObject.load)
loadingThread.start()

PythonThread class (obviously, QThreads are listened to in pyQt and will not start if you do not):

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

    def start(self):
        QtCore.QThread.start(self)

    def run(self):
        QtCore.QThread.run(self)

LoadThread Class:

class LoadThread (QtCore.QObject):
    results = QtCore.Signal(tuple)

    def __init__ (self, arg):
         # Init QObject
         super(QtCore.QObject, self).__init__()

         # Store the argument
         self.arg = arg

    def load (self):
         #
         # Some heavy lifting is done
         #

         loaded = True
         errors = []

         # Emits the results
         self.results.emit((loaded, errors))

Any help is much appreciated!

Thanks. Ben.

+4
source share
2 answers

The problem was using the SQL library that I was using (a custom internal solution), which turned out to be an unsafe thread and, thus, executed blocking queries.

, SQL , . , SQL MySQLdb ( ). , SQL.

+1

, started, , , . QThread start() run() , QThread LoadThread.load, . PythonThread, . QThread start().

PS: QThread run() LoadThread.load(), run() LoadThread.load:

class MyThread(QtCore.QThread):
    run = LoadThread.load # x = y in the class block sets the class x variable to y

:

import time
from PyQt4 import QtCore, QtGui
import sys
application = QtGui.QApplication(sys.argv)

class LoadThread (QtCore.QObject):
    results = QtCore.pyqtSignal(tuple)

    def __init__ (self, arg):
         # Init QObject
         super(QtCore.QObject, self).__init__()

         # Store the argument
         self.arg = arg

    def load(self):
         #
         # Some heavy lifting is done
         #
         time.sleep(5)
         loaded = True
         errors = []

         # Emits the results
         self.results.emit((loaded, errors))

l = LoadThread("test")

class MyThread(QtCore.QThread):
    run = l.load

thread = MyThread()

button = QtGui.QPushButton("Do 5 virtual push-ups")
button.clicked.connect(thread.start)
button.show()
l.results.connect(lambda:button.setText("Phew! Push ups done"))
application.exec_()
0

All Articles