<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
訊號和槽機制是 QT 的核心機制,要精通 QT 程式設計就必須對訊號和槽有所瞭解。訊號和槽是一種高階介面,應用於物件之間的通訊,它是 QT 的核心特性,也是 QT 區別於其它工具包的重要地方。
訊號和槽是用來在物件間傳遞資料的方法:當一個特定事件發生的時候,訊號會被髮射出來,槽呼叫是用來響應相應的訊號的。Qt中物件已經包含了許多預定義的訊號(基本元件都有各自特有的預定義的訊號),根據使用的場景也可以新增新的訊號。同樣Qt的物件中已經包含了許多預定義的槽函數,但也可以根據使用的場景新增新的槽函數。
所有繼承qwidget的控制元件都支援訊號與槽機制。
訊號:當一個訊號發生改變時,向外界發出的資訊。
當一個訊號被髮射的時候,與其關聯的槽函數被立刻執行。其中該物件只負責傳送訊號,發射該訊號的物件並不知道是那個物件在接收這個訊號。這樣保證了物件與物件之間的低耦合。
如果存在訊號和多個槽函數相關聯的時候,當訊號被髮射時,這些槽的執行順序將會是隨機的、不確定的。
槽:一個執行某些操作的函數或者方法。
當和槽連線的訊號被髮射時,槽會被呼叫。一個槽並不知道是否有任何訊號與自己相連線。
訊號與槽機制:主要分兩種
手動操作:訊號連線槽
自動操作:當訊號發出時,連續的槽函數會自動執行
訊號連線
通過呼叫 QObject 物件的 connect 函數來將某個物件的訊號與另外一個物件的槽函數相關聯,這樣當發射者發射訊號時,接收者的槽函數將被呼叫。該函數的定義如下:
object.訊號.connet(槽函數)
當訊號與槽沒有必要繼續保持關聯時,可以使用 disconnect 函數來斷開連線。其定義如下:
disconnect(槽函數)
訊號和槽的特點:
1.一個訊號可以連線到多個槽:當訊號發出後,槽函數都會被呼叫,但是呼叫的順序是隨機的,不確定的。
2.多個訊號可以連線到同一個槽:其中任何一個訊號發出,槽函數都會被執行。
3.訊號的引數可以是任何的Python型別,如list,dict等python獨有的型別。自定義訊號的時候舉例說明。
4.訊號和槽的連線可以被移除:比如斷開某個特定訊號的關聯。
5.訊號可以和另外一個訊號進行關聯:第一個訊號發出後,第二個訊號也同時傳送。比如關閉系統的訊號發出之後,同時會發出儲存資料的訊號。
整體程式碼如下:
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("儲存狀態:") self.saveLabel = QLabel() self.label2 = QLabel("執行狀態:") self.runLabel = QLabel() self.buttonSave = QPushButton("儲存") self.buttonRun = QPushButton("執行") self.buttonStop = QPushButton("停止") self.buttonDisconnect = QPushButton("解除關聯") self.buttonConnect = QPushButton("繫結關聯") 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_())
控制元件說明:
控制元件型別 | 控制元件名稱 | 作用 |
---|---|---|
controlsGroup | QGroupBox | 為構建分組框提供了支援。分組框通常帶有一個邊框和一個標題列,作為容器部件來使用,在其中可以佈置各種視窗部件。 |
lcdNumber | QLCDNumber | 用於顯示一個帶有類似液晶顯示屏效果的數位。 |
slider | QSlider | 提供一個垂直或者水平的滑動條,滑動條是一個用於控制有界值典型的控制元件,它允許使用者沿水平或者垂直方向在某一範圍內移動滾軸,並將滾軸所在的位置轉換為一個合法範圍內的整數值 |
pBar | QProgressBar | 提供了一個水平或垂直的進度條 |
label1 | QLabel |
|
buttonSave | QPushButton | 常用的按鈕控制元件 |
介面說明:
程式樣本執行的介面邏輯,先設定執行的程式樣本數量,然後先儲存後執行的邏輯狀態。通過slider的滑動來改變progressBar和LCD的顯示資料;“儲存”按鈕儲存執行的樣本;“執行”按鈕執行程式樣本;“解除關聯”解除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("儲存狀態:") self.saveLabel = QLabel() self.label2 = QLabel("執行狀態:") self.runLabel = QLabel() self.buttonSave = QPushButton("儲存") self.buttonRun = QPushButton("執行") self.buttonStop = QPushButton("停止") self.buttonDisconnect = QPushButton("解除關聯") self.buttonConnect = QPushButton("繫結關聯") 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()新增標籤以及按鈕。
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()槽函數繫結,當valueChanged訊號觸發的時候,這兩個槽函數均會被呼叫。
2.多個訊號繫結到一個槽:
self.buttonSave.clicked.connect(self.showMessage) self.buttonRun.clicked.connect(self.showMessage)
buttonSave和buttonRun這兩個物件的clicked訊號,同時繫結到showMessage()這個槽函數。無論哪一個訊號被觸發,showMessage()這個槽函數均會被呼叫,而根據self.sender().text() 這個函數來判斷顯示的不同內容。
3.訊號和槽的連線可以被移除:
self.buttonDisconnect.clicked.connect(self.unbindConnection)
當buttonDisconnect訊號觸發之後,與其關聯的槽函數unbindConnection()中就會執行disconnect()方法,如下:
def unbindConnection(self): self.slider.valueChanged.disconnect()
其中執行disconnect()的時候可以指定解除與某個特定的slot槽的關聯,比如self.slider.valueChanged.disconnect(self.pBar.setValue),此時解除和QProgressBar的setValue()的關聯,如果不指定,將解除和這個訊號所有關聯的槽。
4、訊號與訊號的關聯:
self.buttonRun.clicked.connect(self.buttonSave.clicked)
在樣例說明中提到,在執行之前要對樣本進行儲存,所以為了保證執行的時候執行了儲存的操作,所以將buttonRun.clicked訊號和buttonSave.clicked訊號關聯起來。
範例中在沒有執行“儲存”(buttonSave)的時候,執行“執行”(buttonRun),此時由於兩個物件的clicked訊號已經關聯,所以buttonSave的clicked同樣會執行。
最終結果:
本文是《從零開始學PyQt5》第五篇,希望小夥伴們可以多多支援,一起學習!
參考:
Pyqt5系列(七)-訊號與槽機制_追逐陽光的風-CSDN部落格_pyqt5訊號和槽
到此這篇關於PyQt5訊號與槽機制案例詳解的文章就介紹到這了,更多相關PyQt5訊號與槽機制內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45