欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用PySide多線程處理圖形界面卡頓問題詳解

 更新時間:2025年04月05日 09:38:40   作者:編程貓貓o  
這篇文章主要介紹了使用PySide多線程處理圖形界面卡頓問題,在制作圖形界面時,只用一個線程很容易導(dǎo)致卡頓無響應(yīng),一旦主線程被阻塞,那么整個圖形界面都會無法繼續(xù)使用,為了解決這個問題,就得使用多線程,需要的朋友可以參考下

在了解pyside多線程之前,如果是初學(xué)者可以先去看看我的另一篇文章Python多線程threading模塊實例詳解,文中有對多線程的概念進行詳細介紹,如果有相關(guān)基礎(chǔ)可直接跳過。

1.為什么要使用多線程

在制作圖形界面時,只用一個線程很容易導(dǎo)致卡頓無響應(yīng),一旦主線程被阻塞,那么整個圖形界面都會無法繼續(xù)使用,為了解決這個問題,就得使用多線程。

多線程的主要目的就是把各種任務(wù)放在子線程里處理,這樣的話就可以保證主界面的流暢使用,尤其是需要我們在主界面上打開多個子界面。

因此在學(xué)習(xí)Pyside/PyQt時,多線程是必定是要學(xué)習(xí)了解的知識點,我們廢話不多說,直接開始!

2.信號與槽

信號與槽是pyside/pyQt中的一個核心概念,學(xué)習(xí)使用pyside/pyQt進行圖形化界面的繪制時必然會使用到,因此我們首先要簡略介紹一下,熟練掌握此處知識點的小伙伴可以直接跳過。

在理解信號與槽這個概念時,我們不用把他想的太復(fù)雜了,只需要知道:信號的作用就是用于觸發(fā)槽函數(shù)。

我們在使用一個軟件例如網(wǎng)易云音樂時,想要播放某首歌,那么點擊播放的按鈕,歌就開始唱,此時點擊這個動作就是一個信號,而歌播放這個過程就是一個函數(shù)。

在編寫界面時也是如此,我們想要把某個觸發(fā)的信號與某個函數(shù)連接在一起,就常常需要使用connect方法,標準的格式是:

對象.對象的方法信號.connect(槽函數(shù))

如果我們點擊一個按鈕對象Mybutton時想要觸發(fā)一個Myfunction函數(shù),那么就寫為:

Mybutton.clicked.connect(Myfunction)

如果到此處仍無法理解沒有關(guān)系,我們繼續(xù)往下看。

3.結(jié)合實例理解

實例1-不使用多線程導(dǎo)致的問題

我們來看第一個實例,該實例想要實現(xiàn)的效果是:點擊圖形界面上的按鈕便開始計時,總共計時10秒,首先來看不使用多線程的情況下發(fā)現(xiàn)的問題:

"""
Pyside6# QThread多線程
實例1:體驗不使用多線程的結(jié)果
"""
from PySide6.QtCore import QThread, Slot, Signal
from PySide6.QtWidgets import QWidget, QApplication, QPushButton, QVBoxLayout, QLabel, QTextEdit
import time
from time import sleep
# 主界面,繼承QWidget類
class MyGUI(QWidget):
    def __init__(self):  # 重寫構(gòu)造方法
        super().__init__()
        self.setup()  # 創(chuàng)建界面
        self.bind()  # 綁定函數(shù)
    def bind(self):
        self.button.clicked.connect(self.timer)  # 將按鈕與開啟新線程的槽函數(shù)通過click信號相連
    def setup(self):
        layout = QVBoxLayout()  # 界面布局為垂直布局
        self.setLayout(layout)  # 設(shè)置layout布局
        self.resize(300, 150)  # 重新設(shè)置界面大小
        self.label = QLabel("點擊按鈕開始計時")  # 定義標簽控件
        self.button = QPushButton("Click!")   # 定義按鈕控件
        self.text_edit = QTextEdit()  # 定義可編輯文本框控件
        layout.addWidget(self.label)  # 放置標簽控件
        layout.addWidget(self.button)  # 放置按鈕控件
        layout.addWidget(self.text_edit)  # 放置文本框界面
    def timer(self):  # 定義一個10s的計時器
        count = 0
        while count < 10:
            time.sleep(1)
            self.text_edit.setText(f"{count}")  # 將當(dāng)前數(shù)值反映到文本框
            count += 1
if __name__ == '__main__':
    app = QApplication([])  # 定義一個應(yīng)用
    window = MyGUI()  # 定義一個界面
    window.show()  # 展示界面
    app.exec()  # 啟動應(yīng)用

運行代碼后,出現(xiàn)以下界面:

點擊按鈕,開始計時:

但是可以發(fā)現(xiàn),事情沒有安裝我們預(yù)想的情況那樣進行,界面直接卡住了,變成“未響應(yīng)”的狀態(tài)。為什么會產(chǎn)生這樣的結(jié)果呢?

原因在于在計時的時候使用了sleep方法來計時,但是sleep實際上是通過阻塞線程的方式實現(xiàn)的延時,如果只使用一個線程,那么自然會把僅有的這一個線程卡住。

解決方法自然是通過多線程,創(chuàng)建子線程來計時,而主線程只負責(zé)主界面的部分,就不會出現(xiàn)這種一直未響應(yīng)的情況。多線程的優(yōu)勢就在于此,可以同時處理多個并發(fā)任務(wù)。

實例2-使用多線程改進上一實例

接下來我們就開始使用多線程對第一個實例進行改進,主線程負責(zé)主界面myGUI,而子線程負責(zé)計時,其使用自定義的timer函數(shù)。

要實現(xiàn)的目標與實例1相同,即點擊按鈕就開始計時,共計時10s并將數(shù)字實時顯示在主界面文本框中。

在實例2中,共有兩處信號和槽函數(shù)的連接:

①點擊按鈕時,觸發(fā)創(chuàng)建子線程槽函數(shù),此處點擊按鈕的信號與子線程槽函數(shù)連接

②子線程啟動后,開始計時,此處計時的信號與主界面在文本框中實時顯示數(shù)字的槽函數(shù)相連接

實例如下:

"""
Pyside6# QThread多線程
實例2:使用多線程改進實例1
"""
from PySide6.QtCore import QThread, Slot, Signal
from PySide6.QtWidgets import QWidget, QApplication, QPushButton, QVBoxLayout, QLabel, QTextEdit
import time
from time import sleep
# 主界面,繼承QWidget類
class MyGUI(QWidget):
    def __init__(self):  # 重寫構(gòu)造方法
        super().__init__()
        self.setup()  # 創(chuàng)建界面
        self.bind()  # 綁定函數(shù)
    def bind(self):
        self.button.clicked.connect(self.start_new_thread)  # 將按鈕與開啟新線程的槽函數(shù)通過click信號相連
    def setup(self):
        layout = QVBoxLayout()  # 界面布局為垂直布局
        self.setLayout(layout)  # 設(shè)置layout布局
        self.resize(300, 150)  # 重新設(shè)置界面大小
        self.label = QLabel("點擊按鈕開始計時")  # 定義標簽控件
        self.button = QPushButton("Click!")   # 定義按鈕控件
        self.text_edit = QTextEdit()  # 定義可編輯文本框控件
        layout.addWidget(self.label)  # 放置標簽控件
        layout.addWidget(self.button)  # 放置按鈕控件
        layout.addWidget(self.text_edit)  # 放置文本框界面
    def start_new_thread(self):
        print("啟動新線程")
        self.thread1 = myThread()  # 創(chuàng)建子線程thread1
        self.thread1.signal_int.connect(self.update_number)  # 【關(guān)鍵】將信號與槽函數(shù)連接
        self.thread1.start()  # 啟動子線程thread1
    @Slot(int)  # 定義一個槽函數(shù), 在函數(shù)前放一個@Slot()表明其是一個槽函數(shù)
    def update_number(self, count):
        self.text_edit.setText(f"{count}")  # 將計時器傳來的信號展示在文本框中
# 子線程類,繼承QThread類
class myThread(QThread):
    signal_int = Signal(int)  # 定義信號
    def __init__(self):
        super().__init__()
    def run(self):
        self.timer()  # 重寫run()方法,啟動線程時自動調(diào)用并運行timer函數(shù),開始計時
    def timer(self):  # 定義一個10s的計時器
        print("開始計時")
        count = 0
        while count < 10:
            time.sleep(1)
            count += 1
            self.signal_int.emit(count)  # 【關(guān)鍵】每秒發(fā)送一次信號,將當(dāng)前計數(shù)數(shù)字傳至主界面顯示
        print("結(jié)束計時")
# 運行應(yīng)用界面程序
if __name__ == '__main__':
    app = QApplication([])  # 定義一個應(yīng)用
    window = MyGUI()  # 定義一個界面
    window.show()  # 展示界面
    app.exec()  # 啟動應(yīng)用

實現(xiàn)的效果如下:

可以看到,此時計時正常進行,主界面無響應(yīng)的情況也不再發(fā)生了,這就是多線程的作用。雖然此處只使用了time阻塞線程的這一特例,但是在其他很多情況下都可以使用,尤其是項目較為復(fù)雜時,需要同時進行多并發(fā)的任務(wù),多線程就必不可少了。

感謝各位支持,之后還會繼續(xù)分享更多有用的知識!想要了解更多可以關(guān)注我或關(guān)注本專欄。

以上就是使用PySide多線程處理圖形界面卡頓問題詳解的詳細內(nèi)容,更多關(guān)于PySide處理圖形界面卡頓的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python元組解密不可變的數(shù)據(jù)之美探索

    Python元組解密不可變的數(shù)據(jù)之美探索

    這篇文章主要介紹了Python元組解密:不可變的數(shù)據(jù)之美,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • python中的二維列表實例詳解

    python中的二維列表實例詳解

    這篇文章主要介紹了python中的二維列表實例詳解,文中給大家介紹了python 二維列表按列取元素的方法,需要的朋友可以參考下
    2018-06-06
  • 舉例講解Python面向?qū)ο缶幊讨蓄惖睦^承

    舉例講解Python面向?qū)ο缶幊讨蓄惖睦^承

    類是面向?qū)ο笳Z言中的標配,同樣類的繼承也是體現(xiàn)面向?qū)ο蟮闹匾匦?這里我們就來舉例講解Python面向?qū)ο缶幊讨蓄惖睦^承,需要的朋友可以參考下
    2016-06-06
  • 使用Python讀寫及壓縮和解壓縮文件的示例

    使用Python讀寫及壓縮和解壓縮文件的示例

    Python的os模塊中提供了基本的文件讀寫方法,而zipfile模塊則針對文件的壓縮和解壓縮操作,這里我們就來看一下使用Python讀寫及壓縮和解壓縮文件的示例:
    2016-07-07
  • Python實現(xiàn)釘釘發(fā)送報警消息的方法

    Python實現(xiàn)釘釘發(fā)送報警消息的方法

    今天小編就為大家分享一篇Python實現(xiàn)釘釘發(fā)送報警消息的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • Python-OpenCV實戰(zhàn):利用 KNN 算法識別手寫數(shù)字

    Python-OpenCV實戰(zhàn):利用 KNN 算法識別手寫數(shù)字

    K-最近鄰(KNN)是監(jiān)督學(xué)習(xí)中最簡單的算法之一,KNN可用于分類和回歸問題。本文將為大家介紹的是通過KNN算法實現(xiàn)識別手寫數(shù)字。文中的示例代碼介紹詳細,需要的朋友可以參考一下
    2021-12-12
  • Python中max函數(shù)用于二維列表的實例

    Python中max函數(shù)用于二維列表的實例

    下面小編就為大家分享一篇Python中max函數(shù)用于二維列表的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python中的True,False條件判斷實例分析

    Python中的True,False條件判斷實例分析

    這篇文章主要介紹了Python中的True,False條件判斷的用法,實例分析了針對不同數(shù)據(jù)類型的條件判斷用法,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • numpy數(shù)組疊加的實現(xiàn)示例

    numpy數(shù)組疊加的實現(xiàn)示例

    本文主要介紹了numpy數(shù)組疊加的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • numpy如何獲取array中數(shù)組元素的索引位置

    numpy如何獲取array中數(shù)組元素的索引位置

    這篇文章主要介紹了numpy獲取array中數(shù)組元素的索引位置,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01

最新評論