PyQt - 槽連線



管理訊號-槽連線是 PyQt 的重要功能之一,它能夠實現應用程式不同元件之間的通訊。**connectSlotsByName()** 函式用於在 PyQt 中自動建立這些訊號-槽連線,前提是程式碼是由 **pyuic5** 生成的。在訊號過載的情況下,我們無法自動繫結訊號-槽連線,因此需要手動干預。

使用 connectSlotsByName() 自動連線訊號和槽

PyQt 中的 **connectSlotsByName()** 函式可以根據簡單的命名約定自動建立訊號到槽的連線。當 GUI 元素髮出的訊號與 Python 程式碼中的槽名稱匹配時,PyQt 會自動建立連線。這種約定簡化了事件處理,並減少了顯式連線語句的需求。

自動訊號槽連線的問題

對於具有相同訊號名稱但引數型別不同的過載訊號,自動將槽連線到其中一個訊號將變得困難。假設您有一個 **QSpinBox** 部件,它在值更改時發出兩個訊號:**valueChanged(int)** 和 **valueChanged(const QString &)**。如果實現了名為 on_spinbox_valueChanged 的槽,則預設情況下它將連線到訊號的兩個變體。因此,在每次值更改事件中,槽將被呼叫兩次,一次帶整數引數,一次帶字串引數。

使用 pyqtSlot() 處理過載訊號

為了解決由過載訊號引起的問題,可以使用 **pyqtSlot()** 裝飾器來指定槽應該連線到的確切訊號。透過使用 **pyqtSlot()** 裝飾槽定義,開發人員可以確保精確的訊號-槽對映,從而提高程式碼清晰度和功能性。

例如,要將槽專門連線到 **QSpinBox** 發出的 **valueChanged** 訊號的整數變體,可以如下注釋槽定義:

@pyqtSlot(int)
def on_spinbox_valueChanged(self, i):
   # Slot implementation for integer variant.
   pass

在這種情況下,槽只會響應帶有整數引數的訊號,忽略字串變體。使用 **pyqtSlot()** 裝飾器的這種過程使開發人員能夠嚴格控制訊號處理,使其符合應用程式的要求。

示例 1:處理整數變體訊號

from PyQt5.QtWidgets import QApplication, QMainWindow, QSpinBox
from PyQt5.QtCore import pyqtSlot

class MainWindow(QMainWindow):
   def __init__(self):
      super().__init__()
      self.spinBox = QSpinBox(self)
      self.spinBox.valueChanged.connect(self.on_spinbox_valueChanged)

   @pyqtSlot(int)
   def on_spinbox_valueChanged(self, value):
      print("Integer value changed:", value)

if __name__ == "__main__":
   app = QApplication([])
   window = MainWindow()
   window.show()
   app.exec_()

輸出

Handling Integer Variant Signal
Integer value changed: 5

示例 2:處理字串變體訊號

from PyQt5.QtWidgets import QApplication, QMainWindow, QSpinBox
from PyQt5.QtCore import pyqtSlot

class MainWindow(QMainWindow):
   def __init__(self):
      self.spinBox = QSpinBox(self)
      self.spinBox.valueChanged[str].connect(self.on_spinbox_valueChanged)

   @pyqtSlot(str)
   def on_spinbox_valueChanged(self, value):
      print("String value changed:", value)

if __name__ == "__main__":
   app = QApplication([])
   window = MainWindow()
   window.show()
   app.exec_()

輸出

Handling Value Variant Signal
String value changed: 1
String value changed: 2
String value changed: 3
String value changed: 4
String value changed: 5

使用自定義槽名稱區分訊號變體

當需要處理過載訊號的兩個變體,但使用不同的槽實現時,可以使用 **pyqtSlot()** 裝飾器的 **name** 引數分配自定義槽名稱。這種方法允許將多個槽連線到同一個訊號,其中每個槽可以處理特定訊號變體。

示例

@pyqtSlot(int, name='on_spinbox_valueChanged')
def spinbox_int_value(self, i):
   # Slot implementation for integer variant.
   pass

@pyqtSlot(str, name='on_spinbox_valueChanged')
def spinbox_qstring_value(self, s):
   # Slot implementation for string variant.
   pass

在這裡,定義了兩個槽,每個槽都使用 **pyqtSlot()** 裝飾器進行註釋並分配了不同的名稱。儘管共享相同的訊號源,但這些槽將被單獨連線,確保 **valueChanged** 訊號的每個變體都被路由到相應的槽。

示例:使用自定義槽名稱處理兩個訊號變體

from PyQt5.QtWidgets import QApplication, QMainWindow, QSpinBox
from PyQt5.QtCore import pyqtSlot

class MainWindow(QMainWindow):
   def __init__(self):
      super().__init__()
      self.spinBox = QSpinBox(self)
      self.spinBox.valueChanged[int].connect(self.spinbox_int_value)
      self.spinBox.valueChanged[str].connect(self.spinbox_qstring_value)

   @pyqtSlot(int, name='on_spinbox_valueChanged')
   def spinbox_int_value(self, value):
      print("Integer value changed:", value)

   @pyqtSlot(str, name='on_spinbox_valueChanged')
   def spinbox_qstring_value(self, value):
      print("String value changed:", value)

if __name__ == "__main__":
   app = QApplication([])
   window = MainWindow()
   window.show()
   app.exec_()

輸出

Handling Both Int String Variant
String value changed: 1
Integer value changed: 1
String value changed: 2
Integer value changed: 2
String value changed: 3
Integer value changed: 3
String value changed: 4
Integer value changed: 4
String value changed: 5
Integer value changed: 5
廣告

© . All rights reserved.