参考网址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: RuntimeError: Given groups=3, weight of size [3, 1, 5, 5], expected input[1, 8, 260, 260] to have 3 channels, but got 8 channels instead 博主,请问BACKBONE里一加模块就报这个错误,怎么修改最好啊 (三)Yolov5--模型文件(yolov5s.yaml)解读和模型修改 Wy_stu1: RuntimeError: Given groups=1, weight of size [512, 1024, 1, 1], expected input[1, 512, 8, 8] to have 1024 channels, but got 512 channels instead 博主帅哥,请问怎么一改模型就报这个错误,怎么修改最好啊 (三)Yolov5--模型文件(yolov5s.yaml)解读和模型修改 weixin_51035428: 博主你好,请问我想试一下小目标检测于是就加了一个检测头,修改了head部分增加了层数,为什么跑起来在terminal里面显示的构造还是原本的层数呢