PyQt5的信号与槽函数

目录

一、介绍

二、一个信号连接一个槽

三、一个信号连接多个槽

四、多个信号连接一个槽

五、自定义信号

1、创建自定义信号

2、让自定义信号携带值

3、自定义信号与槽函数连接

六、可以在Qt Designer 中设置信号与槽


一、介绍

信号(signal)和槽(slot)是Qt的核心机制

  • 信号:是对象或空间发射出去的消息。(可以理解为事件)
  • 槽:接收信号。本质是一个函数或方法。(可以理解为事件函数)
    一个信号可以和多个槽来绑定,一个槽可以接收多个信号。

在下图中 

  • (1)widget就是PyQt中的控件对象。其实就是组件
  • (2)signal就是控件对象拥有的信号
  • (3)connect()方法用于连接信号和槽,
  • (4)slot是槽函数名称。

 示例:

red信号stop()槽函数进行连接

green信号go()槽函数进行连接

只有这样连接后,发射的信号才可以调用相应的槽函数。 

总结起来就一句话:连接后,信号发射,槽函数“启动”

traffic_light.red.connect(stop)
traffic_light.green.connect(go)
# 在connect()方法中传入的是函数名

常见信号:

二、一个信号连接一个槽

示例:

import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        btn = QPushButton('Start', self)
        btn.clicked.connect(self.change_text)
    def change_text(self):
        btn = self.sender() 
        if btn.text() == 'Start':
            btn.setText('Stop')
        else:
            btn.setText('Start')
if __name__ == '__main__':
    app = QApplication([])
    window = Window()
    window.show()
    sys.exit(app.exec())
  • 实例化一个QPushButton按钮控件之后,我们将按钮的clicked信号与自定义的change_text()槽函数连接起来。
  • 在槽函数中,我们首先通过text()方法获取到当前单击按钮的文本,如果是“Start”,就调用setText()方法将按钮的文本修改为“Stop”。而如果文本是“Stop”,就将其修改为“Start”。
  • 因为要在槽函数中使用btn对象,所以应该在类的初始化函数__init__()中将btn设置为成员变量,也就是self.btn。当然我们也可以直接通过sender()方法获取到当前发射信号的控件对象
  • 每个控件都有相应的内置信号,比如QPushButton控件有clicked、pressed、released等内置信号。当然我们也可以给控件或窗口自定义一个信号

三、一个信号连接多个槽

一个信号可以连接多个槽函数,也就是信号只用发射一次,就可以调用多个槽函数。

import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.btn = QPushButton('Start', self)
        self.btn.clicked.connect(self.change_text)  #注释1开始
        self.btn.clicked.connect(self.change_size)  #注释1结束
    def change_text(self):
        if self.btn.text() == 'Start':
            self.btn.setText('Stop')
        else:
            self.btn.setText('Start')
    def change_size(self):    # 2
        self.btn.resize(150, 30)
if __name__ == '__main__':
    app = QApplication([])
    window = Window()
    window.show()
    sys.exit(app.exec())
  • clicked信号连接了change_text()槽函数和change_size()槽函数。
  • change_size()槽函数用于改变按钮的尺寸

四、多个信号连接一个槽

QPushButton除了有clicked信号,还有pressed信号和released信号。

pressed信号是在按钮被“按下”那一刻发射,而released信号则是在按钮被“松开”后发射。

“按下”和“松开”其实就构成了一次单击,也就会发射clicked信号。

import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.btn = QPushButton('Start', self)
        self.btn.pressed.connect(self.change_text)     #注释1开始
        self.btn.released.connect(self.change_text)    #注释1结束
    def change_text(self):
        if self.btn.text() == 'Start':
            self.btn.setText('Stop')
        else:
            self.btn.setText('Start')
if __name__ == '__main__':
    app = QApplication([])
    window = Window()
    window.show()
    sys.exit(app.exec())
  • 将pressed信号和released信号都跟change_text()槽函数连接起来。
  • 那么当按钮被“按下”(不“松开”)时,槽函数就会被调用,按钮文本从“Start”变成了“Stop”。
  • 当“松开”按钮后,槽函数再次被调用,按钮文本从“Stop”变回了“Start”。

五、自定义信号

在PyQt中,各个控件内置的信号已经能够让我们实现许多功能需求,但是如果想要更加个性化的功能,我们还得借助自定义信号来实现。

1、创建自定义信号

自定义信号是通过pyqtSignal来创建的,接下来通过示例代码来演示自定义信号的创建过程。

import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class Window(QWidget):
    my_signal = pyqtSignal()                   # 1
    def __init__(self):
        super(Window, self).__init__()
        self.my_signal.connect(self.my_slot)   # 2
    def my_slot(self):
        print(self.width())
        print(self.height())
    def mousePressEvent(self, event):          # 3
        self.my_signal.emit()
if __name__ == '__main__':
    app = QApplication([])
    window = Window()
    window.show()
    sys.exit(app.exec())
  • 实例化一个pyqtSignal对象。
  • 将自定义信号与my_slot()槽函数连接。
  • mousePressEvent()是鼠标按下事件函数,每当鼠标被按下时,该事件函数就会被执行my_siganl信号调用emit()方法将自己发射出去,这样my_slot()槽函数就会被执行,输出窗口的宽和高。

2、让自定义信号携带值

如果想要获取鼠标指针在窗口上的x坐标和y坐标,可以通过信号将坐标值发送过来

import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class Window(QWidget):
    my_signal = pyqtSignal(int, int)       # 1
    def __init__(self):
        super(Window, self).__init__()
        self.my_signal.connect(self.my_slot)
    def my_slot(self, x, y):               # 2
        print(x)
        print(y)
    def mousePressEvent(self, event):      # 3
        x = event.pos().x()
        y = event.pos().y()
        self.my_signal.emit(x, y)
if __name__ == '__main__':
    app = QApplication([])
    window = Window()
    window.show()
    sys.exit(app.exec())
  • 要通过自定义信号传值,我们必须在实例化pyqtSignal对象时明确要传递的值的类型。由于x坐标和y坐标都是整型值,因此要给pyqtSignal传入两个int。
  • 槽函数也要稍做修改,需要增加两个参数,分别用于接收x坐标和y坐标。
  • 现在我们需要在鼠标按下事件中获取鼠标指针的x和y坐标,并通过emit()方法将其随信号一同发射出去。 

3、自定义信号与槽函数连接

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

class Window(QWidget):
    # 自定义信号,不带参数
    my_signal = pyqtSignal()

    def __init__(self,parent=None):
        super(Window, self).__init__(parent)

        self.btn1 = QPushButton("点击", self)
        self.btn1.move(400, 200)

        self.label1 = QLabel(self)
        self.label1.setText("未点击")

        # 连接信号与槽函数
        self.btn1.clicked.connect(self.my_dd)
        # 接收信号,连接到槽函数
        self.my_signal.connect(self.my_slot)

    def my_slot(self):
        self.label1.setText("点击啦!")

    def my_dd(self):
        # 发送自定义信号,无参数
        self.my_signal.emit()

if __name__ == '__main__':
    app = QApplication([])
    window = Window()
    window.show()
    sys.exit(app.exec())

六、可以在Qt Designer 中设置信号与槽

制作一个单击按扭来关闭窗口 

拖一个button出来

点击菜单栏中的Edit,找到Edit Signal/slot,点它

鼠标左键按住button,朝着你喜欢的方向拖动,出现这样的红色箭头就松开

松开后点击左侧的clicked(),然后点击右侧的close()(右侧为空的话将下方的复选框勾上),如图

点击ok,esc退出,Ctrl+r预览,做完了

我们看下效果

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清纯世纪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值