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

PyQt5信號與槽機制案例詳解

 更新時間:2022年03月10日 16:56:31   作者:Yunlord  
信號和槽是一種高級接口,應(yīng)用于對象之間的通信,它是?QT?的核心特性,也是?QT?區(qū)別于其它工具包的重要地方,所有繼承qwidget的控件都支持信號與槽機制,本文給大家介紹下PyQt5信號與槽機制的相關(guān)知識,感興趣的朋友一起看看吧

信號和槽機制是 QT 的核心機制,要精通 QT 編程就必須對信號和槽有所了解。信號和槽是一種高級接口,應(yīng)用于對象之間的通信,它是 QT 的核心特性,也是 QT 區(qū)別于其它工具包的重要地方。

信號和槽是用來在對象間傳遞數(shù)據(jù)的方法:當(dāng)一個特定事件發(fā)生的時候,信號會被發(fā)射出來,槽調(diào)用是用來響應(yīng)相應(yīng)的信號的。Qt中對象已經(jīng)包含了許多預(yù)定義的信號(基本組件都有各自特有的預(yù)定義的信號),根據(jù)使用的場景也可以添加新的信號。同樣Qt的對象中已經(jīng)包含了許多預(yù)定義的槽函數(shù),但也可以根據(jù)使用的場景添加新的槽函數(shù)。

一、概念簡介

所有繼承qwidget的控件都支持信號與槽機制。

信號:當(dāng)一個信號發(fā)生改變時,向外界發(fā)出的信息。

當(dāng)一個信號被發(fā)射的時候,與其關(guān)聯(lián)的槽函數(shù)被立刻執(zhí)行。其中該對象只負責(zé)發(fā)送信號,發(fā)射該信號的對象并不知道是那個對象在接收這個信號。這樣保證了對象與對象之間的低耦合。
如果存在信號和多個槽函數(shù)相關(guān)聯(lián)的時候,當(dāng)信號被發(fā)射時,這些槽的執(zhí)行順序?qū)请S機的、不確定的。

槽:一個執(zhí)行某些操作的函數(shù)或者方法。

當(dāng)和槽連接的信號被發(fā)射時,槽會被調(diào)用。一個槽并不知道是否有任何信號與自己相連接。

信號與槽機制:主要分兩種

手動操作:信號連接槽

自動操作:當(dāng)信號發(fā)出時,連續(xù)的槽函數(shù)會自動執(zhí)行

信號連接

通過調(diào)用 QObject 對象的 connect 函數(shù)來將某個對象的信號與另外一個對象的槽函數(shù)相關(guān)聯(lián),這樣當(dāng)發(fā)射者發(fā)射信號時,接收者的槽函數(shù)將被調(diào)用。該函數(shù)的定義如下:

object.信號.connet(槽函數(shù))

當(dāng)信號與槽沒有必要繼續(xù)保持關(guān)聯(lián)時,可以使用 disconnect 函數(shù)來斷開連接。其定義如下:

disconnect(槽函數(shù))

信號和槽的特點:

1.一個信號可以連接到多個槽:當(dāng)信號發(fā)出后,槽函數(shù)都會被調(diào)用,但是調(diào)用的順序是隨機的,不確定的。

2.多個信號可以連接到同一個槽:其中任何一個信號發(fā)出,槽函數(shù)都會被執(zhí)行。

3.信號的參數(shù)可以是任何的Python類型,如list,dict等python獨有的類型。自定義信號的時候舉例說明。

4.信號和槽的連接可以被移除:比如斷開某個特定信號的關(guān)聯(lián)。

5.信號可以和另外一個信號進行關(guān)聯(lián):第一個信號發(fā)出后,第二個信號也同時發(fā)送。比如關(guān)閉系統(tǒng)的信號發(fā)出之后,同時會發(fā)出保存數(shù)據(jù)的信號。

二、代碼樣例

整體代碼如下:

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider,QGridLayout,QLabel,QHBoxLayout, QGroupBox,
    QVBoxLayout, QApplication,QProgressBar,QPushButton,QMessageBox)
 
class SignalSlot(QWidget):
    def __init__(self):
        super(SignalSlot,self).__init__()      
        self.initUI()
    def initUI(self):
        self.controlsGroup = QGroupBox("運行樣本")
        self.lcdNumber = QLCDNumber(self)
        self.slider = QSlider(Qt.Horizontal, self)
        self.pBar = QProgressBar(self)
        vbox = QVBoxLayout()
        vbox.addWidget(self.pBar)
        vbox.addWidget(self.lcdNumber)
        vbox.addWidget(self.slider)
        self.controlsGroup.setLayout(vbox)
        controlsLayout = QGridLayout()
        self.label1 = QLabel("保存狀態(tài):")
        self.saveLabel = QLabel()
        self.label2 = QLabel("運行狀態(tài):")
        self.runLabel = QLabel()
        self.buttonSave = QPushButton("保存")
        self.buttonRun = QPushButton("運行")
        self.buttonStop = QPushButton("停止")
        self.buttonDisconnect = QPushButton("解除關(guān)聯(lián)")
        self.buttonConnect = QPushButton("綁定關(guān)聯(lián)")
        controlsLayout.addWidget(self.label1,0,0)
        controlsLayout.addWidget(self.saveLabel,0,1)
        controlsLayout.addWidget(self.label2,1,0)
        controlsLayout.addWidget(self.runLabel,1,1)
        controlsLayout.addWidget(self.buttonSave,2,0)
        controlsLayout.addWidget(self.buttonRun,2,1)
        controlsLayout.addWidget(self.buttonStop,2,2)
        controlsLayout.addWidget(self.buttonDisconnect,3,0)
        controlsLayout.addWidget(self.buttonConnect,3,1)
        layout = QHBoxLayout()
        layout.addWidget(self.controlsGroup)
        layout.addLayout(controlsLayout)
        self.setLayout(layout)
        self.buttonRun.clicked.connect(self.buttonSave.clicked)
        self.slider.valueChanged.connect(self.pBar.setValue)
        self.slider.valueChanged.connect(self.lcdNumber.display)
        self.buttonSave.clicked.connect(self.showMessage)
        self.buttonRun.clicked.connect(self.showMessage)
        self.buttonDisconnect.clicked.connect(self.unbindConnection)
        self.buttonConnect.clicked.connect(self.bindConnection)
        self.buttonStop.clicked.connect(self.stop)
        self.setGeometry(300, 500, 500, 180)
        self.setWindowTitle('信號和槽')
    def showMessage(self):
        if self.sender().text() == "保存":
            self.saveLabel.setText("Saved")
        elif self.sender().text() == "運行":
            self.runLabel.setText("Running")
    def unbindConnection(self):
        self.slider.valueChanged.disconnect()
    def bindConnection(self):
    def stop(self):
        self.saveLabel.setText("")
        self.runLabel.setText("")
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = SignalSlot()
    ex.show()
    sys.exit(app.exec_())

控件說明:

控件類型控件名稱作用
controlsGroupQGroupBox為構(gòu)建分組框提供了支持。分組框通常帶有一個邊框和一個標(biāo)題欄,作為容器部件來使用,在其中可以布置各種窗口部件。
lcdNumberQLCDNumber用于顯示一個帶有類似液晶顯示屏效果的數(shù)字。
sliderQSlider提供一個垂直或者水平的滑動條,滑動條是一個用于控制有界值典型的控件,它允許用戶沿水平或者垂直方向在某一范圍內(nèi)移動滑塊,并將滑塊所在的位置轉(zhuǎn)換為一個合法范圍內(nèi)的整數(shù)值
pBarQProgressBar提供了一個水平或垂直的進度條
label1QLabel
  • 占位符
  • 顯示文本
  • 顯示圖片
  • 放置gif動畫
  • 超鏈接
  • 提示標(biāo)記
buttonSaveQPushButton常用的按鈕控件

界面說明: 

程序樣本運行的界面邏輯,先設(shè)定運行的程序樣本數(shù)量,然后先保存后運行的邏輯狀態(tài)。通過slider的滑動來改變progressBar和LCD的顯示數(shù)據(jù);“保存”按鈕保存運行的樣本;“運行”按鈕運行程序樣本;“解除關(guān)聯(lián)”解除slider.valueChanged信號的綁定,此時slider的滑動,不會改變progressBar和LCD的顯示。

self.controlsGroup = QGroupBox("運行樣本")
self.lcdNumber = QLCDNumber(self)
self.slider = QSlider(Qt.Horizontal, self)
self.pBar = QProgressBar(self)
vbox = QVBoxLayout()
vbox.addWidget(self.pBar)
vbox.addWidget(self.lcdNumber)
vbox.addWidget(self.slider)
self.controlsGroup.setLayout(vbox)

實例化一個QGroupBox,在其中添加QProgressBar、QLCDNumber、QSlider控件。

controlsLayout = QGridLayout()
self.label1 = QLabel("保存狀態(tài):")
self.saveLabel = QLabel()
self.label2 = QLabel("運行狀態(tài):")
self.runLabel = QLabel()
self.buttonSave = QPushButton("保存")
self.buttonRun = QPushButton("運行")
self.buttonStop = QPushButton("停止")
self.buttonDisconnect = QPushButton("解除關(guān)聯(lián)")
self.buttonConnect = QPushButton("綁定關(guān)聯(lián)")
 
controlsLayout.addWidget(self.label1,0,0)
controlsLayout.addWidget(self.saveLabel,0,1)
controlsLayout.addWidget(self.label2,1,0)
controlsLayout.addWidget(self.runLabel,1,1)
controlsLayout.addWidget(self.buttonSave,2,0)
controlsLayout.addWidget(self.buttonRun,2,1)
controlsLayout.addWidget(self.buttonStop,2,2)
controlsLayout.addWidget(self.buttonDisconnect,3,0)
controlsLayout.addWidget(self.buttonConnect,3,1)

通過QGridLayout()添加標(biāo)簽以及按鈕。

layout = QHBoxLayout()
layout.addWidget(self.controlsGroup)
layout.addLayout(controlsLayout)
self.setLayout(layout)

 最后通過QHBoxLayout將左右兩個界面合并,形成最終界面。

信號與槽說明:

signal和slot進行綁定。
1.一個信號綁定多個槽:

self.slider.valueChanged.connect(self.pBar.setValue)
self.slider.valueChanged.connect(self.lcdNumber.display)

slider控件的valueChanged信號,同時與QProgressBar的setValue(),QLCDNumber的display()槽函數(shù)綁定,當(dāng)valueChanged信號觸發(fā)的時候,這兩個槽函數(shù)均會被調(diào)用。

2.多個信號綁定到一個槽:

self.buttonSave.clicked.connect(self.showMessage)
self.buttonRun.clicked.connect(self.showMessage)

buttonSave和buttonRun這兩個對象的clicked信號,同時綁定到showMessage()這個槽函數(shù)。無論哪一個信號被觸發(fā),showMessage()這個槽函數(shù)均會被調(diào)用,而根據(jù)self.sender().text() 這個函數(shù)來判斷顯示的不同內(nèi)容。

3.信號和槽的連接可以被移除:

self.buttonDisconnect.clicked.connect(self.unbindConnection)

當(dāng)buttonDisconnect信號觸發(fā)之后,與其關(guān)聯(lián)的槽函數(shù)unbindConnection()中就會執(zhí)行disconnect()方法,如下:

def unbindConnection(self):
        self.slider.valueChanged.disconnect()

其中執(zhí)行disconnect()的時候可以指定解除與某個特定的slot槽的關(guān)聯(lián),比如self.slider.valueChanged.disconnect(self.pBar.setValue),此時解除和QProgressBar的setValue()的關(guān)聯(lián),如果不指定,將解除和這個信號所有關(guān)聯(lián)的槽。

4、信號與信號的關(guān)聯(lián):

self.buttonRun.clicked.connect(self.buttonSave.clicked)

在樣例說明中提到,在運行之前要對樣本進行保存,所以為了保證運行的時候執(zhí)行了保存的操作,所以將buttonRun.clicked信號和buttonSave.clicked信號關(guān)聯(lián)起來。

示例中在沒有執(zhí)行“保存”(buttonSave)的時候,執(zhí)行“運行”(buttonRun),此時由于兩個對象的clicked信號已經(jīng)關(guān)聯(lián),所以buttonSave的clicked同樣會執(zhí)行。

最終結(jié)果:

本文是《從零開始學(xué)PyQt5》第五篇,希望小伙伴們可以多多支持,一起學(xué)習(xí)!

參考:

Pyqt5系列(七)-信號與槽機制_追逐陽光的風(fēng)-CSDN博客_pyqt5信號和槽

到此這篇關(guān)于PyQt5信號與槽機制案例詳解的文章就介紹到這了,更多相關(guān)PyQt5信號與槽機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論