PYQT5开启多个线程和窗口,多线程与多窗口的交互实例
作者:liqkjm 发布时间:2023-07-19 04:21:21
标签:PYQT5,多线程,多窗口,交互
每点击一次按钮,弹出一个对话框(子窗口),同时开启一个子线程来执行任务并更新对话框内容,关闭对话框则关闭对应子线程
1. 建立一个简单的主界面和一个自定义对话框
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. 打开弹窗的同时,打开一个子线程,更新对话框中的进度条
在子线程定义信号,关联对话框更新进度条的槽函数
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没有释放正在运行的线程的方法
来源:https://blog.csdn.net/liqkjm/article/details/89331601


猜你喜欢
- 1、说明创建堆有两种基本方法:heappush() 和 heapify()。当使用heappush()时,当新元素添加时,堆得顺序被保持了。
- 目录一、Python执行外部命令1、subprocess模块简介2、subprocess模块的遍历函数3、subprocess模块的Pope
- 本人最近在利用faster_rcnn训练kitti数据集,其中需要将kitti数据集转为voc数据集,但是发现:kitti图片是png格式v
- 由于浏览器是单线程的,因此脚本在载的时候会阻塞下载其它资源;虽然在现在浏览器已经有所改善,但仍然有待改进。 很显然,脚本必须按顺序执行,但没
- 1. 准备工作有朋友可能没用过folium,它其实就是python的一个专业绘制地图的第三方库,所以在使用之前需要先安装它。pip 
- 前言索引对有一定开发经验的同学来说并不陌生,合理使用索引,能大大提升sql查询的性能,可以这么讲,随着业务数据量的不断增长,优化系统的响应速
- 一个比较好用的字符串截取函数:function substring($str, $start, $length){ //比较好用字符串截取函
- 前言本方法基于web2py框架,使用web2py的完整网站数据包创建简单网站。web2py 是一个为Python语言提供的全功能Web应用框
- 一、前期准备1.1 安装环境1、安装python32、打开命令行安装seleniumpip install selenium二、python
- RSS 是一个可用多种扩展来表示的缩写:“RDF 站点摘要(RDF Site Summary)”、“真正简单的辛迪加(Really Simp
- 从一个 Demo 入手为了快速进入状态,我们先搞一个 Demo,当然这个 Demo 是参考 Go 源码 src/net/rpc/s
- selenium 安装与 chromedriver安装我们前文提到,Python脚本中使用了selenium库,而selenium又通过ch
- 虽然以前我写过IE6、IE7、IE8共存的解决方案,但是看到IETester这个软件以后那些都已经没有意义了(那些办法副作用比较大,而且实现
- 1.使用方法:find.py 目录名称 2. 主要是采用python正则表达式来匹配的,可以在keywords中添加自己定义的正则,格式:
- 当我们用一个构造函数创建对象时,其属性就会被添加到this中去。并且被添加到this中的属性实际上不会随着实体发生改变,这时,我们这种做法显
- 目录1.部分转义字符2.slice 切片读取字符串3.调用split()方法分割字符串 ASCII字母4.与字母大小写有关方法5.搜索查找字
- python web.py启动https端口 web.py启动https端口需要ssl
- 摘要:大家提到Mysql的性能优化都是注重于优化sql以及索引来提升查询性能,大多数产品或者网站面临的更多的高并发数据读取问题。然而在大量写
- 一. 介绍fire是python中用于生成命令行界面(Command Line Interfaces, CLIs)的工具,不需要做任何额外的
- 在命令行中使用 Python 时,它可以接收大约 20 个选项(option),语法格式如下:python [-bBdEhiIOqsSuvV