参考网址1:
https://blog.csdn.net/xyisv/article/details/88292870
参考网址2:
https://ask.csdn.net/questions/811874
1.问题及原因描述:
在使用pyqt5编写UI的时候,正如参考网址1所述,我们一般会将后台任务与界面区分,但我自己在实现的时候发现即使使用后台线程,但仍然会阻塞界面的操作,类似问题在参考网址2中也有提到。通过对比我自己的代码和参考网址1的代码,发现原因在于这个后台线程变量是否为该类的成员变量。
2.演示代码及描述:
以下是的在网址1的代码基础上进行修改后的示例演示。
from PyQt5 import QtWidgets, QtCore
import sys
from PyQt5.QtCore import *
import time
from PublicFunc import *
# 继承QThread
class Runthread(QtCore.QThread):
# 通过类成员对象定义信号对象
_signal = pyqtSignal(str)
def __init__(self):
super(Runthread, self).__init__()
def __del__(self):
self.wait()
def JudeIP(self, ipStr):
if ipStr == "0.0.0.0":
reIndex = 4
else:
ipTypeRe = isIpStr(ipStr)
if not ipTypeRe:
reIndex = 3
else:
# 检测IP能否ping通
pingIpRe = pingIp(ipStr)
if pingIpRe:
reIndex = 1
else:
reIndex = 2
return reIndex
def run(self):
for i in range(10):
reIndex = self.JudeIP("192.168.3.111")
print(str(i) + "--ping IP re:" + str(reIndex))
self._signal.emit(str((i+1)*10)) # 注意这里与_signal = pyqtSignal(str)中的类型相同
class Example(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.lineEid = QLineEdit()
# 进度条设置
self.pbar = QtWidgets.QProgressBar()
self.pbar.setGeometry(50, 50, 210, 25)
self.pbar.setValue(0)
# 按钮初始化
self.button1 = QtWidgets.QPushButton('开始(多线程为成员变量)')
self.button1.clicked.connect(self.start_login_m) # 绑定多线程(线程为成员变量)触发事件
self.button2 = QtWidgets.QPushButton('开始(多线程为局部变量)')
self.button2.clicked.connect(self.start_login) # 绑定多线程(线程为局部变量)触发事件
btnHBlayout = QHBoxLayout()
btnHBlayout.addWidget(self.button1)
btnHBlayout.addWidget(self.button2)
winVBlayout = QVBoxLayout()
winVBlayout.addWidget(self.lineEid)
winVBlayout.addWidget(self.pbar)
winVBlayout.addLayout(btnHBlayout)
self.setLayout(winVBlayout)
# 窗口初始化
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('耗时线程阻塞界面演示')
self.show()
self.thread = None # 初始化线程
def start_login(self):
self.pbar.setValue(0)
# 创建线程
thread = Runthread()
# 连接信号
thread._signal.connect(self.call_backlog) # 进程连接回传到GUI的事件
# 开始线程
thread.start()
def start_login_m(self):
self.pbar.setValue(0)
# 创建线程
self.thread = Runthread()
# 连接信号
self.thread._signal.connect(self.call_backlog) # 进程连接回传到GUI的事件
# 开始线程
self.thread.start()
def call_backlog(self, msg):
self.pbar.setValue(int(msg)) # 将线程的参数传入进度条
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myshow = Example()
myshow.show()
sys.exit(app.exec_())
以下是该测试程序运行时的界面,当点击button1,即“开始(多线程为成员变量)”时,上方的lineEdit可以随意输入信息,同时进度条在以10%的速度刷新。但当点击button2,即“开始(多线程为局部变量)”时,点击lineEdit时界面阻塞,无法对界面进行操作,同时进度条也没有刷新,直到后台线程全部执行完毕,界面才能进行操作,lineEdit可以输入信息,进度条直接从0%变到100%。
3.原因分析:
以上两个按钮执行的函数,唯一的区别是阻塞按钮为局部变量,有可能是作用域不同造成的,这仅仅是我的猜测,若是有其他小伙伴知道原因,希望可以不吝赐教。
参考网址1:https://blog.csdn.net/xyisv/article/details/88292870参考网址2:https://ask.csdn.net/questions/8118741.问题及原因描述:在使用pyqt5编写UI的时候,正如参考网址1所述,我们一般会将后台任务与界面区分,但我自己在实现的时候发现即使使用后台线程,但仍然会阻塞界面的操作,类似问题在参考网址2中也有提到。通过对比我自己的代码和参考网址1的代码,发现原因在于这个后台线程是否为该类的成员函数。.
1.资源简介:
PyQt5
中使用
多线程
模块
QT
hread解决了
PyQt5
界面
程序执行比较
耗时
操作时,程序卡顿出现的无响应以及
界面
输出无法实时显示的问题,采用线程池ThreadPoolExecutor解决了ping多个IP多任务
耗时
问题。
2.适用人群:想学习
PyQt5
中
多线程
模块
QT
hread和线程池ThreadPoolExecutor知识的人。
在做GUI
界面
时我们希望后台任务能够与UI分开,在
PyQt
中,主线程用来重绘
界面
。而子线程里边的实时处理结果需要反馈到
界面
,子线程里边不能执行
界面
更新操作。
wx
python
多线程
刷新
界面
转到
https://www.jb51.net/article/176308.htm
下面给出类
Python
3+
PyQt5
多线程
防假死动态刷新
界面
的模板
from
PyQt5
import
Qt
Widgets,
Qt
Core
import sys
from
PyQt5
.
Qt
Core import *
import time
# 继承
QT
hread
class Runthread(
Qt
Core.
QT
hread
前面已经有Scala实现
多线程
了,那么用
Python
实现
多线程
又有什么区别和好处?
Scala里实现
多线程
,启的是同一个Application,计算
多线程
任务的task都是同时返回到driver中进行管理。而这些task的完成情况和状态管理会一直保存在driver中,直到Application结束。如果模型迭代次数很多,或者需要写循环来做多次计算时,这很容易导致driver的内存溢出。
所以,为了同时实现
多线程
,而又不至于让Application任务太大、task太多、driver内存溢出
有一个应用场景,
pyqt5
执行过程中,启动一个
QT
hread执行
耗时
操作,
QT
hread执行过程中,会生成数据,生成的数据需要实时展示,这时候主程序在收到数据后,会调用QDialog实时展示,需要将数据由
QT
hread传递到QDialog中,QDialog是一个单独的模块供主程序调用,在调用时,需要先启动QDialog,然后再调用
QT
hread,下面是一个示例:
1.
QT
hread中定义一个信号,
QT
hread调用逻辑函数时,将自己定义的信号传递进去,由逻辑函数使用该信号发送产生的数据;
当你想在主线程创建类似 while(1)的这种死循环时,你可能会写下这样的代码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
今天用子线程处理数据,但只创建了子线程,还没有来得及让子线程处理大量的数据。在子线程只作了简单处理,发现主线程
界面
一直不能响应,在主线程让子线程参数isStop= true,也跳不出循环。
while(!isStop)
emit mySignal();
if(isStop)
break;
后来在子线程加入
QT
hread::sleep(1);主线程就...
PyQt
Echarts
对着书<
Pyqt5
快速开发与实战> 实战Js在QWebEngineView 中的运用
主要还是
Qt
Chart用着比较麻烦… 需求者不喜欢
pyqt
graph并且对速度不在意,就改为Echarts
1.创建Widget
在
Qt
Designer中创建一个Widget(chartWidget),使用栅格布局,放入一个布局Layout 我这里是水平布局,
2.使用PyUic将Ui文件转为py文件,也可用uic直读UI文件
我这边转为了chartWidget_rc,下图是文件
心得:写着写着找到了自己的感觉,还是需要大量的代码和项目来加深对代码的理解
一、
PyQt5
多线程
防卡死
在
界面
中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件或者做一些操作,这些操作会
耗时
,如果不能及时结束,主线程将会阻塞,这样
界面
就会出现未响应的状态,因此必须使用
多线程
来解决这个问题。
# -*- coding: UTF-8 -*-
""""======================...
在
PyQt5
中,子线程不能直接访问UI控件,因为
PyQt5
只能在主线程中更新UI。但您可以通过信号和槽机制在主线程和子线程之间进行通信。
以下是一个例子,演示了如何在子线程中获取窗口控件的内容并将其发送到主线程:
```
python
from
PyQt5
.
Qt
Core import
QT
hread,
pyqt
Signal
from
PyQt5
.
Qt
Widgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QPushButton, QLabel
import sys
class Worker(
QT
hread):
finished =
pyqt
Signal(str)
def __init__(self, parent=None):
super().__init__(parent)
def run(self):
# 在这里调用子线程需要执行的任务,例如获取窗口控件内容
content = "子线程获取到的内容"
self.finished.emit(content)
class Window(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.resize(400, 300)
self.lineEdit = QLineEdit()
self.pushButton = QPushButton("获取内容")
self.label = QLabel()
layout = QVBoxLayout(self)
layout.addWidget(self.lineEdit)
layout.addWidget(self.pushButton)
layout.addWidget(self.label)
self.pushButton.clicked.connect(self.start_worker)
self.worker = Worker()
self.worker.finished.connect(self.update_label)
def start_worker(self):
self.worker.start()
def update_label(self, content):
self.label.setText(content)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
在这个例子中,我们创建了一个`Worker`类,它继承自`
QT
hread`类,并包含一个`finished`信号。在`run`方法中,我们可以执行子线程需要执行的任务,例如获取窗口控件内容,并通过`finished`信号将结果发送到主线程。
在`Window`类中,我们创建了一个`Worker`实例,并将其`finished`信号连接到`update_label`方法。在`start_worker`方法中,我们启动子线程。当子线程完成并发出`finished`信号时,`update_label`方法将被调用,主线程中的标签控件将更新为子线程获取到的内容。
您可以根据您的具体需求修改代码。
weixin_47561700:
(三)Yolov5--模型文件(yolov5s.yaml)解读和模型修改
Wy_stu1:
(三)Yolov5--模型文件(yolov5s.yaml)解读和模型修改
weixin_51035428: