在下面的“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_())
剧本“冻结”是因为你让它这么做。你知道吗
Worker
类定义了一个__del__
方法,该方法使线程等待(或者说“冻结”)直到run方法返回。但它当然永远不会返回,因为它调用的函数会启动一个永远不会终止的阻塞循环。调用__del__
方法是因为您没有保留对线程的引用,因此只要_do_print2()
方法返回(即线程启动后立即),它就会被垃圾回收。你知道吗请注意,第一个线程不是主窗口的子,它只是一个实例属性(使其保持活动状态)。如果删除^ {< CD2> }方法,启动第二个线程可能会崩溃程序,因为没有任何东西可以阻止基础C++线程过早地被删除。你知道吗
相关问题 更多 >
编程相关推荐