pyqt5 信号与槽和源文件使用总结
简单总结:
①创建信号
②创建方法,并且选择你想发射信号的方法进行信号发射
③创建接收信号的槽函数
④将信号与槽函数关联
例子:这里创建一个Human类(注:必须是QObeject的子类),在该类里创建两个信号,分别为nameChanged和ageChanged,ageChanged为overload型信号,一种为int,一种为str。然后在初始化的方法里面定义sheName和setAge函数,在setName函数里面发射nameChanged信号;在setAge函数里分别发射int和str型的ageChanged信号。接着创建一个Responsor类(注:必须是QObeject的子类),在该类里创建接收信号的槽函数。最后在main函数里面将信号与槽连接。
1 ##自定义信号与槽的演示 2 import sys 3 from PyQt5.QtCore import QObject,pyqtSlot,pyqtSignal 4 import time 5 6 class Human(QObject): 7 ##定义一个带str类型的参数的信号 8 nameChanged = pyqtSignal(str) 9 ##overload型信号有两种参数,一种是int,一种是str,默认为int类型,定义一个带int和str类型参数的信号 10 ageChanged = pyqtSignal([int],[str]) 11 12 #创建设置名字和姓名方法 13 def __init__(self,name="Mike",age=10,parent=None): 14 super().__init__(parent) 15 self.setName(name) 16 self.setAge(age) 17 18 #setAge方法并且发送信号 19 def setAge(self,age): 20 self.__age=age 21 self.ageChanged.emit(self.__age) #发射int信号 22 if age <18: 23 ageInfo ="你好,年轻人" 24 elif (18<=age<35): 25 ageInfo ="你好,中年人" 26 elif (35<=age<55): 27 ageInfo ="你好,大叔" 28 elif (55<=age<80): 29 ageInfo ="你好,大爷" 30 else: 31 ageInfo ="你好,老大爷" 32 33 self.ageChanged[str].emit(ageInfo) #发射str信号 34 35 # setName方法并且发送信号 36 def setName(self,name): 37 self.__name=name 38 self.nameChanged.emit(self.__name) 39 40 class Responsor(QObject): 41 #接收信号的槽函数 42 @pyqtSlot(int) 43 def do_ageChanged_int(self,age): 44 print("你的年龄是:"+str(age)) 45 @pyqtSlot(str) 46 def do_ageChanged_str(ageInfo): 47 print(ageInfo) 48 49 def do_nameChanged(self,name): 50 print("Hello " + name) 51 52 if __name__=="__main__": #测试程序 53 print("**创建对象时**") 54 boy=Human() 55 boy.setName("Boy") 56 boy.setAge(16) 57 resp=Responsor() 58 boy.nameChanged.connect(resp.do_nameChanged) 59 60 ## overload的信号,两个槽函数不能同名,关联时需要给信号加参数区分 61 boy.ageChanged.connect(resp.do_ageChanged_int) #默认参数,int类型 62 boy.ageChanged[str].connect(resp.do_ageChanged_str) #str参数 63 time.sleep(2) 64 print("\n **建立关联后**") 65 boy.setAge(35) #发射两个ageChanged信号 66 boy.setName("Jack") #发射nameChanged信号 67 68 boy.ageChanged[str].disconnect(resp.do_ageChanged_str)
69 #与槽函数断开关联
70 print("\n **断开ageChanged[str]关联后")
71 boy.setAge(10) #发射两个ageChanged信号
该例子中一开始传入Name=“BOy”和Age=16,因为没有将槽与信号连接,控制台没有结果,如图
当连接之后,就开始出现结果,如图
后面讲str类型的ageChabged信号断开之后,发现str类型的槽函数也未触发,如图:
附加:
后面使用UI Designer做成图形化界面,但是几乎都是差不多,这里给出代码:
界面部分:
1 # -*- coding: utf-8 -*- 2 3 # Form implementation generated from reading ui file 'Widget.ui' 4 # 5 # Created by: PyQt5 UI code generator 5.15.4 6 # 7 # WARNING: Any manual changes made to this file will be lost when pyuic5 is 8 # run again. Do not edit this file unless you know what you are doing. 9 10 11 from PyQt5 import QtCore, QtGui, QtWidgets 12 13 14 class Ui_Widget(object): 15 def setupUi(self, Widget): 16 Widget.setObjectName("Widget") 17 Widget.resize(309, 270) 18 self.verticalLayout = QtWidgets.QVBoxLayout(Widget) 19 self.verticalLayout.setObjectName("verticalLayout") 20 self.groupBox_Age = QtWidgets.QGroupBox(Widget) 21 self.groupBox_Age.setObjectName("groupBox_Age") 22 self.gridLayout = QtWidgets.QGridLayout(self.groupBox_Age) 23 self.gridLayout.setObjectName("gridLayout") 24 self.horizontalLayout = QtWidgets.QHBoxLayout() 25 self.horizontalLayout.setObjectName("horizontalLayout") 26 self.label = QtWidgets.QLabel(self.groupBox_Age) 27 self.label.setObjectName("label") 28 self.horizontalLayout.addWidget(self.label) 29 self.SliderSetAge = QtWidgets.QSlider(self.groupBox_Age) 30 self.SliderSetAge.setMaximum(100) 31 self.SliderSetAge.setProperty("value", 50) 32 self.SliderSetAge.setOrientation(QtCore.Qt.Horizontal) 33 self.SliderSetAge.setObjectName("SliderSetAge") 34 self.horizontalLayout.addWidget(self.SliderSetAge) 35 self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1) 36 self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 37 self.horizontalLayout_2.setObjectName("horizontalLayout_2") 38 self.label3 = QtWidgets.QLabel(self.groupBox_Age) 39 self.label3.setObjectName("label3") 40 self.horizontalLayout_2.addWidget(self.label3) 41 self.lineEdit = QtWidgets.QLineEdit(self.groupBox_Age) 42 self.lineEdit.setObjectName("lineEdit") 43 self.horizontalLayout_2.addWidget(self.lineEdit) 44 self.gridLayout.addLayout(self.horizontalLayout_2, 1, 0, 1, 1) 45 self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 46 self.horizontalLayout_3.setObjectName("horizontalLayout_3") 47 self.label2 = QtWidgets.QLabel(self.groupBox_Age) 48 self.label2.setObjectName("label2") 49 self.horizontalLayout_3.addWidget(self.label2) 50 self.lineEdit_2 = QtWidgets.QLineEdit(self.groupBox_Age) 51 self.lineEdit_2.setObjectName("lineEdit_2") 52 self.horizontalLayout_3.addWidget(self.lineEdit_2) 53 self.gridLayout.addLayout(self.horizontalLayout_3, 2, 0, 1, 1) 54 self.verticalLayout.addWidget(self.groupBox_Age) 55 self.groupBox_Name = QtWidgets.QGroupBox(Widget) 56 self.groupBox_Name.setObjectName("groupBox_Name") 57 self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_Name) 58 self.gridLayout_2.setObjectName("gridLayout_2") 59 self.horizontalLayout_4 = QtWidgets.QHBoxLayout() 60 self.horizontalLayout_4.setObjectName("horizontalLayout_4") 61 self.label_4 = QtWidgets.QLabel(self.groupBox_Name) 62 self.label_4.setObjectName("label_4") 63 self.horizontalLayout_4.addWidget(self.label_4) 64 self.editNameInput = QtWidgets.QLineEdit(self.groupBox_Name) 65 self.editNameInput.setObjectName("editNameInput") 66 self.horizontalLayout_4.addWidget(self.editNameInput) 67 self.btnSetName = QtWidgets.QPushButton(self.groupBox_Name) 68 icon = QtGui.QIcon() 69 icon.addPixmap(QtGui.QPixmap(":/icons/images/打钩.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 70 self.btnSetName.setIcon(icon) 71 self.btnSetName.setObjectName("btnSetName") 72 self.horizontalLayout_4.addWidget(self.btnSetName) 73 self.gridLayout_2.addLayout(self.horizontalLayout_4, 0, 0, 1, 1) 74 self.horizontalLayout_5 = QtWidgets.QHBoxLayout() 75 self.horizontalLayout_5.setObjectName("horizontalLayout_5") 76 self.label_5 = QtWidgets.QLabel(self.groupBox_Name) 77 self.label_5.setObjectName("label_5") 78 self.horizontalLayout_5.addWidget(self.label_5) 79 self.editNameHello = QtWidgets.QLineEdit(self.groupBox_Name) 80 self.editNameHello.setObjectName("editNameHello") 81 self.horizontalLayout_5.addWidget(self.editNameHello) 82 self.gridLayout_2.addLayout(self.horizontalLayout_5, 1, 0, 1, 1) 83 self.verticalLayout.addWidget(self.groupBox_Name) 84 self.frame_Button = QtWidgets.QFrame(Widget) 85 self.frame_Button.setFrameShape(QtWidgets.QFrame.StyledPanel) 86 self.frame_Button.setFrameShadow(QtWidgets.QFrame.Raised) 87 self.frame_Button.setObjectName("frame_Button") 88 self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.frame_Button) 89 self.horizontalLayout_6.setObjectName("horizontalLayout_6") 90 spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 91 self.horizontalLayout_6.addItem(spacerItem) 92 spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 93 self.horizontalLayout_6.addItem(spacerItem1) 94 spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 95 self.horizontalLayout_6.addItem(spacerItem2) 96 self.pushButton = QtWidgets.QPushButton(self.frame_Button) 97 icon1 = QtGui.QIcon() 98 icon1.addPixmap(QtGui.QPixmap(":/icons/images/打叉.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 99 self.pushButton.setIcon(icon1) 100 self.pushButton.setObjectName("pushButton") 101 self.horizontalLayout_6.addWidget(self.pushButton) 102 spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 103 self.horizontalLayout_6.addItem(spacerItem3) 104 self.verticalLayout.addWidget(self.frame_Button) 105 106 self.retranslateUi(Widget) 107 QtCore.QMetaObject.connectSlotsByName(Widget) 108 109 def retranslateUi(self, Widget): 110 _translate = QtCore.QCoreApplication.translate 111 Widget.setWindowTitle(_translate("Widget", "Widget")) 112 self.groupBox_Age.setTitle(_translate("Widget", "年龄设置")) 113 self.label.setText(_translate("Widget", "设置年龄(0~100)")) 114 self.label3.setText(_translate("Widget", "ageChanged(int)响应")) 115 self.label2.setText(_translate("Widget", "ageChanged(str)响应")) 116 self.groupBox_Name.setTitle(_translate("Widget", "姓名设置")) 117 self.label_4.setText(_translate("Widget", "输入姓名")) 118 self.btnSetName.setText(_translate("Widget", "设置姓名")) 119 self.label_5.setText(_translate("Widget", "nameChanged(str)响应")) 120 self.pushButton.setText(_translate("Widget", "关闭")) 121 import res_rc
逻辑处理部分:
1 import sys 2 from PyQt5.QtWidgets import QApplication,QWidget 3 from PyQt5.QtGui import QIcon 4 from PyQt5.QtCore import pyqtSlot 5 6 from human import Human 7 from ui_Widget import Ui_Widget 8 9 class QmyWidget(QWidget): 10 def __init__(self,parent=None): 11 super().__init__(parent) 12 self.ui=Ui_Widget() 13 self.ui.setupUi(self) 14 15 self.boy=Human("Boy",16) 16 self.boy.nameChanged.connect(self.do_nameChanged) 17 self.boy.ageChanged.connect(self.do_ageChanged_int) 18 self.boy.ageChanged[str].connect(self.do_ageChanged_str) 19 20 21 #===由connectSlotByname() 自动创建的信号关联的槽函数=== 22 def on_SliderSetAge_valueChanged(self,value): 23 self.boy.setAge(value) 24 25 def on_btnSetName_clicked(self): 26 hisName=self.ui.editNameInput.text() 27 self.boy.setName(hisName) 28 29 def on_pushButton_clicked(self): 30 Qapp=QApplication.instance() 31 Qapp.quit() 32 33 # ===自定义槽函数=== 34 def do_nameChanged(self,name): 35 self.ui.editNameHello.setText("Hello"+name) 36 37 @pyqtSlot(int) 38 def do_ageChanged_int(self,age): 39 self.ui.lineEdit.setText(str(age)) 40 41 @pyqtSlot(str) 42 def do_ageChanged_str(self,info): 43 self.ui.lineEdit_2.setText(info ) 44 45 if __name__=="__main__": 46 app=QApplication(sys.argv) 47 icon = QIcon(":/icons/images/app.png") 48 app.setWindowIcon(icon) #给窗口添加Icon图标
49 form=QmyWidget()
50 form.show()
51 sys.exit(app.exec_())
界面如图:
这里还使用了源文件,即添加一些图标。具体步骤如下:
①在你当前项目点击File-->New File or Project,出现界面如图选择,点击choose后创建一个名字即可,之后就会出现一个与Headers和sources同级目录下的一个Resources文件 :
②点击Resources目录下后缀为.qrc的文件,右键,选择Open in Editor,然后设置自己的目录名称,使用下面的add添加想要的东西
③然后在该目录下通过 pyrcc5 xxx.qrc -o xxx.rc.py 命令将.qrc文件转换为.py文件(注:.py文件必须为xxx_rc.py,"_rc"不可缺少,也必须在.qrc初始文件目录下转换为.py文件后才能复制到你的项目下面,即先转换再复制,例如是想添加log,如果先复制再转换,会造成无法搜索的log路径的问题)
补充:将.ui文件转换为.py文件的命令:
pyuic5 -o ui_xxx.py xxx.ui