PyQt5零基础入门:信号与槽

前言

PyQt5的信号与槽是一种对象之间的通信机制,允许一个QObject对象发出信号,与之相连接的槽函数将会自动执行。信号与槽有以下几个特点:

  • 信号可以携带任意个、任意类型的参数。
  • 一个信号可以连接多个槽,即一个槽可以监听多个信号。
  • 信号与槽的连接方式可以是同步连接,也可以是异步连接。
  • 信号与槽可能会在不同的线程间连接,这时信号连接只能是异步方式。
  • 信号不是必须有槽和其连接,即信号可以不处理。
  • 信号个槽的连接可以被断开。

PyQt5使用pyqtSignal函数为QObject对象创建信号,并把信号定义为类的属性。使用connect()函数可以将信号绑定到槽函数上,使用disconnect()函数可以接触信号和槽之间的绑定。

信号与槽单对单

直接连接

python 复制代码
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)

    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())

在上述代码中创建一个QPushButton对象self.btn,并将其文本设置为"Start"。这个按钮被添加到当前窗口中(由self表示)。

self.btn.clicked.connect(self.change_text): 当按钮被点击时,将调用change_text方法。在change_text的方法中根据当前按钮显示的文字改变为另一个文字。

这个简单的程序创建了一个窗口,其中包含一个可以切换其标签的按钮("Start"和"Stop")。每次点击按钮时,都会调用change_text方法来更改其标签。

运行结果如下,运行时按钮上的文字是Start,按下之后会变成Stop

使用lambda表达式

python 复制代码
import sys
from PyQt5.QtWidgets import *

class Window(QWidget):
    def __init__(self):
        super().__init__()
        btn = QPushButton("Start", self)
        btn.clicked.connect(lambda:btn.setText("Stop"))


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

在上述代码中我们并没有创建新的槽函数,只采用lambda表达式来设置按钮的值。不过与上一个方法相比,这个代码只能将Start变成Stop,但是不能变回Start

运行结果与上种方式相同

信号与槽多对多

一个信号连接多个槽

python 复制代码
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)
        self.btn.clicked.connect(self.change_size)

    def change_text(self):
        if self.btn.text() == "Start":
            self.btn.setText("Stop")
        else:
            self.btn.setText("Start")

    def change_size(self):
        self.btn.resize(150, 30)


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

在代码中,按钮除了连接到了改变按钮文字的槽函数之外还连接到了更换按钮大小的槽函数,所以在按下按钮后除了改变了文字,还改变了按钮大小。

运行结果如下

多个信号连接一个槽

python 复制代码
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)
        self.btn.released.connect(self.change_text)

    def change_text(self):
        if self.btn.text() == "Start":
            self.btn.setText("Stop")
        else:
            self.btn.setText("Start")


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

在上述代码中

当按钮被按下时,会触发 pressed 信号,连接 pressed 信号到 self.change_text 函数,每次按钮被按下时,self.change_text 函数都会被调用。

当按钮被释放时,会触发 released 信号,连接 released 信号到 self.change_text 函数,每次按钮被释放时,self.change_text 函数都会被调用。

所以,self.change_text 函数会在按钮被按下和释放时都被调用。

信号与信号连接

python 复制代码
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.btn.released)
        self.btn.released.connect(self.change_text)

    def change_text(self):
        if self.btn.text() == "Start":
            self.btn.setText("Stop")
        else:
            self.btn.setText("Start")


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

在上述代码中将pressed连接到released,而released连接到了change_text。运行效果和上面代码一致

自定义信号

python 复制代码
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *


class Window(QWidget):
    my_signal = pyqtSignal(int, int)
    def __init__(self):
        super().__init__()
        self.my_signal.connect(self.my_slot)

    def my_slot(self, x, y):
        print(x)
        print(y)

    def mousePressEvent(self, event):
        x = event.pos().x()
        y = event.pos().y()
        self.my_signal.emit(x, y)


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

在PyQt5中mousePressEvent是鼠标按下时会触发的信号,我们自己定义的信号self.my_signal与槽函数my_slot相连接,当鼠标按下时,self.my_signal使用emit触发self.my_signal信号。效果就是点击窗口会输出当前鼠标位置。

相关推荐
倔强的石头_10 分钟前
你的 Python 为什么“优雅地慢”?——读《极速Python:高性能编码、计算与数据分析》
python
程序猿 小项目大搞头17 分钟前
视频加水印,推荐使用运营大管家-视频批量加水印软件
python
Adorable老犀牛39 分钟前
可遇不可求的自动化运维工具 | 2 | 实施阶段一:基础准备
运维·git·vscode·python·node.js·自动化
xchenhao1 小时前
SciKit-Learn 全面分析 digits 手写数据集
python·机器学习·分类·数据集·scikit-learn·svm·手写
胡耀超2 小时前
7、Matplotlib、Seaborn、Plotly数据可视化与探索性分析(探索性数据分析(EDA)方法论)
python·信息可视化·plotly·数据挖掘·数据分析·matplotlib·seaborn
tangweiguo030519872 小时前
Django REST Framework 构建安卓应用后端API:从开发到部署的完整实战指南
服务器·后端·python·django
Dfreedom.2 小时前
在Windows上搭建GPU版本PyTorch运行环境的详细步骤
c++·人工智能·pytorch·python·深度学习
兴科Sinco2 小时前
[leetcode 1]给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数[力扣]
python·算法·leetcode
程序员奈斯2 小时前
Python深度学习:NumPy数组库
python·深度学习·numpy
yongche_shi2 小时前
第二篇:Python“装包”与“拆包”的艺术:可迭代对象、迭代器、生成器
开发语言·python·面试·面试宝典·生成器·拆包·装包