我正在开发一个复杂且评论不佳的基于Qt的Python应用程序。它使用PySide.QtCore.QTimer.singleShot(int,slot)计时器来延迟线程中插槽的执行,我对此计时器的工作原理感到困惑。
这是一个MWE。此示例使用子类化QThread和重新实现run()的方法。我将以下内容放在名为timertester.py的文件中:
import PySide
import time
class SubClassThread(PySide.QtCore.QThread):
def run(self):
print('called SubClassThread.run()')
self.delayed_print()
def delayed_print(self):
print('called SubClassThread.delayed_print()')
PySide.QtCore.QTimer.singleShot(1000, self.print_things)
time.sleep(2)
print('end of delayed_print()')
def print_things(self):
print('called print_things')
我用来测试它的代码(称之为test.py
):
import sys
import time
import PySide
from timertester import SubClassThread
print('Test: QThread subclassing')
app = PySide.QtCore.QCoreApplication([])
sct = SubClassThread()
sct.finished.connect(app.exit)
sct.start()
sys.exit(app.exec_())
python test.py
的输出:
Test: QThread subclassing
called SubClassThread.run()
called SubClassThread.delayed_print()
end of delayed_print()
奇怪的是,传递给QTimer.singleShot的callable似乎永远不会被调用(输出中没有called print_things()
!)我将非常感谢您可以清楚地了解这一点。我觉得我错过了Qt框架的一些简单要素。请耐心等待 - 我花了几个小时寻找答案。
答案 0 :(得分:1)
QThread.run()
调用QThread.exec()
的默认实现,它启动线程自己的事件循环。 QTimer
需要一个正在运行的事件循环,并且它的timeout()
信号将在它启动的线程中发出。run()
的实现不会启动事件循环,所以计时器什么都不做。
答案 1 :(得分:1)
正如@ekhumoro指出的那样,我重新实现run()无法调用exec_()。这是主要问题。我花了一分钟时间找出exec_()调用的位置以及如何在完成工作时正确退出()线程。这是有效的代码。
班级定义,timertester.py
:
import PySide
class SubClassThread(PySide.QtCore.QThread):
def __init__(self,parent=None):
print('called SubClassThread.__init__()')
super(SubClassThread,self).__init__(parent)
def run(self):
print('called SubClassThread.run()')
self.delayed_print()
self.exec_()
def delayed_print(self):
print('called SubClassThread.delayed_print()')
PySide.QtCore.QTimer.singleShot(1000, self.print_things)
print('end of delayed_print()')
def print_things(self):
print('called print_things')
self.quit()
申请,test.py
:
import sys
import PySide
from timertester import SubClassThread
print('Test: QThread subclassing')
# instantiate a QApplication
app = PySide.QtCore.QCoreApplication([])
# instantiate a thread
sct = SubClassThread()
# when the thread finishes, make sure the app quits too
sct.finished.connect(app.quit)
# start the thread
# it will do nothing until the app's event loop starts
sct.start()
# app.exec_() starts the app's event loop.
# app will then wait for signals from QObjects.
status=app.exec_()
# print status code and exit gracefully
print('app finished with exit code {}'.format(status))
sys.exit(status)
最后,python test.py
的输出:
Test: QThread subclassing
called SubClassThread.__init__()
called SubClassThread.run()
called SubClassThread.delayed_print()
end of delayed_print()
called print_things
app finished with exit code 0
我学到了关于QTimers的知识:在timer定时器仍在运行时对delayed_print()的调用结束,并且通过在计时器调用的方法中放置quit(),应用程序在调用该方法之后才会退出。
如果对此代码有任何进一步的评论,或者有关此简单应用的Qt方面,请发帖!我在为初学者找到可访问的PyQt / PySide信息时遇到了一些麻烦。