程序需要每个半小时就运行,需要一个while True的循环,所以就想到了使用线程。不用行不行?我试过将while True写到主界面的类里面,这时候运行程序就会发现窗口无法点动了,因为进程陷入那个while True的循环里。所以很自然的就需要用到线程了。
QThread是pyqt5中带的, 而Threading是python自带的,两者也都是,自己需要写自己的线程类,继承它们,然后重写run方法,再通过start启动。所以是用QThread 还是 Threading呢?
首先QThread依旧还是受GIL的影响,与真正的多线程依旧还是有区别,但我但理解是在pyqt中,还是最好使用,QThread。QThread可以发送信号, 利用信号-槽机制可以方便的与 GUI 跨线程交互。
stackoverflow上有对QThread 与 Threading对区别的一个讨论,基本也是说两者的区别不大,但在pyqt中更鼓励使用QThread
Threading in a PyQt application: Use Qt threads or Python threads?
这边帖子也对两者的区别展开了讨论,但可以肯定的是QThread依旧没有避开GIL。
PyQt 编程中多线程应该用 QThread、QTimer 还是 threading??
这里我主要想通过主进程这边发送一个信号,可以让线程结束。
我想的是将while True改为 while flag
然后看了百度的这个回答,也没深纠,就直接依葫芦画瓢的用了信号量(信号量这种方式肯定是没有问题的)
Pyqt5如何停止多线程
但直接调用stop函数上面链接说的是不能停止循环,后面我自己试了下,应该是能够停止循环,并没有什么问题。。。
然后我通过设置全局变量,发现也是可以的
最后我又转念一想,既然能通过调用线程中的函数来修改变量,那能不能直接修改线程中的变量呢?
结果还是可以的。。。
如果我的操作没有什么问题的话,其实就可以有3种方式来结束线程循环
-
通过信号量来与线程通信
-
直接修改线程中的变量值或直接调用线程中的方法去修改变量值
-
设置全局变量
本来写这篇博客是想告诉大家要用信号量来调用线程中的方法,来结束while循环。结果写的时候为了有图有真相写了下小例子。。。结果是出乎了我的意料。。。
如果有什么不对的地方还请各位大佬不吝赐教,以免我误人子弟
最后就是如果是while循环里的sleep的时间特别长的话,是没有办法立即结束掉线程的,如果有大佬知道的话,还请多多指教。
前言程序需要每个半小时就运行,需要一个while True的循环,所以就想到了使用线程。不用行不行?我试过将while True写到主界面的类里面,这时候运行程序就会发现窗口无法点动了,因为进程陷入那个while True的循环里。所以很自然的就需要用到线程了。QThread 与 ThreadingQThread是pyqt5中带的, 而Threading是python自带的,两者也都是,自己...
文章目录Qt 线程中
QThread
的使用1. 线程类
QThread
1.1 常用共用成员函数1.2
信号
槽1.3 静态函数1.4 任务处理函数2. 使用方式 12.2 示例代码3. 使用方式 23.1 操作步骤3.2 示例代码
Qt 线程中
QThread
的使用
在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个线程处理窗口事件,其他线程进行逻辑运算,多个线程各司其职,不仅可以
一、应用场景
在编写GUI界面中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件或者做一些操作,这些操作会耗时,如果不能及时结束,主线程将会阻塞,这样界面就会出现未响应的状态,因此必须使用多线程来解决这个问题。
二、使用多线程
解决卡顿和假死
1.两个按钮,分别在控制台打印不同的内容,分别点击两个按钮后,控制台会依次打印内容,多次点击按钮,程序会先循环完上
尊重原创,请读原文
class startThread(
QThread
): #继承
QThread
trigger =
pyqt
Signal() #创建
信号
def __init__(self):
super(startThread, self).__init__()
self.flag = 1 #自定义变量 ...
我相信很多人在学习
PyQt5
的时候都遇到过多线程
QThread
怎么接收
信号
,在百度或者视频以及书籍里都只教了怎么用多线程
QThread
来发射
信号
。
多线程接收
信号
有多种方法,1、__init__()函数传参;2、使用队列Queue();3、使用
pyqt
Signal
新手的我之前琢磨了很久研究
QThread
多线程怎么接收
pyqt
Signal的
信号
,我们知道多线程
QThread
的start()和run()函数不能接收
信号
,无奈翻遍了全网都没有找到,基本都讲的是怎么发出
信号
。昨晚的时候突然想通了,实现了接收信
产生这个疑问是因为,使用
QThread
创建的线程在
Python
的主线程里看不到子线程调用堆栈,而且用viztracer也看不到。
1.
QThread
的viztracer图表
2. 使用threading.Thread的viztracer图表
import threading
import time
from
PyQt5
import QtCore
class Task(QtCore.
QThread
):
def __init__(self, idx):
QThread
使用
PyQt5
开发应用程序时,处理耗时较长的任务时为避免主程序卡死就要用到
QThread
开子线程,有时子线程是去执行For/While 循环任务,我们如果想临时终止线程,就可以增加一个属性用作判定是否要临时终止的标志位,每轮循环开始前做一次校验判定是否要退出。
以下示例是做LED循环开关及调光测试的小程序,循环次数通常都设置在数万次,运行后如发现DUT表现异常操作员就要终止测试。
主程序代码(片段)
self.ui.dimmer_cycle_exec.clicked.conn
今天想要实现子线程与子线程之间参数的传送,而且是要实现动态传参,上网搜了好久,然后又自己尝试,结果发现实在不知道如何直接实现两个子线程之间参数的传递(利用实例化时参数无法实现动态传参),使用
信号
与槽机制结果传到另一个线程里的不知道是啥。最后采用了子线程->主线程->子线程的思路。
这里需要搞明白
信号
发送与接受,还有主线程动态传参到子线程。首先看一下界面:
我想要实现label标签内的数字随着进度的变化而变化,利用线程实现(当然有更简单的方法,这里仅是为了了解线程)。
建立两个线程类:.
在
PyQt
中常用的图像类有4个,即QPixmap、QImage、QPicture和QBitmap。
QPixmap是专门为绘图而设计的,在绘制图片时需要使用QPixmap;
QImage提供了一个与硬件无关的图像表示函数,可以用于图片的像素级访问;
QPicture是一个绘图设备类,它继承自QPainter类,可以使用QPainter的begin()函数在QPicture上绘图,使用end()函数结束绘图,使用QPicture的save()函数将QPainter所使用过的绘图指令保存到文件中;
QBit..
虚拟机线程:这种线程的操作时需要JVM达到安全点才会出现。这些操作必须在不同的线程中发生的原因是他们都需要JVM达到安全点,这样堆才不会变化。这种线程的执行类型包括“stop-the-world”的垃圾收集,线程栈收集,线程挂起以及偏向撤销。
周期任务线程:这种线程是时间周期性事件的体现(比如中断),他们一般用于周期性操作的调度执行。
GC线程:这种线程对
在
PyQt5
中使用
QThread
创建线程时,确保线程安全性非常重要。如果线程不安全,可能会导致资源争用、竞争条件和死锁。
要实现线程安全退出,需要在代码中实现以下几个步骤:
1. 创建一个类,该类继承自QObject和
QThread
,并重写run()方法。
2. 添加一个
信号
,当线程退出时发出,该
信号
作为通知主线程的指示器。
3. 在run()方法中,添加一个while循环,检查一个布尔值,该值表示程序是否应该继续运行。如果此布尔值为False,则跳出循环,结束线程。
4. 在mainwindow的析构函数中,将该布尔值设置为False,并通过emitsignal()方法发送
信号
,通知线程停止。
例如,以下是一个简单的例子,可以在主线程和
PyQt5
QThread
线程之间创建一种安全退出:
from
PyQt5
.QtCore import Qt,
QThread
,
pyqt
Signal, QObject
class Worker(
QThread
):
exitThread =
pyqt
Signal()
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
def run(self):
while True:
if not self.isRunning():
return
#线程执行代码
def stop(self):
self.exitThread.emit()
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.workerThread = Worker()
self.workerThread.exitThread.connect(self.stopThread)
self.workerThread.start()
def stopThread(self):
self.workerThread.terminate()
在上面的代码中,如果从mainwindow发送emit
信号
,emit将调用worker stop,从而启动
信号
退出方法exitThread,从而终止
QThread
中的运行。这将确保一个线程安全退出的模式,防止资源泄漏或竞争条件。