最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Pyqt5實(shí)現(xiàn)多線程程序的使用示例

 更新時(shí)間:2023年11月23日 15:53:34   作者:唐BiuBiu  
Pyqt常常使用主從架構(gòu)(Master-Workers 架構(gòu))來避免界面卡死的情況,本文主要介紹了Pyqt5實(shí)現(xiàn)多線程程序的使用示例,感興趣的可以了解一下

主從架構(gòu)

Pyqt常常使用**主從架構(gòu)(Master-Workers 架構(gòu))**來避免界面卡死的情況。

Master-Workers 架構(gòu)就像它的名字,一個(gè)master統(tǒng)領(lǐng)著幾個(gè)workers一起干活。其中某個(gè)worker倒下了不會(huì)導(dǎo)致整體任務(wù)失敗。matser不用干活,因此可以專心指揮workers。

在qt5中,master代表主線程,主要維持主界面的運(yùn)行。當(dāng)觸發(fā)某項(xiàng)耗時(shí)耗力的任務(wù)時(shí),主線程將這項(xiàng)任務(wù)分配給其他線程(workers)來做。其他線程出現(xiàn)了災(zāi)難性的錯(cuò)誤,不會(huì)影響到主線程,因此程序不會(huì)完全崩潰。且主線程不承擔(dān)耗時(shí)耗力的任務(wù),因此避免了復(fù)雜運(yùn)算時(shí)主界面卡頓的問題。

進(jìn)程和線程詳見1

pyqt5多線程的架構(gòu)一般由三個(gè)模塊實(shí)現(xiàn):

  • Gui.py:只存放GUI界面,一般是Qt Designer生成的代碼,無需做任何修改
  • Thread.py:從線程,主要的邏輯代碼都放在這里。接收主線程的指令,并向主線程返回信號(hào)。
  • Main.py:主線程,負(fù)責(zé)運(yùn)行GUI界面,向從線程發(fā)送指令并接收從線程返回的信號(hào)。

GUI模塊

Qt Designer保存的文件為Gui.ui的格式,使用下面命令轉(zhuǎn)為Gui.py。

pyuic5 Gui.ui -o Gui.py

轉(zhuǎn)換后的代碼結(jié)構(gòu)如下,我們不需要對(duì)這個(gè)代碼做任何修改。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object): # 注意這個(gè)類名,后面在Main.py中找到它
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        # ------- 省略很多行... ------- #
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "標(biāo)題"))
        # ------- 省略很多行... ------- #

不同線程間的信號(hào)與槽

在討論主線程和從線程之前,首先要明確線程間傳遞信號(hào)的方法2。

主 -> 從

主線程到從線程的信號(hào)就是最基本信號(hào)與槽的機(jī)制,使用槽函數(shù)來與從線程通信。一般是Wight被clicked,然后觸發(fā)槽函數(shù)。傳遞的路徑為:1.觸發(fā)信號(hào)事件 -> 2.信號(hào)clicked -> 3.槽函數(shù)接收信號(hào)并運(yùn)行。使用以下語句綁定槽函數(shù):

from Thread import New_thread # 從線程的引用

class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None) -> None:
        super(MainWindow,self).__init__(parent)
        self.setupUi(self)
        
        # ----------------------------------------- #
        # ↓↓↓↓↓↓↓ 不用管上面的代碼,主要看下面 ↓↓↓↓↓↓↓ #
        # ----------------------------------------- #
        
        self.thread = None # 先預(yù)定義一個(gè)從線程的實(shí)例屬性,這里無需將從線程實(shí)例化
        # self.btn為Ui_MainWindow中定義的按鈕,這里將按鈕點(diǎn)擊的信號(hào)與槽函數(shù)self.func連接起來
        self.btn.clicked.connect(self.func) 

    def func(self):
        self.thread = New_thread() # 在槽函數(shù)中實(shí)例化從線程,然后就可以操作從線程了
        self.thread.start()
        pass

有時(shí)我們需要向槽函數(shù)傳遞參數(shù),一般使用偏函數(shù)或lambda,偏函數(shù)可參見3

from functools import partial # 偏函數(shù)的引用
from Thread import New_thread # 從線程的引用

class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None) -> None:
        super(MainWindow,self).__init__(parent)
        self.setupUi(self)
        
        # ----------------------------------------- #
        # ↓↓↓↓↓↓↓ 不用管上面的代碼,主要看下面 ↓↓↓↓↓↓↓ #
        # ----------------------------------------- #
        
        self.thread = None # 先預(yù)定義一個(gè)從線程的實(shí)例屬性,這里無需將從線程實(shí)例化
        # 第一種方法:這個(gè)槽函數(shù)被寫成了偏函數(shù)的形式 partial(self.func, param1, param2)
	    self.btn1.clicked.connect(partial(self.func, param1=1, param2=2)) 
        # 第二種方法:這個(gè)槽函數(shù)被寫成了lambda的形式 lambda:self.func(param1=1, param2=2)
        self.btn2.clicked.connect(lambda:self.func(param1=1, param2=2))
        
    # 這個(gè)槽函數(shù)監(jiān)聽了兩個(gè)信號(hào)哦
    def func(self, param1, param2):
         # 在槽函數(shù)中實(shí)例化從線程,然后就可以操作從線程了
        self.thread = New_thread(param1, param2) # 從線程實(shí)例化也可以放在__init__里面,但我喜歡放在這。
        self.thread.start()
        pass

從 -> 主

從線程向主線程傳遞信號(hào)一般使用自定義信號(hào),觸發(fā)后,從線程的自定義信號(hào)傳遞給主線程連接的槽函數(shù)。觸發(fā)的路徑為1.從線程觸發(fā)信號(hào)emit -> 2.聲明信號(hào)pyqtSignal -> 3.傳遞給主線程連接的槽函數(shù)。使用下面代碼建立自定義信號(hào)。

先在Thread.py中定義信號(hào):

# Thread.py
from PyQt5.QtCore import QThread, pyqtSignal

class New_Thread(QThread):
    # 聲明定義信號(hào),注意它必須是類屬性。
    mySignal = pyqtSignal(int,str) # 后面的參數(shù)是信號(hào)的數(shù)據(jù)類型
    
    def __init__(self) -> None:
        super(New_Thread, self).__init__(parent)
        pass 
    
    def run(self):
        pass
    
    # ------------------------------------------ #
    # ↓↓↓↓↓↓↓ 上面的兩個(gè)函數(shù)不用理會(huì),看下面 ↓↓↓↓↓↓↓ #
    # ------------------------------------------ #
    
    # 下面是從線程的邏輯代碼
    def func(self):
        # ------- 省略很多邏輯代碼... ------- #
        # 向主線程發(fā)送信號(hào)
        self.mySignal.emit(1,"Hello, Pyqt5")

在主線程Main.py中監(jiān)聽信號(hào)并連接到槽:

# Main.py
from Thread import New_thread # 從線程的引用

class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None) -> None:
        super(MainWindow,self).__init__(parent)
        self.setupUi(self)
        
        # ----------------------------------------- #
        # ↓↓↓↓↓↓↓ 不用管上面的代碼,主要看下面 ↓↓↓↓↓↓↓ #
        # ----------------------------------------- #
        
    def func1(self):
        self.thread = New_thread() # 從線程實(shí)例化(也可以放在__init__里面)
        self.thread.start()
        # 監(jiān)聽從線程發(fā)出的信號(hào),并連接到槽函數(shù)func2
        # 記得嗎?mySignal發(fā)出了兩個(gè)數(shù)據(jù),一個(gè)是int類型,一個(gè)str類型
        self.thread.mySignal.connect(self.func2) 
    
    # 槽函數(shù)接收了從線程的信號(hào)
    def func2(self, param1:int, param2:str):
        pass

主線程Main模塊

主線程的作用是維護(hù)UI界面運(yùn)行,下面給出Main模塊的一般架構(gòu)

import sys # 顯示ui界面必要的引用
from PyQt5.QtWidgets import QMainWindow, QApplication # 顯示ui界面必要的引用
from GUI import * # 引用Qt Designer生成的GUI模塊
from Thread import New_thread # 從線程的引用

# 第一個(gè)父類是PyQt5.QtWidgets.QMainWindow(取決于你在Qt Designer選擇的窗口類型)
# 第二個(gè)父類是GUI.Ui_MainWindow
class MainWindow(QMainWindow, Ui_MainWindow): 

    def __init__(self, parent=None) -> None:
        super(MainWindow,self).__init__(parent)
        self.setupUi(self) # 初始化UI界面
        self.thread = None # 先預(yù)定義一個(gè)從線程的實(shí)例屬性,這里無需將從線程實(shí)例化
        self.btn1.clicked.connect(self.func1) # 綁定控件的槽函數(shù),以啟動(dòng)從線程
        self.thread.finished.connect(self.func3) # 監(jiān)聽線程是否完成任務(wù),以結(jié)束從線程
        # 省略一萬行綁定槽函數(shù)的代碼...
        
    # 定義槽函數(shù),這里可以放入從線程。
    def func1(self):
        self.thread = New_Thread() # 實(shí)例化一個(gè)從函數(shù)
        self.thread.start()
        self.thread.mySignal.connect(self.func2) # 監(jiān)聽從線程的信號(hào),并綁定槽函數(shù)
    
    # 定義響應(yīng)從線程信號(hào)的槽函數(shù)
    def func2(self,param:int):
        pass
    
    # 定義結(jié)束從線程的槽函數(shù)
    def func3(self):
        self.thread.stop()
    
    # 省略一萬個(gè)槽函數(shù)...

if __name__ == '__main__':
    # 任何一個(gè)qt應(yīng)用都必須有且僅有一個(gè)QApplication對(duì)象
    # sys.argv是一組命令行參數(shù)的列表。
    # 這行代碼就是實(shí)例化一個(gè)QApplication
    app = QApplication(sys.argv) 
    
    # 主線程實(shí)例化
    main_window = MainWindow()
    
    # 顯示窗口
    main_window.show()
    
    # sys.exit()是Python退出進(jìn)程的函數(shù)
    # QApplication.exec_()的功能是“qt程序進(jìn)入主循環(huán),直到exit()被調(diào)用”
    # 沒有exec_()的話,程序不會(huì)進(jìn)入主循環(huán),會(huì)閃退。沒有sys.exit()的話,程序退出后進(jìn)程不會(huì)結(jié)束。
    sys.exit(app.exec_())

從線程Thread模塊

from PyQt5.QtCore import QThread, pyqtSignal
from functools import partial

class New_Thread(QThread):
    # 聲明定義信號(hào),注意它必須是類屬性。
    mySignal = pyqtSignal(int,str) # 后面的參數(shù)是信號(hào)的數(shù)據(jù)類型
    finishedSignal = pyqtSignal() # 線程完成的信號(hào)
    
    def __init__(self) -> None:
        super(New_Thread, self).__init__(parent)
    
    # run()是父類的方法,這里要重寫run方法
    # 將邏輯代碼放在run里面,當(dāng)主線程調(diào)用thead.start()時(shí)會(huì)自動(dòng)運(yùn)行run函數(shù)。
    def run(self):
        # 省略一萬行代碼
        self.finishedSignal.emit()
    
    # 停止線程
    def stop(self):
        self.isRunning = False # isRunning是父類的屬性,可以停止線程。

參考文章

到此這篇關(guān)于Pyqt5實(shí)現(xiàn)多線程程序的使用示例的文章就介紹到這了,更多相關(guān)Pyqt5多線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • javascript實(shí)現(xiàn)的textarea運(yùn)行框效果代碼 不用指定id批量指定

    javascript實(shí)現(xiàn)的textarea運(yùn)行框效果代碼 不用指定id批量指定

    今天在寫一個(gè)網(wǎng)頁的時(shí)候用到了N多嵌套在textarea標(biāo)簽里的代碼,定義雙擊運(yùn)行其內(nèi)的代碼段。但是每次創(chuàng)建一個(gè)這樣的可運(yùn)行的實(shí)例都要給textarea元素自定義一個(gè)id值和寫入雙擊事件,好不麻煩。
    2009-12-12
  • 微信小程序使用map組件實(shí)現(xiàn)解析經(jīng)緯度功能示例

    微信小程序使用map組件實(shí)現(xiàn)解析經(jīng)緯度功能示例

    這篇文章主要介紹了微信小程序使用map組件實(shí)現(xiàn)解析經(jīng)緯度功能,涉及微信小程序map組件結(jié)合高德地圖進(jìn)行經(jīng)緯度獲取相關(guān)操作技巧,需要的朋友可以參考下
    2019-01-01
  • 微信小程序全局配置以及頁面配置詳解

    微信小程序全局配置以及頁面配置詳解

    微信小程序中我們創(chuàng)建頁面時(shí)會(huì)自動(dòng)創(chuàng)建四個(gè)文件分別為js文件,wxml文件wxss文件最后還有我們今天的主角json配置文件,下面這篇文章主要給大家介紹了關(guān)于微信小程序全局配置以及頁面配置的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • JS+CSS繪制棋盤格的示例代碼

    JS+CSS繪制棋盤格的示例代碼

    在這篇文章中,將為大家展示如何使用css Flex-box和一些JavaScript來設(shè)計(jì)棋盤。文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-05-05
  • 解析Javascript中難以理解的11個(gè)問題

    解析Javascript中難以理解的11個(gè)問題

    這篇文章主要是對(duì)Javascript中難以理解的11個(gè)問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2013-12-12
  • 十分鐘教你上手ES2020新特性

    十分鐘教你上手ES2020新特性

    這篇文章主要介紹了十分鐘教你上手ES2020新特性,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 解決layer.open彈出框不能獲取input框的值為空的問題

    解決layer.open彈出框不能獲取input框的值為空的問題

    今天小編就為大家分享一篇解決layer.open彈出框不能獲取input框的值為空的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • 詳解javascript事件冒泡

    詳解javascript事件冒泡

    這篇文章主要向大家介紹了javascript事件冒泡,以及javascript阻止事件冒泡的實(shí)現(xiàn)代碼,感興趣的朋友可以參考一下
    2016-01-01
  • JavaScript語法 JSON序列化之stringify實(shí)例詳解

    JavaScript語法 JSON序列化之stringify實(shí)例詳解

    這篇文章主要為大家介紹了JavaScript語法 JSON序列化之stringify實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • uniapp引入axios異步框架的完整步驟

    uniapp引入axios異步框架的完整步驟

    雖然Uniapp可以使用Vue.js自帶的$http,但也可以使用Axios,只需要在項(xiàng)目中進(jìn)行簡單的配置,這篇文章主要給大家介紹了關(guān)于uniapp引入axios異步框架的相關(guān)資料,需要的朋友可以參考下
    2023-12-12

最新評(píng)論

白山市| 苏州市| 宁德市| 宜城市| 鸡东县| 易门县| 蚌埠市| 三江| 乌什县| 双峰县| 水富县| 封开县| 阳城县| 白城市| 额济纳旗| 仁寿县| 大新县| 剑阁县| 陕西省| 清水河县| 浦东新区| 邓州市| 抚顺市| 翼城县| 那曲县| 乐山市| 莲花县| 罗城| 潢川县| 通化县| 贵州省| 抚松县| 封开县| 镇宁| 色达县| 都昌县| 阿坝| 金溪县| 蒲江县| 邢台县| 海林市|