记录自定义信号创建和使用
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_())