記錄自定義信號創建和使用
1.信號的定義:在類內部,以類屬性形式定義;pyqtSignal([int],[str])
注意:一個信號連接另外一個信號時,必需保證參數類型和個數一致。
信號的定義需要掌握以下幾點:
-
信號的聲明: 信號名 = pyqtSignal(類型)
-
信號的觸發: 信號名.emit(信號內容)
-
信號的接收: 信號所在類實例.信號名.connect(接收函數)
下文以一個右擊按鈕信號demo示例
需要自定義某個控件的信號,你需要創建一個新類繼承原來的類
from PyQt5.Qt import * # 自定義信號按鍵方法程序 class Btn(QPushButton): rightClicked = pyqtSignal([str],[int, str]) #設置自定義信號函數pyqtSignal在使用時默認傳遞一個參數,可以使用[int, str...]傳遞多個參數 def mousePressEvent(self, evt): super(Btn, self).mousePressEvent(evt) #一定要使用super,因為程序先看子類方法再去看父類方法,子類方法覆蓋了 #父類方法,會到導致mousePressEvent()的其他方法無法使用 #evt:事件對象 if evt.button() == Qt.RightButton: print('應該發射右擊信號') self.rightClicked[str].emit(self.text()) #傳遞值,默認是pyqtSignal的第一個參數,可以加[str]確定傳送目標值 self.rightClicked[int, str].emit(888,'xuexi') # emit:確保自定義信號的發射,保證槽函數正確使用 class Window(QWidget): def __init__(self): super(Window, self).__init__() self.setWindowTitle('自定義信號') self.resize(500,500) self.setup_ui() def setup_ui(self): btn = Btn('xx',self) # 繼承自定信號類 btn.rightClicked[int, str].connect(lambda content, c2:print("按鈕右鍵被點擊了", content, c2)) btn.pressed.connect(lambda :print("按鈕被按下")) if __name__ == '__main__': import sys app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
案例二:連接一個槽函數
from PyQt5.Qt import * # 自定義信號按鍵方法程序 class Btn(QPushButton): rightClicked = pyqtSignal() # 定義一個rightClicked信號 # 設置自定義信號函數pyqtSignal在使用時默認傳遞一個參數,可以使用[int, str...]傳遞多個參數 def mousePressEvent(self, evt): super(Btn, self).mousePressEvent(evt) # 一定要使用super,因為程序先看子類方法再去看父類方法,子類方法覆蓋了 # 父類方法,會到導致mousePressEvent()的其他方法無法使用 # evt:事件對象 if evt.button() == Qt.RightButton: print('應該發射右擊信號') self.rightClicked.emit() # 觸發信號 class Window(QWidget): def __init__(self): super(Window, self).__init__() self.setWindowTitle('自定義信號') self.resize(500, 500) self.setup_ui() def cao(self): print('lianjie') def setup_ui(self): btn = Btn('xx', self) # 繼承自定信號類 btn.rightClicked.connect(self.cao) # 鏈接槽函數 if __name__ == '__main__': import sys app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
2.利用裝飾器自動連接信號與槽
核心函數:QMetaObject.connectSlotsByName(obj);@pyqtSlot()
from PyQt5.Qt import * class Window(QWidget): def __init__(self): super(Window, self).__init__() self.setWindowTitle('裝飾器連接信號與槽的學習') self.resize(500,500) self.setup_ui() def setup_ui(self): btn = QPushButton('測試按鈕',self) btn.setObjectName('btn') btn.resize(200,200) btn.move(100,100) btn2 = QPushButton("測試按鈕2", self) btn2.setObjectName("btn2") btn2.resize(200, 200) btn2.move(100, 300) QMetaObject.connectSlotsByName(self) # 注意QMetaObject.connectSlotsByName(obj)一定要放在槽函數控件設置后 # 否則無法使用該方法 @pyqtSlot() # 將@pyqtSlot()放置在槽函數上 def on_btn_clicked(self): print('成功連接') # 槽函數格式為on_ObjectName(控件設置的setObjectName)_信號 if __name__ == '__main__': import sys app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
自定義信號和裝飾器連用
from PyQt5.Qt import * class Btn(QPushButton): rightClicked = pyqtSignal() #設置自定義信號函數pyqtSignal在使用時默認傳遞一個參數,可以使用[int, str...]傳遞多個參數 def mousePressEvent(self, evt): super(Btn, self).mousePressEvent(evt) #一定要使用super,因為程序先看子類方法再去看父類方法,子類方法覆蓋了 #父類方法,會到導致mousePressEvent()的其他方法無法使用 #evt:事件對象 if evt.button() == Qt.RightButton: print('應該發射右擊信號') #傳遞值,默認是pyqtSignal的第一個參數,可以加[str]確定傳送目標值 self.rightClicked.emit() # emit:信號的發射 class Window(QWidget): def __init__(self): super(Window, self).__init__() self.setWindowTitle('裝飾器連接信號與槽的學習') self.resize(500,500) self.setup_ui() def setup_ui(self): btn = Btn('測試按鈕',self) btn.setObjectName('btn') btn.resize(200,200) btn.move(100,100) btn2 = QPushButton("測試按鈕2", self) btn2.setObjectName("btn2") btn2.resize(200, 200) btn2.move(100, 300) QMetaObject.connectSlotsByName(self) # 注意QMetaObject.connectSlotsByName(obj)一定要放在槽函數控件設置后 # 否則無法使用該方法 @pyqtSlot() # 將@pyqtSlot()放置在槽函數上 def on_btn_rightClicked(self): print('成功連接') # 槽函數格式為on_ObjectName(控件設置的setObjectName)_信號 if __name__ == '__main__': import sys app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
上述是通過一個控件類增加自定義信號,下面討論在一個類方法內使用方法
應用場景比如自動刷新數據
步驟分三步:1.創建信號: 信號名 = pyqtSignal(類型)
2.建立信號和槽的連接: 信號所在類實例.信號名.connect(self.槽函數名)
3.發射信號:信號名.emit()
from PyQt5.Qt import * from PyQt5.QtCore import * import sys class Window(QWidget): signal = pyqtSignal() # 1.創建信號 def __init__(self): super(Window, self).__init__() self.setWindowTitle("自定義信號") self.resize(500,500) self.move(500,500) self.setup_ui() def setup_ui(self): self.text= QLineEdit(self) self.text.setText('5') self.text.resize(100,100) self.text.move(50,50) self.signal.connect(self.cao) # 2.自定義信號連接槽函數;注意自定義信號只能類實例調用 self.signal.emit() #3.發射信號 def cao(self): self.text.setText('4') if __name__ =='__main__': app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())