如何使 PySide.QtCore.QTimer.singleShot 调用其超时方法
How to make a PySide.QtCore.QTimer.singleShot call its timeout method
I am working on a complex and poorly commented Qt-based Python application. It employs a PySide.QtCore.QTimer.singleShot(int,slot) timer to delay the execution of a slot within a thread, and I am confused about how this timer works.
Here is a MWE. This example uses the approach of subclassing QThread and reimplementing 运行(). I put the following in a file called 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')
The code I am using to test this (call it 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_())
The output of python test.py
:
Test: QThread subclassing
called SubClassThread.run()
called SubClassThread.delayed_print()
end of delayed_print()
The curious part is that the callable passed to QTimer.singleShot never seems to get called (there is no called print_things()
in the output!) I would greatly appreciate any clarity that you can shed on this. I feel that I am missing some simple ingredient of the Qt framework. Please bear with me- I did spend some hours searching for answers to this.
QThread.run()
的默认实现调用 QThread.exec()
,它启动线程自己的事件循环。 QTimer
需要一个 运行 事件循环,它的 timeout()
信号将在它启动的线程中发出。您的 run()
实现不会启动事件-循环,所以定时器什么都不做。
正如@ekhumoro 所指出的,我对 运行() 的重新实现未能调用 exec_()。这是主要问题。我花了一分钟才弄清楚将 exec_() 调用放在哪里,以及如何在线程工作完成后正确地 quit() 线程。这是有效的代码。
Class 定义,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 的了解:对 delayed_print() 的调用在计时器仍在 运行ning 时完成,并且通过将 quit() 放入计时器调用的方法中,应用程序在调用该方法之前不会退出。
如果对此代码或与此简单应用程序相关的 Qt 方面有任何进一步的评论,请post!我在为初学者寻找可访问的 PyQt/PySide 信息时遇到了一些麻烦。
I am working on a complex and poorly commented Qt-based Python application. It employs a PySide.QtCore.QTimer.singleShot(int,slot) timer to delay the execution of a slot within a thread, and I am confused about how this timer works.
Here is a MWE. This example uses the approach of subclassing QThread and reimplementing 运行(). I put the following in a file called 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')
The code I am using to test this (call it 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_())
The output of python test.py
:
Test: QThread subclassing
called SubClassThread.run()
called SubClassThread.delayed_print()
end of delayed_print()
The curious part is that the callable passed to QTimer.singleShot never seems to get called (there is no called print_things()
in the output!) I would greatly appreciate any clarity that you can shed on this. I feel that I am missing some simple ingredient of the Qt framework. Please bear with me- I did spend some hours searching for answers to this.
QThread.run()
的默认实现调用 QThread.exec()
,它启动线程自己的事件循环。 QTimer
需要一个 运行 事件循环,它的 timeout()
信号将在它启动的线程中发出。您的 run()
实现不会启动事件-循环,所以定时器什么都不做。
正如@ekhumoro 所指出的,我对 运行() 的重新实现未能调用 exec_()。这是主要问题。我花了一分钟才弄清楚将 exec_() 调用放在哪里,以及如何在线程工作完成后正确地 quit() 线程。这是有效的代码。
Class 定义,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 的了解:对 delayed_print() 的调用在计时器仍在 运行ning 时完成,并且通过将 quit() 放入计时器调用的方法中,应用程序在调用该方法之前不会退出。
如果对此代码或与此简单应用程序相关的 Qt 方面有任何进一步的评论,请post!我在为初学者寻找可访问的 PyQt/PySide 信息时遇到了一些麻烦。