PYQT5开启多个线程和窗口,多线程与多窗口的交互实例


Posted in Python onDecember 13, 2019

每点击一次按钮,弹出一个对话框(子窗口),同时开启一个子线程来执行任务并更新对话框内容,关闭对话框则关闭对应子线程

1. 建立一个简单的主界面和一个自定义对话框

PYQT5开启多个线程和窗口,多线程与多窗口的交互实例

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
 def setupUi(self, MainWindow):
  MainWindow.setObjectName("MainWindow")
  MainWindow.resize(327, 303)
  self.centralwidget = QtWidgets.QWidget(MainWindow)
  self.centralwidget.setObjectName("centralwidget")
  self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
  self.gridLayout.setObjectName("gridLayout")
  spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
  self.gridLayout.addItem(spacerItem, 0, 0, 1, 1)
  self.pushButton = QtWidgets.QPushButton(self.centralwidget)
  self.pushButton.setObjectName("pushButton")
  self.gridLayout.addWidget(self.pushButton, 0, 1, 1, 1)
  spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
  self.gridLayout.addItem(spacerItem1, 0, 2, 1, 1)
  MainWindow.setCentralWidget(self.centralwidget)
  self.menubar = QtWidgets.QMenuBar(MainWindow)
  self.menubar.setGeometry(QtCore.QRect(0, 0, 327, 23))
  self.menubar.setObjectName("menubar")
  MainWindow.setMenuBar(self.menubar)
  self.statusbar = QtWidgets.QStatusBar(MainWindow)
  self.statusbar.setObjectName("statusbar")
  MainWindow.setStatusBar(self.statusbar)

  self.retranslateUi(MainWindow)
  self.pushButton.clicked.connect(MainWindow.open_dialog)
  QtCore.QMetaObject.connectSlotsByName(MainWindow)

 def retranslateUi(self, MainWindow):
  _translate = QtCore.QCoreApplication.translate
  MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
  self.pushButton.setText(_translate("MainWindow", "多线程弹窗"))


class Ui_Dialog(object):
 def setupUi(self, Dialog):
  Dialog.setObjectName("Dialog")
  Dialog.resize(369, 128)
  self.gridLayout = QtWidgets.QGridLayout(Dialog)
  self.gridLayout.setObjectName("gridLayout")
  self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
  self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
  self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
  self.buttonBox.setObjectName("buttonBox")
  self.gridLayout.addWidget(self.buttonBox, 1, 0, 1, 1)
  self.progressBar = QtWidgets.QProgressBar(Dialog)
  self.progressBar.setProperty("value", 24)
  self.progressBar.setObjectName("progressBar")
  self.gridLayout.addWidget(self.progressBar, 0, 0, 1, 1)

  self.retranslateUi(Dialog)
  self.buttonBox.accepted.connect(Dialog.accept)
  self.buttonBox.rejected.connect(Dialog.reject)
  QtCore.QMetaObject.connectSlotsByName(Dialog)

 def retranslateUi(self, Dialog):
  _translate = QtCore.QCoreApplication.translate
  Dialog.setWindowTitle(_translate("Dialog", "Dialog"))

2. 每点击一次按钮,打开一个弹窗

class DialogWindow(QDialog, Ui_Dialog):
 def __init__(self, parent=None):
  super(DialogWindow, self).__init__(parent)
  self.setupUi(self)


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
 def __init__(self, parent=None):
  super(MainWindow, self).__init__(parent)
  self.setupUi(self)

 def open_dialog(self):
  dialog = DialogWindow(self)
  dialog.show()


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

3. 打开弹窗的同时,打开一个子线程,更新对话框中的进度条

PYQT5开启多个线程和窗口,多线程与多窗口的交互实例

在子线程定义信号,关联对话框更新进度条的槽函数

class DialogWindow(QDialog, Ui_Dialog):
 def __init__(self, parent=None):
  super(DialogWindow, self).__init__(parent)
  self.setupUi(self)

 def update_progressbar(self, p_int):
  self.progressBar.setValue(p_int) # 更新进度条


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
 def __init__(self, parent=None):
  super(MainWindow, self).__init__(parent)
  self.setupUi(self)
  self.count = 0

 def open_dialog(self):
  dialog = DialogWindow(self)
  dialog.show()
  self.thread = RunThread(self.count)
  self.count += 1
  self.thread.update_pb.connect(dialog.update_progressbar) # 关联
  self.thread.start()


class RunThread(QThread):
 update_pb = pyqtSignal(int) # 定义更新进度条的信号

 def __init__(self, count):
  super().__init__()
  self.count = count

 def run(self):
  for i in range(100):
   print('thread%s' % self.count, i, QThread().currentThreadId())
   self.update_pb.emit(i)
   time.sleep(1)
  pass


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

4. 关闭对话框,则关闭对应子线程

在对话框中添加自定义信号,并重写关闭事件,在关闭窗口时发送关闭子线程的信号

class DialogWindow(QDialog, Ui_Dialog):
 stop_thread = pyqtSignal() # 定义关闭子线程的信号

 def __init__(self, parent=None):
  super(DialogWindow, self).__init__(parent)
  self.setupUi(self)

 def update_progressbar(self, p_int):
  self.progressBar.setValue(p_int)

 def closeEvent(self, event):
  self.stop_thread.emit()
  pass


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
 def __init__(self, parent=None):
  super(MainWindow, self).__init__(parent)
  self.setupUi(self)
  self.count = 0

 def open_dialog(self):
  dialog = DialogWindow(self)
  dialog.show()
  self.thread = RunThread(self.count)
  self.count += 1
  self.thread.update_pb.connect(dialog.update_progressbar)
  dialog.stop_thread.connect(self.thread.terminate)
  self.thread.start()


class RunThread(QThread):
 update_pb = pyqtSignal(int)

 def __init__(self, count):
  super().__init__()
  self.count = count

 def run(self):
  for i in range(1, 101):
   print('thread_%s' % self.count, i, QThread().currentThreadId())
   self.update_pb.emit(i)
   time.sleep(1)
  pass


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

5. 使用线程池QThreadPool管理子线程

使用QThreadPool, 线程需要继承QRunnable,而QRunnable只是namespace,没有继承QT的信号机制,

所以需要另外继承QObject来使用信号,我这里直接在线程中使用封装的信号向外部传递信息

class DialogWindow(QDialog, Ui_Dialog):
 stop_thread = pyqtSignal() # 定义关闭子线程的信号

 def __init__(self, parent=None):
  super(DialogWindow, self).__init__(parent)
  self.setupUi(self)

 def update_progressbar(self, p_int):
  self.progressBar.setValue(p_int)

 def closeEvent(self, event):
  self.stop_thread.emit()
  pass


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
 def __init__(self, parent=None):
  super(MainWindow, self).__init__(parent)
  self.setupUi(self)
  self.count = 0
  self.pool = QThreadPool()
  self.pool.globalInstance()
  self.pool.setMaxThreadCount(10) # 设置最大线程数

 def open_dialog(self):
  dialog = DialogWindow(self)
  dialog.show()
  thread = RunThread(self.count)
  self.count += 1
  thread.signal.update_pb.connect(dialog.update_progressbar)
  # dialog.stop_thread.connect(thread.stop)
  # self.thread.start()
  self.pool.start(thread) # 线程池分配一个线程运行该任务


class Signal(QObject):
 update_pb = pyqtSignal(int)


class RunThread(QRunnable):
 def __init__(self, count):
  super().__init__()
  self.count = count
  self.signal = Signal() # 信号

 def run(self):
  for i in range(1, 101):
   print('thread_%s' % self.count, i, QThread().currentThreadId())
   self.signal.update_pb.emit(i)
   time.sleep(1)


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

QThreadPool没有释放正在运行的线程的方法

以上这篇PYQT5开启多个线程和窗口,多线程与多窗口的交互实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
web.py获取上传文件名的正确方法
Aug 26 Python
python 迭代器和iter()函数详解及实例
Mar 21 Python
Python中标准模块importlib详解
Apr 16 Python
python Pygame的具体使用讲解
Nov 03 Python
Python中optparser库用法实例详解
Jan 26 Python
Python使用Pickle库实现读写序列操作示例
Jun 15 Python
详解Django中类视图使用装饰器的方式
Aug 12 Python
详解python算法之冒泡排序
Mar 05 Python
python实现比对美团接口返回数据和本地mongo数据是否一致示例
Aug 09 Python
flask 使用 flask_apscheduler 做定时循环任务的实现
Dec 10 Python
python读取dicom图像示例(SimpleITK和dicom包实现)
Jan 16 Python
Python实现爬取网页中动态加载的数据
Aug 17 Python
浅谈PyQt5中异步刷新UI和Python多线程总结
Dec 13 #Python
python编写微信公众号首图思路详解
Dec 13 #Python
selenium+python实现自动登陆QQ邮箱并发送邮件功能
Dec 13 #Python
python中设置超时跳过,超时退出的方式
Dec 13 #Python
python opencv实现gif图片分解的示例代码
Dec 13 #Python
python多进程并发demo实例解析
Dec 13 #Python
使用Matplotlib 绘制精美的数学图形例子
Dec 13 #Python
You might like
来自phpguru得Php Cache类源码
2010/04/15 PHP
PHP合并两个数组的两种方式的异同
2012/09/14 PHP
php is_writable判断文件是否可写实例代码
2016/10/13 PHP
php-app开发接口加密详解
2018/04/18 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
2020/06/24 PHP
jQuery控制图片的hover效果(smartRollover.js)
2012/03/18 Javascript
浅谈jquery事件处理
2015/04/24 Javascript
AngularJS使用ng-app自动加载bootstrap框架问题分析
2017/01/04 Javascript
快速掌握jQuery插件开发
2017/01/19 Javascript
vue2.0中goods选购栏滚动算法的实现代码
2017/05/17 Javascript
js实现QQ面板拖拽效果(慕课网DOM事件探秘)(全)
2017/09/19 Javascript
js原生日历的实例(推荐)
2017/10/31 Javascript
vue-router中scrollBehavior的巧妙用法
2018/07/09 Javascript
微信小程序实现复选框效果
2018/12/28 Javascript
vue使用vant中的checkbox实现全选功能
2020/11/17 Vue.js
一张图带我们入门Python基础教程
2017/02/05 Python
python实现俄罗斯方块游戏
2020/03/25 Python
Python实现数据可视化看如何监控你的爬虫状态【推荐】
2018/08/10 Python
python实现决策树分类
2018/08/30 Python
详解利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击
2018/10/09 Python
PyQT实现菜单中的复制,全选和清空的功能的方法
2019/06/17 Python
Python 继承,重写,super()调用父类方法操作示例
2019/09/29 Python
美国在线家居装饰店:Belle&June
2018/10/24 全球购物
新奥尔良珠宝:Mignon Faget
2020/11/23 全球购物
财务管理专业应届毕业生求职信
2013/09/22 职场文书
创业计划书中要认真思考的问题
2013/12/28 职场文书
中学教师教育感言
2014/02/21 职场文书
大学活动总结范文
2014/04/29 职场文书
青春奉献演讲稿
2014/05/08 职场文书
大学生村官个人对照检查材料(群众路线)
2014/09/26 职场文书
信用卡工资证明范本
2014/10/17 职场文书
总经理聘用协议书
2015/09/21 职场文书
大学三好学生主要事迹范文
2015/11/03 职场文书
2016大学生社会实践单位评语
2015/12/01 职场文书
Django+Nginx+uWSGI 定时任务的实现方法
2022/01/22 Python
Python获取字典中某个key的value
2022/04/13 Python