PyQt多线程与信号机制

  • A+
所属分类:安全开发

点击阅读原文体验更佳


前言

最近写了一个基于PyQt的程序,在这里记录一下多线程与信号机制的用法


完整项目代码:https://gitee.com/wochinijiamile/suiyi/raw/master/halite-master.zip

pycharm配置pyqt开发环境

首先安装pyqt5和pyqt5-tools

python3 -m pip install PyQt5
python3 -m pip install PyQt5-tools


在pycharm的设置中找到External Tools,点击加号进行如下配置:

PyQt多线程与信号机制



这里Program就是designer.exe的绝对路径,直接用everything搜索designer.exe即可获取其绝对路径

PyQt多线程与信号机制



配置pyuic用于将ui文件编译成py文件:

PyQt多线程与信号机制



使用方法如下:

PyQt多线程与信号机制



代码示例

import multiprocessing
from shutil import copyfile

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QStringListModel, QThread, pyqtSignal, QBasicTimer
from PyQt5.QtWidgets import QFileDialog, QMessageBox
from main import Ui_MainWindow
import subprocess
import re
import multiprocessing
import sys
import os
import random
import time

step = 0

class DemoThread(QThread):
   timer = pyqtSignal()
   def run(self) -> None:
       while True:
           self.demo()
           global step
           if step >= 5:
               break
       self.timer.emit()

   def demo(self):
       self.sleep(1)
       #something to do
       global step
       step += 1

class ProcessBarWorkThread(QThread):
   timer = pyqtSignal()
   def run(self) -> None:
       while True:
           #每一秒钟发送一次绘制信号
           self.sleep(1)
           self.timer.emit()

class MainWindow(QtWidgets.QMainWindow):
   def __init__(self, parent=None):
       super(MainWindow, self).__init__(parent=parent)
       self.ui = Ui_MainWindow()
       self.setupMyUi(self)
   def setupMyUi(self, MainWindow):
       self.ui.setupUi(MainWindow)
       # 初始化进度条
       global step
       step = 0
       self.ui.progressBar.setValue(0)
       self.ui.pushButton.clicked.connect(self.on_pushButton_click)
################################################CMS扫描模块事件Begin########################################################
   #点击确定开始绘制进度条
   def on_pushButton_click(self):
       self.demoThread = DemoThread()
       #设置接收到信号时触发的方法
       self.demoThread.timer.connect(self.on_demo_finished)
       self.demoThread.start()
       #初始化进度条
       global step
       step = 0
       self.ui.progressBar.setValue(0)
       self.processBarWorkThread = ProcessBarWorkThread()
       #这里使用lambda匿名方法接受进度条控件参数
       self.processBarWorkThread.timer.connect(lambda: self.processBar(self.ui.progressBar))
       self.processBarWorkThread.start()

   #扫描完成,关闭线程
   def on_demo_finished(self):
       self.demoThread.terminate()

   #绘制进度条
   def processBar(self,processBar):
       global step
       processBar.setValue(step/5*100)
       if step >= 5:
           self.processBarWorkThread.terminate()
           QMessageBox.information(self, "info", "演示结束!")

if __name__ == "__main__":
   app = QtWidgets.QApplication(sys.argv)
   w = MainWindow()
   w.show()
   sys.exit(app.exec_())

效果图:

PyQt多线程与信号机制


可以看到代码中写了两个线程类:DemoThreadProcessBarWorkThread,它们两个都继承自QThread


ProcessBarWorkThread类中,首先使用pyqtSignal初始化一个定时器,然后我们通过sleep方法控制信号发送间隔,本示例程序中是一秒发送一次信号,通过connect方法绑定每次接收到信号时出发的动作

self.processBarWorkThread.timer.connect(lambda: self.processBar(self.ui.progressBar))

processBar方法接受一个QProgressBar类型的对象作为参数来确定要对哪一个进度条控件进行绘制


而另一个线程类:DemoThread是我们的程序中的业务代码,也就是真正干活的线程,我们每完成一定的任务就改变一下全局变量step的值,然后当下一次ProcessBarWorkThread发送信号通知processBar方法进行进度条的绘制时,进度条就会发生变化

这两个线程通信的方式就是使用全局变量step


免责声明:本站提供安全工具、程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负!

转载声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


订阅查看更多复现文章、学习笔记

thelostworld

安全路上,与你并肩前行!!!!

PyQt多线程与信号机制

个人知乎:https://www.zhihu.com/people/fu-wei-43-69/columns

个人简书:https://www.jianshu.com/u/bf0e38a8d400

个人CSDN:https://blog.csdn.net/qq_37602797/category_10169006.html

个人博客园:https://www.cnblogs.com/thelostworld/

FREEBUF主页:https://www.freebuf.com/author/thelostworld?type=article

PyQt多线程与信号机制

欢迎添加本公众号作者微信交流,添加时备注一下“公众号”

PyQt多线程与信号机制


本文始发于微信公众号(thelostworld):PyQt多线程与信号机制

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: