QThread 使用技巧 常见问题 注意事项


QThread 在 PySide2 PyQt5 用户界面编程中,会经常用到。

注意: 采用 QThread (或类型功能) 异步处理任务,很容易出现 RuntimeError TypeError 等异常。

print 输出


在重实现的 QThread.run() 函数内调用 print() 内置函数,每次不一定输出提示信息。

注意:当调试源代码时,没有输出让人很困惑。

多线程 vs 多进程


由于 PIL 解释器 原因,PySide2 PyQt5 的 QThread 只能使用一物理线程,即使能够采用 QThreadPool 多线程编程技术。

解决办法: 使用并行多进程代替多线程,虽然编程架构要复杂不少。

注意:PySide2 QThread 的 wait() 函数有时可能阻塞其后的所有操作。

对于应用程序局部异步多线程 (类似协程),Python 是支持的,只是不能超出一物理线程。

QtGui QtWidgets


在 QThread 实例中可以调用 QtGui QtWidgets 实例,但在其中可能不能对其进行修改。

否则,会出现错误提示、异常中断、应用程序变得不稳定、描绘更新异常、自动崩溃、等现象。

解决办法: 在 QThread 实例 run() 函数中修改 QtGui QtWidgets 实例参数,再用信号把计算所得参数连接到 QThread 外 QtGui QtWidgets 实例槽进行更新。

如下所示:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QListView(0x8307d10), parent's thread is QThread(0x280b7c0), current thread is threadTest(0x8739a10)
QBasicTimer::start: Timers cannot be started from another thread
					

界面相关


界面消息提示、界面刷新不要放到 QThread 内,否则无法正常使用,且还可能导致崩溃。

当然,更不可能进行交互操作。

计时器


QThread 实例自带一计时器,其它自定义计时器不能跨线程。

关闭计时器要注意对应线程关系,否则操作无效且会提示出错 (或导致崩溃)。

自定义计时器跨线程运行,计时有时会被线程打乱 (可将计时器重新移回原线程以解决此问题)。

PyQt5 对 QThread 内计时器要求不严格,譬如在 run() 函数可以杀除其它对象的计时器,而 PySide2 绝对不可以。

另请参阅:

QtCore::QTimer 计时器类

版权声明: 本文为独家原创稿件,版权归 乐数软件 ,未经许可不得转载。