(4)pyqt5教程--->自定义信号和槽(超级绕....)

GitHub连接:
本专栏所有源代码的GitHub直通车

上一篇已经讲了如何去使用对象自带的信号和槽

这一篇是比较绕的,反正我第一次看见,我是挺晕的。在明确一下吧

用下面的这个图来明确一下
(4)pyqt5教程--->自定义信号和槽(超级绕....)
首先我们得知道,谁(发送者)发送了什么信号(信号)给谁接受者,谁接收到了信号并去执行了什么函数(槽函数)

先上代码吧

ui文件代码

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '03.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(691, 509)
        self.verticalLayoutWidget = QtWidgets.QWidget(Form)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(100, 60, 391, 231))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.pushButton_2 = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.verticalLayout.addWidget(self.pushButton_2)
        self.pushButton_3 = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.pushButton_3.setObjectName("pushButton_3")
        self.verticalLayout.addWidget(self.pushButton_3)
        self.pushButton_4 = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.pushButton_4.setObjectName("pushButton_4")
        self.verticalLayout.addWidget(self.pushButton_4)
        self.pushButton_1 = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.pushButton_1.setObjectName("pushButton_1")
        self.verticalLayout.addWidget(self.pushButton_1)
        self.pushButton_5 = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.pushButton_5.setObjectName("pushButton_5")
        self.verticalLayout.addWidget(self.pushButton_5)
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(140, 340, 411, 81))
        font = QtGui.QFont()
        font.setFamily("Agency FB")
        font.setPointSize(14)
        self.label.setFont(font)
        self.label.setObjectName("label")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.pushButton_1.setText(_translate("Form", "无参数"))
        self.pushButton_2.setText(_translate("Form", "一个int型参数"))
        self.pushButton_3.setText(_translate("Form", "int和str型两个参数"))
        self.pushButton_4.setText(_translate("Form", "列表作为参数"))
        self.pushButton_5.setText(_translate("Form", "字典作为参数"))
        self.label.setText(_translate("Form", "自定义的信号和槽测试,以及带参传递"))

主文件代码:

from ui3 import Ui_Form
import sys,time
from PyQt5 import QtWidgets,QtCore


class mydesigner(QtWidgets.QWidget,Ui_Form):
    #定义自定义信号
    signal_1 = QtCore.pyqtSignal()#不带参数

    signal_2 = QtCore.pyqtSignal(int)#带int型参数

    signal_3 = QtCore.pyqtSignal(int,str)#带int和str两个参数

    signal_4 = QtCore.pyqtSignal(list)#带列表型

    signal_5 = QtCore.pyqtSignal(dict)#带字典型

    def __init__(self):
        super(mydesigner,self).__init__()
        self.setupUi(self)

        #为自定义的信号绑定自定义函数,当接收者接收到这个信号的时候,将会执行这个函数
        self.signal_1.connect(self.signal_1_response)
        self.signal_2.connect(self.signal_2_response)
        self.signal_3.connect(self.signal_3_response)
        self.signal_4.connect(self.signal_4_response)
        self.signal_5.connect(self.signal_5_response)
        
        self.pushButton_1.clicked.connect(self.signal_1_call)
        self.pushButton_2.clicked.connect(self.signal_2_call)
        self.pushButton_3.clicked.connect(self.signal_3_call)
        self.pushButton_4.clicked.connect(self.signal_4_call)
        self.pushButton_5.clicked.connect(self.signal_5_call)
        
    def signal_1_call(self):
        self.signal_1.emit()

    def signal_2_call(self):
        self.signal_2.emit(1)

    def signal_3_call(self):
        self.signal_3.emit(1,"test")

    def signal_4_call(self):
        self.signal_4.emit([1,2,3,4])

    def signal_5_call(self):
        self.signal_5.emit({"name":"huhaoming","age":"20"})

    #自定义的槽函数
    def signal_1_response(self):
        print("不带参数")
    def signal_2_response(self,val):
        print("带整形参数:",val)
        
    def signal_3_response(self,val_int,val_str):
        print("带int和str两个参数:",val_int,val_str)
    def signal_4_response(self,val):
        print("带列表型:",val)
    def signal_5_response(self,val):
        print("带字典型:",val)

  
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    myshow = mydesigner()
    myshow.show()
    sys.exit(app.exec_())

为了能够更好的表达我理解,我用下面的这个图配合代码来讲:
(4)pyqt5教程--->自定义信号和槽(超级绕....)

主要理解两行代码就可以

第一:

self.pushButton_1.clicked.connect(self.signal_1_call)

这个意思是主界面按钮点击事件连接着self.signal_1_call这个函数,换一种说法就是当这个按钮点击(不局限与点击,还可以是其它的事件)的时候会去执行self.signal_1_call这个函数,而这个函数就是负责将某个自定义的信号发射出去。在这里是发射给主界面。

第二:

 self.signal_1.connect(self.signal_1_response)

这个的意思就是主界面的这个信号连接着self.signal_1_response这个函数,当主界面接收到这个信号的时候,回去执行,self.signal是主界面的属性,一个信号可以指定连接一个槽函数,这个槽函数就是当你发射这个信号的时候,你希望我去执行的东西。这个槽函数可以直接将参数打印出来。代码中有体现

反正这里是很绕的,不知道各位大佬是怎么学的。弄懂了之后就好受多了(对于强迫症来说)。

**

这个代码可以直接运行的。还有一个点忘记说了,定义自定义信号的时候需用用到pyqtSignal类,所以说信号也可以认为是一个对象,pyqtSignal类在QtCore之下。需要导入

**

对于信号和槽函数的自定义及其传参的时候暂时学习和理解到这里,本篇博客中可能存在错误的地方,仅供参考。后面理解得更好的时候再过来补充。

这个源码也上传到gitHub上面了,连接在博客顶部。

上一篇:操作系统概念 第6章 进程同步


下一篇:线程通信生产者和消费者传统版(sync-wait-notityAll)(lock-await-signal)