Detailed explanation and examples of python PyQt5 (custom) signals and slots


The so-called PyQt5 advanced custom signal and slot means that we can define signal and slot functions in the way we like, and pass parameters. The general process of custom signal is as follows

  • define signal
  • define slot function
  • Connecting Signals and Slots
  • transmit a signal

1 Define the signal

PyQt5 defines signal objects through class member variables

from PyQt5.QtCore import pyqtSignal
# 无参数的信号
signal1 = pyqtSignal()
# 带一个参数(整数)的信号
signal2 = pyqtSignal(int)
# 带两个参数(整数,字符串)的信号
signal3 = pyqtSignal(int, str)
# 带一个参数(列表)的信号
signal4 = pyqtSignal(list)
# 带一个参数(字典)的信号
signal5 = pyqtSignal(dict)
# 带(整数 字符串)或者(字符串)的信号
signal6 = pyqtSignal([int, str], [str])

2 Define the slot function

Define a slot function that takes a number of different input parameters

def signalCall1(self):
  print("signal1 emit")
def signalCall2(self, val):
  print('signal2 emit, value:', val)
def signalCall3(self, val, text):
  print('signall3 emit, value:', val, text)
def signalCall4(self, val):
  print('signal4 emit, value:', val)
def signalCall5(self, val):
  print('signal5 emit, value', val)
def signalCall6(self, val, text):
  print('signal6 emit,value', val, text)
def signalCall7(self, val):
  print('signal6 ovetload emit',val)

3 Connecting signals and slots

# 信号与槽函数的连接
self.signal1.connect(self.signalCall1)
self.signal2.connect(self.signalCall2)
self.signal3.connect(self.signalCall3)
self.signal4.connect(self.signalCall4)
self.signal5.connect(self.signalCall5)
self.signal6[int, str].connect(self.signalCall6)
self.signal6[str].connect(self.signalCall7)

4 transmit signal

#信号发射
self.signal1.emit()
self.signal2.emit(1)
self.signal3.emit(1,'第三个')
self.signal4.emit([1,2,3,4])
self.signal5.emit({
    
    "name":'JIA','age':'21'})
self.signal6[int,str].emit(1,"第六")
self.signal6[str].emit('第六')

5 instances

from PyQt5.QtCore import QObject,pyqtSignal
class CusSignal(QObject):
  #无参数的信号
  signal1 = pyqtSignal()
  #带一个参数(整数)的信号
  signal2 = pyqtSignal(int)
  #带两个参数(整数,字符串)的信号
  signal3 = pyqtSignal(int,str)
  #带一个参数(列表)的信号
  signal4 = pyqtSignal(list)
  #带一个参数(字典)的信号
  signal5 = pyqtSignal(dict)
  #带(整数 字符串)或者(字符串)的信号
  signal6 = pyqtSignal([int,str],[str])
  def __init__(self, parent=None):
    super(CusSignal, self).__init__(parent)
    #信号与槽函数的链接
    self.signal1.connect(self.signalCall1)
    self.signal2.connect(self.signalCall2)
    self.signal3.connect(self.signalCall3)
    self.signal4.connect(self.signalCall4)
    self.signal5.connect(self.signalCall5)
    self.signal6[int,str].connect(self.signalCall6)
    self.signal6[str].connect(self.signalCall7)
    #信号发射
    self.signal1.emit()
    self.signal2.emit(1)
    self.signal3.emit(1,'第三个')
    self.signal4.emit([1,2,3,4])
    self.signal5.emit({
    
    "name":'JIA','age':'21'})
    self.signal6[int,str].emit(1,"第六")
    self.signal6[str].emit('第六')
  #槽函数
  def signalCall1( self ):
    print("signal1 emit")
  def signalCall2( self,val ):
    print('signal2 emit,value:',val)
  def signalCall3( self,val,text ):
    print('signall3 emit,value:',val,text)
  def signalCall4( self,val ):
    print('signal4 emit,value:',val)
  def signalCall5( self,val ):
    print('signal5 emit,value',val)
  def signalCall6( self,val,text ):
    print('signal6 emit,value',val,text)
  def signalCall7(self, val ):
    print('signal6 ovetload emit', val)
if __name__ == '__main__':
  custSignal = CusSignal()

operation result:
insert image description here

Passing and examples of custom parameters

In the process of pyqt programming, we often encounter the situation of passing custom parameters to the slot function. For example, there is a connection between a signal and the slot function. We know that
button.clicked.connect(show_page)
for the clicked signal, it has no parameters. For the show_page function, we hope it Can accept parameters, I hope the show_page function is as follows

def show_page(self,name):
    print(name',点击了')

So there will be a problem, the number of parameters sent by the signal is different from the number of parameters accepted by the slot function, so how to solve this problem, here are two solutions;

lamdba expression

Use a lambda expression to pass the button number to the slot function, and of course you can pass other things, even the button itself

button1.clicked.connect(lambda :self.onButtonClick(1))
button2.clicked.connect(lambda :self.onButtonClick(2))

Use the partial function in functools

button1.clicked.connect(partial(self.onButtonClick, 1))
button2.clicked.connect(partial(self.onButtonClick, 2))

example

import sys
from PyQt5.QtWidgets import *
from functools import partial
class WinForm(QMainWindow):
  def __init__(self,parent=None):
    super(WinForm, self).__init__(parent)
    #实例化两个按钮
    button1=QPushButton('Button1')
    button2=QPushButton('Button2')
    #todo 第一种方法
    #单击信号关联槽函数,利用Lanbda表达式传递一个参数
    # button1.clicked.connect(lambda :self.onButtonClick(1))
    # button2.clicked.connect(lambda :self.onButtonClick(2))
    #
    #todo 第二种方法
    button1.clicked.connect(partial(self.onButtonClick, 1))
    button2.clicked.connect(partial(self.onButtonClick, 2))
    #实例化窗口
    main=QWidget()
    #设置窗口的布局,并向其中添加控件
    layout=QHBoxLayout(main)
    layout.addWidget(button1)
    layout.addWidget(button2)
    #设置为中央控件
    self.setCentralWidget(main)
  def onButtonClick( self,n ):
    #弹窗信息提示框,输出被点击的信息
    print("Button {0}".format(n))
    QMessageBox.information(self,'信息提示框','Button {0}'.format(n))
if __name__ == '__main__':
  app=QApplication(sys.argv)
  form=WinForm()
  form.show()
  sys.exit(app.exec_())

insert image description here

Reference link: https://blog.csdn.net/weixin_34987818/article/details/113969835

Guess you like

Origin blog.csdn.net/weixin_45928096/article/details/126928975