精华内容
下载资源
问答
  • PyQt5线程

    千次阅读 2019-06-03 09:25:40
    线程一般有两种办法: 继承QThread 继承QObject并使用movetothread(官方推荐) 使用第二种方法时,在线程结束后要执行以下两行代码: self.test_thread2.quit() self.test_thread2.wait() ...from PyQt5...

     多线程一般有两种办法:

    1. 继承QThread
    2. 继承QObject并使用movetothread(官方推荐)

    使用第二种方法时,在线程结束后要执行以下两行代码:

    self.test_thread2.quit()
    self.test_thread2.wait()

     如果不确保线程完全退出,线程再次运行时程序会崩溃。

    效果图:

    源码:

    import time
    
    from PyQt5.QtCore import QObject, pyqtSignal, QThread
    
    from PyQt5.QtWidgets import QProgressBar, QApplication, QPushButton, QDialog, QGridLayout
    
    
    class TestWorker1(QThread):
        _signal = pyqtSignal(int)
    
        def __init__(self):
            super(TestWorker1, self).__init__()
    
        def run(self):
            for i in range(101):
                print(i)
                self._signal.emit(i)
                time.sleep(0.01)
    
    
    class TestWorker2(QObject):
        _signal = pyqtSignal(int)
        finished = pyqtSignal()
    
        def __init__(self):
            super(TestWorker2, self).__init__()
    
        def run(self):
            for i in range(101):
                print(i)
                self._signal.emit(i)
                time.sleep(0.01)
            self.finished.emit()
    
    
    class ThreadDialog(QDialog):
        def __init__(self):
            super(ThreadDialog, self).__init__()
    
            self.grid_layout = QGridLayout(self)
            self.progress = QProgressBar(self)
            self.grid_layout.addWidget(self.progress, 0, 0, 1, 2)
            self.pushbutton1 = QPushButton('继承线程', self)
            self.grid_layout.addWidget(self.pushbutton1, 1, 0, 1, 1)
            self.pushbutton2 = QPushButton('movetothread', self)
            self.grid_layout.addWidget(self.pushbutton2, 1, 1, 1, 1)
    
            self.pushbutton1.clicked.connect(self.pushbutton1_clicked)
            self.pushbutton2.clicked.connect(self.pushbutton2_clicked)
    
        def pushbutton1_clicked(self):
            self.test_worker1 = TestWorker1()
            self.test_worker1._signal.connect(self.progress.setValue)
            self.test_worker1.start()
    
        def pushbutton2_clicked(self):
            self.test_worker2 = TestWorker2()
            self.test_thread2 = QThread()
            self.test_worker2.moveToThread(self.test_thread2)
            self.test_worker2._signal.connect(self.progress.setValue)
            self.test_worker2.finished.connect(self.test_worker2_finished)
            self.test_thread2.started.connect(self.test_worker2.run)
            self.test_thread2.start()
    
        def test_worker2_finished(self):
            self.test_thread2.quit()
            self.test_thread2.wait()
    
    
    if __name__ == '__main__':
        import sys
    
        app = QApplication(sys.argv)
        thread_dialog = ThreadDialog()
        thread_dialog.show()
        app.exec_()

     

    展开全文
  • PyQt5线程添加进度条

    千次阅读 2018-12-15 23:26:50
    amp;amp;lt;开始>按钮后加载模型计算,pyqt界面卡住等待计算结束。目的是添加进度条,优化用户等待。一开始以为添加进度条加上时钟就行,...from PyQt5.QtCore import * class MyCal(QThread): ...

    问题:点击<开始>按钮后加载模型计算,pyqt界面卡住等待计算结束。目的是添加进度条,优化用户等待。一开始以为添加进度条加上时钟就行,调试后发现把计算部分写在主界面类里,计算和进度条无法一起进行。
    解决:需要把计算部分分离出去另起一个线程。

    线程类的结构

    以我程序所写的线程类为参考如下

    from PyQt5.QtCore import *
    class MyCal(QThread):
       #自定义一个信号名
        cal_signal = pyqtSignal(np.ndarray, np.ndarray)  #定义信号返回的数值类型
        #构造函数
        def __init__(self, model, img, parent=None):     #model为传入的模型,img为传入的要处理的图片
            super(MyCal, self).__init__(parent)
            self.work = True
            self.model = model
            self.cam_image = img
        #析构函数
        def __del__(self):
            self.work = False
            self.wait()
        #该线程主程序
        def run(self):
            mask, overley = self.model.predict(self.cam_image)   
            self.cal_signal.emit(mask, overley)          #发射信号,传参数
    

    在主线程界面中调用上面的线程 并 设置进度条时钟

    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent=parent)
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
            #此处省略一系列初始化操作
            ######################
            self.pbar = self.ui.progressBar
            self.timer = QBasicTimer()       #初始化一个时钟
            self.step = 0                              #进度条的值
            self.ui.btn_run.clicked.connect(self.btn_click) #连接槽函数
        def btn_click(self):
            if self.cam_image is None:
                        return
            self.ui.btn_run.setEnabled(False)
            self.timer.start(100, self)                    #启动QBasicTimer,每100ms调用一次事件回调函数
            self.cal = MyCal(self.model, self.cam_image)   #点击按钮后新建计算的线程 
            self.cal.cal_signal.connect(self.cal_callback) #连接计算线程的信号
            self.cal.start()                               #开始运行线程
            
        def cal_callback(self, mask, overley):   #接收到计算线程信号后的回掉函数
              #省略 使用接收到线程返回的参数
              ##########################
        def timerEvent(self, *args, **kwargs):             #QBasicTimer的事件回调函数
        # 把进度条每次充值的值赋给进度条
            self.pbar.setValue(self.step)
            if self.step >= 100:
                # 停止进度条
                self.timer.stop()
                self.step = 0
                return
        #把进度条卡在99,等处理好了再到100
            if self.step < 99:
                self.step += 1
    
    
    展开全文
  • 一、PyQt5线程防卡死 在界面中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件或者做一些操作,这些操作会耗时,如果不能及时结束,主线程将会阻塞,这样界面就会出现未响应的状态,因此必须使用多线程...
  • 一、PyQt5线程防卡死 在界面中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件或者做一些操作,这些操作会耗时,如果不能及时结束,主线程将会阻塞,这样界面就会出现未响应的状态,因此必须使用多线程...

    心得:写着写着找到了自己的感觉,还是需要大量的代码和项目来加深对代码的理解

    一、PyQt5多线程防卡死

    在界面中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件或者做一些操作,这些操作会耗时,如果不能及时结束,主线程将会阻塞,这样界面就会出现未响应的状态,因此必须使用多线程来解决这个问题。

    # -*- coding: UTF-8 -*-
    """"=================================================
    @Project -> File   :Django 
    @IDE    :PyCharm
    @Author :爱跳水的温文尔雅的laughing
    @Date   :2020/4/2 21:56
    @Desc   :
    =================================================="""
    
    from PyQt5.QtCore import pyqtSignal, QThread
    from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication
    from untitled import Ui_MainWindow
    import sys
    import time
    
    class Example(QThread):
        signal = pyqtSignal(str)  # 括号里填写信号传递的参数
    
        def __init__(self):
            super(Example, self).__init__()
    
        def __del__(self):
            self.wait()
    
        def run(self):
            """
            进行任务操作,主要的逻辑操作,返回结果
            """
            for i in range(10): 
                time.sleep(0.5)
                self.signal.emit(str("hello world"+str(i)))  # 发射信号
    
    
    class MyWindows(QMainWindow, Ui_MainWindow):
        def __init__(self):
            super(MyWindows, self).__init__()
            self.setupUi(self)
            self.pushButton.clicked.connect(self.buttonClick)
    
        # 点击事件启动线程
        def buttonClick(self):
            self.thread = Example()
            self.thread.signal.connect(self.callback) #连接回调函数,接收结果
            self.thread.start()  # 启动线程
    
        def callback(self, msg):
            self.lineEdit.setText(str(msg))
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        mywindow = MyWindows()
        mywindow.show()
        sys.exit(app.exec_())
    
    

    点击之后显示会从1到9,逻辑运行在子线程,前端显示在主线程
    在这里插入图片描述

    二、PyQt5多窗口用法

    点击事件直接切换窗口

    class MyWindows(QMainWindow, Ui_MainWindow):
        sig = pyqtSignal() #实例化信号
    
        def __init__(self):
            super(MyWindows, self).__init__()
            self.setupUi(self)
            self.pushButton.clicked.connect(self.slot_btn_function)  #设定点击事件
    
        def slot_btn_function(self):
            # self.hide()
            self.f = Children() #第二个实例化UI
            self.f.show()
    

    自定义信号和槽函数来打开第二个窗口

    # -*- coding: UTF-8 -*-
    """"=================================================
    @Project -> File   :Django -> 二叉树之有序列表
    @IDE    :PyCharm
    @Author :爱跳水的温文尔雅的laughing
    @Date   :2020/4/2 21:56
    @Desc   :
    =================================================="""
    from PyQt5.QtCore import pyqtSignal, QThread
    from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication
    from untitled import Ui_MainWindow
    from children import Ui_Dialog
    import sys
    
    #第二个子窗口,当然子窗口也可以用多线程
    class Children(QWidget, Ui_Dialog):
        def __init__(self):
            super(Children, self).__init__()
            self.setupUi(self)
    
    
    #主窗口
    class MyWindows(QMainWindow, Ui_MainWindow):
        sig = pyqtSignal() #实例化信号
    
        def __init__(self):
            super(MyWindows, self).__init__()
            self.setupUi(self)
            self.pushButton.clicked.connect(self.buttonClick)  #设定点击事件
            self.sig.connect(self.signal_slot)  #连接信号
    
        def buttonClick(self):
            self.sig.emit()
    
        #实例化第二个窗口
        def signal_slot(self):
            self.s = Children()
            self.s.show()
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        mywindow = MyWindows()
        mywindow.show()
        sys.exit(app.exec_())
    
    

    在这里插入图片描述

    三、Pyqt5常用指令

    1. 设置btn不能被点击
      True可以正常点击
    self.btn.setEnable(False)
    
    1. 菜单按钮绑定事件

    按钮绑定事件

    self.btn.clicked.connect(self.test)
    

    菜单action绑定事件

    self.btn.trigged.connect(self.test)
    
    1. QLabel标签
    label = QLabel(self)
    label.setText("显示内容")  # 写入
    text = label.text()  # 读取
    
    1. QTextEdit文本编辑器
    text_edit = QTextEdit(self)
    text_edit.setText(a) # 设置文本
    text_edit.append(a) # 追加文本
    text = text_edit.toPlainText() # 获取文本
    
    1. QPushButton按键
    button = QPushButton(self)
    button .setChecked() # 设置为可选中
    button.clicked.connect(clicked_function) # 按下触发
    
    def clicked_function():
    	pass
    
    1. QCheckBox复选框和QRadioButton单选按钮
    radio_button1.setChecked(True) # 设置选中,同时只能有一个选中
    check_box.setCheckable(True) # 设置为可被选中
    
    展开全文
  • PyQT——多线程(QThread)

    2021-04-26 18:51:44
    PyQT5线程:多线程QThread前言一、应用场景二、使用多线程解决卡顿和假死第一种:线程锁(QMutex)第二种:信号(Signal) 前言 一、应用场景 在编写GUI界面中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件...

    前言

    一、应用场景

    在编写GUI界面中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件或者做一些操作,这些操作会耗时,如果不能及时结束,主线程将会阻塞,这样界面就会出现未响应的状态,因此必须使用多线程来解决这个问题。

    二、使用多线程

    解决卡顿和假死

    1.两个按钮,分别在控制台打印不同的内容,分别点击两个按钮后,控制台会依次打印内容,多次点击按钮,程序会先循环完上一次的点击,然后再执行下一次的点击,并且窗口可能会出现假死状态。

    下面将这两个循环使用多线程来写,在PyQT5中,使用QThread

    代码如下(示例):

    from PyQt5.Qt import (QApplication, QWidget, QPushButton,
                          QThread)
    import sys
    import time
    
    # 继承QThread
    class Thread_1(QThread):  # 线程1
        def __init__(self):
            super().__init__()
    
        def run(self):
            values = [1, 2, 3, 4, 5]
            for i in values:
                print(i)
                time.sleep(0.5)  # 休眠
    
    class Thread_2(QThread):  # 线程2
        def __init__(self):
            super().__init__()
    
        def run(self):
            values = ["a", "b", "c", "d", "e"]
            for i in values:
                print(i)
                time.sleep(0.5)
    

    执行上述多线程程序,不管我们点击哪个按钮,点击多少次,在控制台会立刻打印内容,且窗口不会出现卡顿,假死。

    2、这里又出现了一个新的问题,当重复点击相同按钮的时候,会多一个循环。例如,点击按钮1,循环打印1,2,3。此时再次点击按钮1,在控制台会开启一个新的循环,我们期望在点击之后开始循环,在循环没有结束之前,此线程不允许使用。有两种解决办法:线程锁和信号

    第一种:线程锁(QMutex)

    1、创建两个线程锁,然后在run里面加锁和解锁,运行程序,点击不同的按钮可以同步运行,可以同步循环打印,点击相同的按钮,先打印完一次循环后,在打印第二次循环,并且主界面不会假死。
    2、这种办法还是不够完善,想要的结果是,点击按钮后,开启循环,当循环没有结束时,不允许点击按钮,这里使用信号。

    第二种:信号(Signal)

    按钮1使用线程锁,按钮2使用信号,注意两者的区别,按钮1可以无限点击,按钮2在点击之后,开启循环,按钮呈不可点击状态,只有当循环结束后,才能被再次点击。

    代码如下(示例):

    from PyQt5.Qt import QApplication, QWidget, QPushButton, QThread, QMutex, pyqtSignal
    import sys
    import time
    
    
    class PreventFastClickThreadMutex(QThread):  # 线程1
        qmut = QMutex()  # 创建线程锁
        def __init__(self):
            super().__init__()
    
    
        def run(self):
            self.qmut.lock()  # 加锁
            values = [1, 2, 3, 4, 5]
            for i in values:
                print(i)
                time.sleep(0.5)  # 休眠
            self.qmut.unlock()  # 解锁
    
    
    class PreventFastClickThreadSignal(QThread):  # 线程2
        _signal = pyqtSignal()
    
        def __init__(self):
            super().__init__()
    
        def run(self):
            values = ["a", "b", "c", "d", "e"]
            for i in values:
                print(i)
                time.sleep(0.5)
            self._signal.emit()
    
    
    class MyWin(QWidget):
        def __init__(self):
            super().__init__()
            # 按钮初始化
            self.btn_1 = QPushButton('按钮1', self)
            self.btn_1.setCheckable(True)
            self.btn_1.move(120, 80)
            self.btn_1.clicked.connect(self.click_1)  # 绑定槽函数
    
            self.btn_2 = QPushButton('按钮2', self)
            self.btn_2.setCheckable(True)
            self.btn_2.move(120, 120)
            self.btn_2.clicked.connect(self.click_2)  # 绑定槽函数
    
        def click_1(self):
            self.thread_1 = PreventFastClickThreadMutex()  # 创建线程
            self.thread_1.start()  # 开始线程
    
        def click_2(self):
            self.btn_2.setEnabled(False)
            self.thread_2 = PreventFastClickThreadSignal()
            self.thread_2._signal.connect(self.set_btn)
            self.thread_2.start()
    
        def set_btn(self):
            self.btn_2.setEnabled(True)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        myshow = MyWin()
        myshow.show()
        sys.exit(app.exec_())
    
    
    展开全文
  • 在编写GUI界面中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件或者做一些操作,这些操作会耗时,如果不能及时结束,主线程将会...下面将这两个循环使用多线程来写,在PyQT5中,使用QThread from Py...
  • pyqt5设计了一个主窗体,在窗体运行时需要把一个无限循环放在一个线程去工作。运行后,发现通过鼠标按主窗体的关闭按键关闭主创体后,线程不会自动终止,依然在运行。尽管对我的使用场景来说,这不是问题,因为...
  • !... 如图所示,我在开启的子线程里启动了4个爬虫,之后写了一个弹窗,但是这个弹窗一弹出来,直接就死机了“python 已经...如果是这样的话,该如何在爬虫结启动并束后给用户弹一个窗告诉他爬虫结束了?求大佬指点!
  • python库中可以用来录音的基本山就是pyaudio(如何还有其他的库,请高手指路),但笔者在实际...通过一段摸索,终于通过多线程和设置标志位的方法,间接实现随时录音,随时结束录音,不用多说直接上代码。#-*-coding...
  • 时间短的线程结束结束后其它线程进入阻塞
  • python 的 PyQT5 问题

    2019-11-04 01:26:32
    from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * global sec sec = 0 class WorkThread(QThread): trigger = pyqtSignal() def __int__(self): super...
  • 不知不觉都已经做完了,最后我们加入一个QProcess作为结束吧。首先还是在QtDesigner中加入一个进度条,然后把它的初始值设定为0,然后pyuic更新一下我们继承到的界面。如果你还不清楚工作流请看app构建第一节。 ...
  • from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal 首先爬虫类需要继承QObject类 在爬虫里定义信号 将每个爬虫定义为信号槽函数 在爬虫函数结束时发送信号 在UI界面里,使用信号链接槽,在槽里定义...
  • pyqt5+scrapy传值问题

    2019-04-14 09:56:34
    pyqt5给爬虫做个界面,但是在界面中的lineEdit文本传不到爬虫中去(要爬微博所以得传一个用于搜索的关键字) 方法是设一个全局变量KEYWORD然后再在界面中用lineEdit修改这个全局变量,最后开启爬虫,读取这个修改...
  • PyQt5 QThread多线MVC 模式简单实例

    千次阅读 2019-04-30 14:00:23
    文章目录1、简介2、功能实现 1、简介 实例for 循环仿照处理耗时操作。比如网络访问,读取文件,访问数据库等。 在线程中进行耗时操作,通过信号槽链接,传递到主程序更新ui ... PyQT5中 QTimer例子 ...
  • 一个简单的FTP客户端,使用pyqt5+python3实现1. 设计需求2. 设计思路3.主要实现4.代码贴图5.结束语附: 1. 设计需求 从ftp服务器下载文件到本地,并且在下载完后把FTP服务器端的该文件移动到指定文件夹,作为已下载...
  • print("接收到是否结束线程\n",th) self.th.quit() self.th.wait() self.update_table2() print("进程结束") def th_start(self, x): """ 使用lambda表达式将实例移动到self.th这个Qthread...
  • from PyQt5.QtCore import * from PyQt5.QtWidgets import * class DialogDemo(QMainWindow): def __init__(self, parent=None): super(DialogDemo, self).__init__(parent) self.setWindowTitle("...
  • python中使用pyqt5制作的GUI界面,在点击开始按钮后界面卡死,显示未响应,什么按钮都无法点击,必须结束进程才可以,如何解决? 补充:开始按钮连接一个槽函数执行的是while循环,是因为单线程执行的原因卡死吗...
  • 原因是在MyWidget中,t是一个局部变量,当mousePressEvent函数结束后,它的生命周期也都结束了,但是这个线程里的程序很有可能还没有运行完,所以才会报错,解决方案如下 t=CustomThread(self.onMsg) 改为 self.t=...
  • 程序启动,创建一个线程(存活周期:直到软件关闭),当点击事件发生,发送信号,该信号连接两个槽,A负责界面变化切换,B进行后台通讯,B通讯结束,再通过信号将结果返回到界面切换,通过这种机制实现界面与通信的...
  • 原因是在MyWidget中,t是一个局部变量,当mousePressEvent函数结束后,它的生命周期也都结束了,但是这个线程里的程序很有可能还没有运行完,所以才会报错,解决方案如下 test=Test(self.msg) 改为 self.test=Test...
  • 《冠状病毒传播仿真器》可以实时模拟从病毒爆发到疫情结束的整个过程,可以通过参数设置在不同情况下疫情的最终结果,本项目使用Python、PyQt5以及多线程技术实现,并且使用了正态分布模拟人员分布以及人员运动轨迹...
  • PyQt5报错原因还是没找到,先用tkinter凑合,然而不知道为什么摄像机采集到的图像用tkinter的label显示出来白平衡不一样,可保存到文件的话又正常了 还有显示窗口是建了一个线程来刷新,可是不知道怎么结束...

空空如也

空空如也

1 2
收藏数 27
精华内容 10
关键字:

pyqt5结束线程