python - pyqt5 QTimer.singleShot 根本不运行
问题描述
(Python 3.7.3,PyQt5m MacOS Mojave)
在下面的代码中,我希望看到
start_batch
item
item
item
item
returned from start_batch
但我实际上得到的是
start_batch
returned from start_batch
也就是说,simulated_item 永远不会运行,甚至一次也不会。
我需要做什么来纠正这个问题?
from PyQt5.QtCore import QTimer, QCoreApplication, QThread
import time, sys
class Scanner(object):
def __init__(self):
self.num = -1
def start_batch(self, operator_id, update_callback):
print('start_batch')
self.update_callback = update_callback
QTimer.singleShot(1, self.simulated_item)
def simulated_item(self):
print('item')
self.update_callback()
self.num += 1
if self.num > 4:
self.normal_stop_callback()
return
QTimer.singleShot(100, self.simulated_item)
class dummy(QThread):
def update(self):
print('update')
def run(self):
scnr = Scanner()
scnr.start_batch('opid', self.update)
print('returned from start_batch')
for i in range(10):
time.sleep((0.2))
app = QCoreApplication([])
thread = dummy()
thread.run()
解决方案
In your code you have the error that you are calling the run method directly but that is not appropriate but you have to use the start()
method:
app = QCoreApplication([])
thread = dummy()
thread.start()
app.exec_()
But you still won't get what you want.
Many elements such as the case of QTimer (also the signals) need an event loop to be able to work but when you override the run method that has it by default you have eliminated it so it fails.
So an approximation of what you want may be the following code where the QTimer uses the QCoreApplication event loop:
from PyQt5.QtCore import QTimer, QCoreApplication, QThread
import time, sys
class Scanner(object):
def __init__(self):
self.num = -1
def start_batch(self, operator_id, update_callback):
print("start_batch")
self.update_callback = update_callback
QTimer.singleShot(1, self.simulated_item)
def simulated_item(self):
print("item")
# QTimer.singleShot() is used so that the update_callback function
# is executed in the thread where the QObject to which it belongs lives,
# if it is not a QObject it will be executed in the thread
# where it is invoked
QTimer.singleShot(0, self.update_callback)
# self.update_callback()
self.num += 1
if self.num > 4:
# self.normal_stop_callback()
return
QTimer.singleShot(100, self.simulated_item)
class dummy(QThread):
def update(self):
print("update")
def run(self):
for i in range(10):
time.sleep(0.2)
print("returned from start_batch")
if __name__ == "__main__":
app = QCoreApplication(sys.argv)
thread = dummy()
thread.start()
scnr = Scanner()
thread.started.connect(lambda: scnr.start_batch("opid", thread.update))
sys.exit(app.exec_())
推荐阅读
- python - 如何在列表理解中将变量添加到 for 循环
- laravel - Laravel Fortify + Inertia + vue 如何添加角色和权限?
- java - 使用哪种设计模式来避免验证类中的 if/else?
- r - 如何在 R 中修复具有两个条件的 if 语句(它在长度 8 后停止)
- facebook-graph-api - Facebook Graph API - 无法从名称中获取帖子上的所有评论
- android - 错误:将字节码转换为dex时出错:原因:com.android.dex.DexException:多个dex文件定义Lokhttp3/internal/http/RealResponseBody;
- excel - Excel:使用 countif 和 & 的变量频率
- .net - 在公共交通中,如何将当前文化设置为正在执行的消息?
- sql - 如何根据 SQL 中的日期条件求和?
- php - 从 foreach 循环加入数组并制作多个数组,其中数组键为空