电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

python GUI庫圖形界面開發之PyQt5 UI主線程與耗時線程分離詳細方法實例

瀏覽:10日期:2022-08-05 18:24:08

在做界面開發時,無論是移動端的Android,還是我們這里講的PyQt5,經常會有一個界面開發準則,那就是UI主線程與耗時子線程一定要分開,主線程負責刷新界面,耗時操作,如網絡交互、磁盤IO等,都應該放在子線程里執行,它們各司其職,保證系統正常運行,提升整體用戶體驗。

軟硬件環境

windows 10 64bit

PyQt5

Anaconda3 with python 3.6.5

實例代碼

首先看下工程目錄結構

python GUI庫圖形界面開發之PyQt5 UI主線程與耗時線程分離詳細方法實例

main.py,這是工程入口文件,它負責創建app

# -*- coding: utf-8 -*-import sysfrom PyQt5.QtWidgets import QApplicationfrom gui.mainwindow import MainWindowif __name__ == ’__main__’: app = QApplication(sys.argv) main_window = MainWindow() main_window.show() sys.exit(app.exec_())

ui_mainwindow.py,負責界面的繪制,這個文件通過designer圖形化工具作圖然后使用pyuic工具生成對應的python代碼

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file ’.mainwindow.ui’## Created by: PyQt5 UI code generator 5.6## WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName('MainWindow') MainWindow.resize(800, 600) MainWindow.setMinimumSize(QtCore.QSize(800, 600)) MainWindow.setMaximumSize(QtCore.QSize(800, 600)) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName('centralwidget') self.button_ok = QtWidgets.QPushButton(self.centralwidget) self.button_ok.setGeometry(QtCore.QRect(260, 220, 230, 140)) self.button_ok.setMinimumSize(QtCore.QSize(230, 140)) self.button_ok.setMaximumSize(QtCore.QSize(230, 140)) font = QtGui.QFont() font.setPointSize(50) self.button_ok.setFont(font) self.button_ok.setFocusPolicy(QtCore.Qt.TabFocus) self.button_ok.setObjectName('button_ok') MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName('statusbar') MainWindow.setStatusBar(self.statusbar) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23)) self.menubar.setObjectName('menubar') self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setObjectName('menuFile') self.menuHelp = QtWidgets.QMenu(self.menubar) self.menuHelp.setObjectName('menuHelp') MainWindow.setMenuBar(self.menubar) self.actionExit = QtWidgets.QAction(MainWindow) self.actionExit.setObjectName('actionExit') self.actionCopy = QtWidgets.QAction(MainWindow) self.actionCopy.setObjectName('actionCopy') self.actionPaste = QtWidgets.QAction(MainWindow) self.actionPaste.setObjectName('actionPaste') self.actionCut = QtWidgets.QAction(MainWindow) self.actionCut.setObjectName('actionCut') self.actionHelp = QtWidgets.QAction(MainWindow) self.actionHelp.setObjectName('actionHelp') self.actionAbout = QtWidgets.QAction(MainWindow) self.actionAbout.setObjectName('actionAbout') self.action_query = QtWidgets.QAction(MainWindow) self.action_query.setObjectName('action_query') self.action_backupDB = QtWidgets.QAction(MainWindow) self.action_backupDB.setObjectName('action_backupDB') self.action_reset_mac = QtWidgets.QAction(MainWindow) self.action_reset_mac.setObjectName('action_reset_mac') self.menuFile.addSeparator() self.menuFile.addAction(self.actionExit) self.menuFile.addSeparator() self.menuHelp.addSeparator() self.menuHelp.addSeparator() self.menuHelp.addAction(self.actionAbout) self.menuHelp.addSeparator() self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuHelp.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate('MainWindow', '分離UI主線程和工作線程')) self.button_ok.setText(_translate('MainWindow', '確定')) self.menuFile.setTitle(_translate('MainWindow', 'File')) self.menuHelp.setTitle(_translate('MainWindow', 'Help')) self.actionExit.setText(_translate('MainWindow', '退出')) self.actionHelp.setText(_translate('MainWindow', '軟件使用說明')) self.actionAbout.setText(_translate('MainWindow', '關于'))

mainwindow.py,主要負責界面上控件的事件處理

import timefrom PyQt5.QtWidgets import QMainWindowfrom gui.ui_mainwindow import *class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) # 綁定點擊事件 self.button_ok.clicked.connect(self.button_start) def button_start(self): self.button_ok.setChecked(True) self.button_ok.setDisabled(True) time.sleep(20)

這里我們使用time.sleep(20)來模擬耗時任務,執行python main.py后一會,界面就會出現無響應,假死的現象,等到20秒過后,界面又恢復了正常,用戶體驗非常差。

python GUI庫圖形界面開發之PyQt5 UI主線程與耗時線程分離詳細方法實例

其實要解決這個問題,也非常簡單。我們將UI主線程中的time.sleep(20)移動到子線程中就可以了。PyQt5中提供了線程類QThread,我們繼承它并重寫它的run方法,新建一個新的文件threads.py

# -*- coding: utf-8 -*-import timefrom PyQt5.QtCore import QThread, pyqtSignalclass WorkThread(QThread): # 使用信號和UI主線程通訊,參數是發送信號時附帶參數的數據類型,可以是str、int、list等 finishSignal = pyqtSignal(str) # 帶參數示例 def __init__(self, ip, port, parent=None): super(WorkThread, self).__init__(parent) self.ip = ip self.port = port def run(self): ’’’ 重寫 ’’’ print(’=============sleep======ip: {}, port: {}’.format(self.ip, self.port)) time.sleep(20) self.finishSignal.emit(’This is a test.’) return

注意到這里我們使用了pyqtSignal,我們使用它來跟UI主線程通訊,一般用于界面元素的刷新,在子線程的最后,我們發送這個信號。

對應的mainwindow.py,需要進行如下修改

from gui.threads import WorkThread# 其它部分省略def button_start(self): print(’button_start clicked.’) # 設置按鈕不可用 self.button_ok.setChecked(True) self.button_ok.setDisabled(True) self.th = WorkThread(ip=’192.168.1.1’, port=4000) # 將線程th的信號finishSignal和UI主線程中的槽函數button_finish進行連接 self.th.finishSignal.connect(self.button_finish) # 啟動線程 self.th.start()def button_finish(self, msg): print(’msg: {}’.format(msg)) # 設置按鈕可用 self.button_ok.setChecked(False) self.button_ok.setDisabled(False)

一頓操作之后,再次執行python main.py,界面就再也不會出現No Resonding的提示了,可以在子線程執行過程中可以隨意操作界面上的其它控件

更多相關知道請查看下面的相關鏈接

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 山东螺杆空压机,烟台空压机,烟台开山空压机-烟台开山机电设备有限公司 | U拓留学雅思一站式服务中心_留学申请_雅思托福培训 | 宁波普瑞思邻苯二甲酸盐检测仪,ROHS2.0检测设备,ROHS2.0测试仪厂家 | 济南网站建设_济南网站制作_济南网站设计_济南网站建设公司_富库网络旗下模易宝_模板建站 | 储能预警-储能消防系统-电池舱自动灭火装置-四川千页科技股份有限公司官网 | 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 - 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 | 活性氧化铝球|氧化铝干燥剂|分子筛干燥剂|氢氧化铝粉-淄博同心材料有限公司 | SPC工作站-连杆综合检具-表盘气动量仪-内孔缺陷检测仪-杭州朗多检测仪器有限公司 | 昆山PCB加工_SMT贴片_PCB抄板_线路板焊接加工-昆山腾宸电子科技有限公司 | 玄米影院| 加盟店-品牌招商加盟-创业项目商机平台 | 长城人品牌官网 | 小型高低温循环试验箱-可程式高低温湿热交变试验箱-东莞市拓德环境测试设备有限公司 | 手术示教系统-数字化手术室系统-林之硕医疗云智能视频平台 | 智慧物联网行业一站式解决方案提供商-北京东成基业 | 东莞注册公司-代办营业执照-东莞公司注册代理记账-极刻财税 | 铝合金重力铸造_铝合金翻砂铸造_铝铸件厂家-东莞市铝得旺五金制品有限公司 | 品牌策划-品牌设计-济南之式传媒广告有限公司官网-提供品牌整合丨影视创意丨公关活动丨数字营销丨自媒体运营丨数字营销 | 纳米涂料品牌 防雾抗污纳米陶瓷涂料厂家_虹瓷科技 | 伶俐嫂培训学校_月嫂培训班在哪里报名学费是多少_月嫂免费政府培训中心推荐 | 拖鞋定制厂家-品牌拖鞋代加工厂-振扬实业中国高端拖鞋大型制造商 | 中红外QCL激光器-其他连续-半导体连续激光器-筱晓光子 | 新中天检测有限公司青岛分公司-山东|菏泽|济南|潍坊|泰安防雷检测验收 | 威客电竞(vk·game)·电子竞技赛事官网| 西安烟道厂家_排气道厂家_包立管厂家「陕西西安」推荐西安天宇烟道 | 陕西安玻璃自动感应门-自动重叠门-磁悬浮平开门厂家【捷申达门业】 | 汝成内控-行政事业单位内部控制管理服务商| 工装定制/做厂家/公司_工装订做/制价格/费用-北京圣达信工装 | 东莞海恒试验仪器设备有限公司 | 无压烧结银_有压烧结银_导电银胶_导电油墨_导电胶-善仁(浙江)新材料 | 河北中仪伟创试验仪器有限公司是专业生产沥青,土工,水泥,混凝土等试验仪器的厂家,咨询电话:13373070969 | 安徽控制器-合肥船用空调控制器-合肥家电控制器-合肥迅驰电子厂 安徽净化板_合肥岩棉板厂家_玻镁板厂家_安徽科艺美洁净科技有限公司 | 泥沙分离_泥沙分离设备_泥砂分离机_洛阳隆中重工机械有限公司 | 滤芯,过滤器,滤油机,贺德克滤芯,精密滤芯_新乡市宇清流体净化技术有限公司 | 天津试验仪器-电液伺服万能材料试验机,恒温恒湿标准养护箱,水泥恒应力压力试验机-天津鑫高伟业科技有限公司 | 展厅设计公司,展厅公司,展厅设计,展厅施工,展厅装修,企业展厅,展馆设计公司-深圳广州展厅设计公司 | 石膏基自流平砂浆厂家-高强石膏基保温隔声自流平-轻质抹灰石膏粉砂浆批发-永康市汇利建设有限公司 | ★济南领跃标识制作公司★济南标识制作,标牌制作,山东标识制作,济南标牌厂 | 山东led显示屏,山东led全彩显示屏,山东LED小间距屏,临沂全彩电子屏-山东亚泰视讯传媒有限公司 | 剪刃_纵剪机刀片_分条机刀片-南京雷德机械有限公司 | 太原装修公司_山西整装家装设计_太原室内装潢软装_肖邦家居 |