PyQt GUI編程——信號與槽

PyQt中使用信號與槽的機制實現對象之間的通信。

信號

當對象改變其狀態時,信號就由該對象發射出去,並且對象只負責發送信號,它不知道另一端是誰在接收這個信號。這樣就做到了真正的信息封裝,能確保對象被當作一個真正的軟件組件來使用。

用於接收信號,並且槽只是普通的對象成員函數。一個槽並不知道是否有其他信號自己相連接,而且對象並不瞭解具體的通信機制。

信號和槽的綁定

 通過調用QObject對象的connect()函數將某個對象的信號與另外一個對象的槽函數相關聯。這樣當發射者發射信號時,接受者的槽函數將被調用。

一個信號可以連接到多個槽,當信號發出後,槽函數都會被調用,但是調用的順序是隨機的,不確定的。

多個信號可以連接到同一個槽,其中任何一個信號發出,槽函數都會被執行。

信號和槽的連接可以被移除,PyQt5提供了disconnect()成員函數來進行解綁。

信號可以和另外一個信號進行關聯;第一個信號發出後,第二個信號也同時發送。

 

一個演示信號和槽的關係的樣例

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

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *


class SignalSlot(QWidget):
   def __init__(self):
      super(SignalSlot, self).__init__()
      self.initUI()

   def initUI(self):
      self.controlsGroup = QGroupBox('信號和槽')
      self.lcdNumber = QLCDNumber(self)  # 創建lcdNumber控件
      self.slider = QSlider(Qt.Horizontal, self)   # 創建slider控件
      self.pBar = QProgressBar(self)  # 創建ProgressBar控件
      vbox = QVBoxLayout()  # 創建垂直佈局
      vbox.addWidget(self.pBar)  # 將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)  # 在網格佈局中1行1列添加控件
      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.slider.valueChanged.connect(self.pBar.setValue)
      self.slider.valueChanged.connect(self.lcdNumber.display)
      self.buttonRun.clicked.connect(self.buttonSave.clicked)
      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.saveLabel.setText("Saved")
         self.runLabel.setText("Running")

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

   def bindConnection(self):
      self.slider.valueChanged.connect(self.pBar.setValue)
      self.slider.valueChanged.connect(self.lcdNumber.display)

   def stop(self):
      self.saveLabel.setText('')
      self.runLabel.setText('')


if __name__ == '__main__':
   app = QApplication(sys.argv)
   ex = SignalSlot()
   ex.show()
   sys.exit(app.exec_())
-------------------------------------------------------------代碼分割線--------------------------------------------

1-47行生成用戶界面

 

47-54行連接了信號與槽。

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

連接滑動條的改變(信號) 到進度條顯示(槽)

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

連接滑動條的改變(信號) 到LCD面板顯示(槽)

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

連接運行按鈕點擊操作(信號) 到保存按鈕點擊操作(信號)

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)

連接停止按鈕點擊操作(信號)到停止操作(槽)

 

66-67行解除了信號和槽的關聯

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

解除滑動條的改變(信號)的一切關聯。

--------------------------------------------------------------------------------------

本文實例來源:《Python程序設計》人民郵電出版社 王學軍 胡暢霞 韓豔峯 主編

That's All .Thankyou!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章