为什么我的Qt应用程序在线程不是主线程的子对象时会冻结?

2024-09-29 05:21:59 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的“minimal”示例中,当我将启动QThread的函数更改为“\u do\u print2”时,我的主窗口冻结。为了比较,上面的按钮将启动QThread而没有任何问题。为什么线程必须是MainWindow类的子对象?你知道吗

我使用python2.7.6和qt4.8.6。你知道吗

from PyQt4 import QtCore, QtGui
import sys, time

class MainWindow(QtGui.QDialog):
    def __init__(self):
        super(self.__class__, self).__init__()
        self.verticalLayout = QtGui.QVBoxLayout(self)
        self.pushButton = QtGui.QPushButton()
        self.pushButton2 = QtGui.QPushButton()
        self.verticalLayout.addWidget(self.pushButton)
        self.verticalLayout.addWidget(self.pushButton2)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL('clicked()'), self._do_print)
        QtCore.QObject.connect(self.pushButton2, QtCore.SIGNAL('clicked()'), self._do_print2)
    ## Working function
    def _do_print(self):
        self.thread = Worker(printer)
        self.thread.start() 
    ## Function freezes the MainWindow
    def _do_print2(self):
        thread = Worker(printer)
        thread.start()


def printer():
    while True:
        print "alive"
        time.sleep(1)

class Worker(QtCore.QThread):
    def __init__(self, function, *args, **kwargs):
        super(self.__class__, self).__init__()
        self.args = args
        self.kwargs = kwargs
        self.function = function

    def run(self):
        self.function(*self.args, **self.kwargs)
        return

    def __del__(self):
        self.wait()

app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

Tags: selfinitdefsysargsfunctiondothread
1条回答
网友
1楼 · 发布于 2024-09-29 05:21:59

剧本“冻结”是因为你让它这么做。你知道吗

Worker类定义了一个__del__方法,该方法使线程等待(或者说“冻结”)直到run方法返回。但它当然永远不会返回,因为它调用的函数会启动一个永远不会终止的阻塞循环。调用__del__方法是因为您没有保留对线程的引用,因此只要_do_print2()方法返回(即线程启动后立即),它就会被垃圾回收。你知道吗

请注意,第一个线程不是主窗口的,它只是一个实例属性(使其保持活动状态)。如果删除^ {< CD2> }方法,启动第二个线程可能会崩溃程序,因为没有任何东西可以阻止基础C++线程过早地被删除。你知道吗

相关问题 更多 >