繁体   English   中英

pyqt QThread阻塞主线程

[英]pyqt QThread blocking main thread

我正在尝试创建一个简单的线程应用程序,我有一个方法,它做了一些长处理和一个显示加载栏和取消按钮的小部件。

我的问题是,无论我如何实现线程,它实际上都没有线程 - 一旦线程启动,UI就会被锁定。我已阅读每个教程并发布有关此内容的信息,我现在正在求助社区我试着解决我的问题,因为我不知所措!

最初我尝试了继承QThread,直到互联网说这是错误的。 然后我尝试了moveToThread方法,但它没有区别。

初始化代码:

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

PythonThread类(显然QThreads在pyQt中被窃听并且除非你这样做否则不启动):

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

任何帮助是极大的赞赏!

谢谢。 本。

问题在于我使用的SQL库(一个自定义的内部解决方案),结果证明它不是线程安全的,因此执行了阻塞查询。

如果您遇到类似问题,请首先尝试删除SQL调用并查看它是否仍然阻塞。 如果这解决了阻塞问题,请尝试通过MySQLdb使用原始SQL重新引入查询(或者使用您正在使用的DB类型的等效项)。 这将诊断问题是否与您选择的SQL库有关。

连接到started信号的功能将运行它所连接的线程,即主GUI线程。 但是,在初始化线程后,QThread的start()函数在线程中执行其run()方法,因此应创建QThread的子类,并且其run方法应运行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's 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_()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM