PyQt6系列(2)——信号槽、多窗口

系列启语

作者属计算机在读本科生,编写的大部分内容属于个人原创,发文章的目的一是为了总结自己的学习路程,帮助正在学习这方面的人士,二是为了能吸引更优秀的人对文章提出建议,共同进步。

更新速度根据个人时间安排,预计会在十一之前完成。

篇幅原因,此文章只包含两个内容。

信号槽

信号与槽函数

信号槽可以说是 PyQt甚至Qt 最重要的机制之一。

信号,顾名思义是一种发散的类似广播的“标志位”。当用户点击某个按钮,框选某个选项...都会有独自的”广播“信号,如果有对象对这个信号感兴趣,可以使用连接(connect)函数,将某个响应函数与此信号连接。

将某个信号和自己的一个需求函数(称为槽函数)绑定来响应这个信号。当信号产生时,被连接的槽函数会自动执行调用。

一个信号可以连接到多个槽函数上,也可以将多个信号连接到同一个槽函数。

槽函数分两种,一种是不同控件内置的槽函数,还有一种是我们自己定义的槽函数。

简单实例

制作简单计算器窗口

1. 打开qtDesigner

通过PyCharm外部工具方式打开QtDesigner:

具体添加方法在设置中可以添加外部工具(External Tools)

方法类似与Keil5中添加VsCode或TiSyscfg

 找出QtDesigner可执行程序,复制快捷方式至桌面:

designer.exe文件地址(默认:虚拟环境):

工程文件/venv/Lib/site-packages/qt6_applications/Qt/bin/designer.exe

2. 设计UI页面

必须要清楚的一点是,即使一个简单的计算器窗口也不能仅仅依靠QtDesigner实现,QtDesigner是可视化设计UI页面的工具,它并不能详细的编写代码,具体的一些逻辑还是需要在代码层面实现。

创建QWidget,自定义窗口大小等。

添加控件,QLineEdit,QLabel,QPushButton。

 3. PyUIC 转ui文件为python文件

保存此ui文件,PyCharm中使用 PyUIC 转ui文件为python文件:

选中ui文件,按照上述方法打开外部工具PyUIC,得到同名的python代码文件。

pyuic生成的代码文件是QtDesigner下经过特殊的方法转化出来的代码,此时在pycharm下运行是不会有结果的。

我们在做自己的应用程序或者只是一个窗口时,都是讲ui文件的代码复制到一个新的python文件中,添加固定代码框架(下一步骤会提到)即可运行。

 4. 得到可运行的代码

代码框架得到可运行的pyqt代码:具体要添加 / 修改的地方见代码注释。

CSDN_Demo.ui经过PyUIC生成的代码为:

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


from PyQt6 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 200)
        self.lineEdit = QtWidgets.QLineEdit(parent=Form)
        self.lineEdit.setGeometry(QtCore.QRect(20, 60, 61, 51))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(parent=Form)
        self.lineEdit_2.setGeometry(QtCore.QRect(160, 60, 61, 51))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.label = QtWidgets.QLabel(parent=Form)
        self.label.setGeometry(QtCore.QRect(100, 60, 41, 41))
        font = QtGui.QFont()
        font.setPointSize(36)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.lineEdit_3 = QtWidgets.QLineEdit(parent=Form)
        self.lineEdit_3.setGeometry(QtCore.QRect(320, 60, 61, 51))
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.pushButton = QtWidgets.QPushButton(parent=Form)
        self.pushButton.setGeometry(QtCore.QRect(230, 70, 75, 24))
        self.pushButton.setObjectName("pushButton")
        self.label_2 = QtWidgets.QLabel(parent=Form)
        self.label_2.setGeometry(QtCore.QRect(130, 140, 151, 31))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.label.setText(_translate("Form", "+"))
        self.pushButton.setText(_translate("Form", "等于"))
        self.label_2.setText(_translate("Form", "加法计算器窗口"))

 复制拷贝到file.py中,可执行代码:

import sys
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtWidgets import QWidget, QApplication


# 此class 类名字可以改变,但是需要继承QWidget,因为我们创建的窗口是QWidget
# 如果是QMainWindow就对应继承QMainWindow,
class Ui_Form(QWidget):
    def __init__(self):
        super(QWidget, self).__init__() # 需要执行QWidget的初始化,这里的变量与上述变量同
        self.setupUi(self)
    
    # -------------以下内容不改变------------- #
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 200)
        self.lineEdit = QtWidgets.QLineEdit(parent=Form)
        self.lineEdit.setGeometry(QtCore.QRect(20, 60, 61, 51))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(parent=Form)
        self.lineEdit_2.setGeometry(QtCore.QRect(160, 60, 61, 51))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.label = QtWidgets.QLabel(parent=Form)
        self.label.setGeometry(QtCore.QRect(100, 60, 41, 41))
        font = QtGui.QFont()
        font.setPointSize(36)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.lineEdit_3 = QtWidgets.QLineEdit(parent=Form)
        self.lineEdit_3.setGeometry(QtCore.QRect(320, 60, 61, 51))
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.pushButton = QtWidgets.QPushButton(parent=Form)
        self.pushButton.setGeometry(QtCore.QRect(230, 70, 75, 24))
        self.pushButton.setObjectName("pushButton")
        self.label_2 = QtWidgets.QLabel(parent=Form)
        self.label_2.setGeometry(QtCore.QRect(130, 140, 151, 31))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.label.setText(_translate("Form", "+"))
        self.pushButton.setText(_translate("Form", "等于"))
        self.label_2.setText(_translate("Form", "加法计算器窗口"))

    # -------------以上内容不改变------------- # 

# 主函数程序,固定。
if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = Ui_Form() # 将此ui类给某个变量,这里将此ui类赋值给变量ui

    ui.show() # 展示
    sys.exit(app.exec()) # 保持窗口不消失,PyQt5会多一个下划线

 5. 编写槽函数逻辑代码

面向对象编程,在此ui类下编写加法运算函数,在PushButton相关代码下连接按下信号至此运算函数。

        self.pushButton = QtWidgets.QPushButton(parent=Form)
        self.pushButton.setGeometry(QtCore.QRect(230, 70, 75, 24))
        self.pushButton.setObjectName("pushButton")

        # 将PushButton按下的信号连接至响应函数
        self.pushButton.clicked.connect(self.Calculate)
    def Calculate(self):
        a = int(self.lineEdit.text())
        b = int(self.lineEdit_2.text())
        c = a + b  # 简单整形加法运算
        self.lineEdit_3.setText(str(a + b))

6. 预览结果

7. 全部代码

import sys
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtWidgets import QWidget, QApplication


class Ui_Form(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()
        self.setupUi(self)

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 200)
        self.lineEdit = QtWidgets.QLineEdit(parent=Form)
        self.lineEdit.setGeometry(QtCore.QRect(20, 60, 61, 51))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(parent=Form)
        self.lineEdit_2.setGeometry(QtCore.QRect(160, 60, 61, 51))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.label = QtWidgets.QLabel(parent=Form)
        self.label.setGeometry(QtCore.QRect(100, 60, 41, 41))
        font = QtGui.QFont()
        font.setPointSize(36)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.lineEdit_3 = QtWidgets.QLineEdit(parent=Form)
        self.lineEdit_3.setGeometry(QtCore.QRect(320, 60, 61, 51))
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.pushButton = QtWidgets.QPushButton(parent=Form)
        self.pushButton.setGeometry(QtCore.QRect(230, 70, 75, 24))
        self.pushButton.setObjectName("pushButton")

        # 将PushButton按下的信号连接至响应函数
        self.pushButton.clicked.connect(self.Calculate)

        self.label_2 = QtWidgets.QLabel(parent=Form)
        self.label_2.setGeometry(QtCore.QRect(130, 140, 151, 31))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.label.setText(_translate("Form", "+"))
        self.pushButton.setText(_translate("Form", "等于"))
        self.label_2.setText(_translate("Form", "加法计算器窗口"))

    def Calculate(self):
        a = int(self.lineEdit.text())
        b = int(self.lineEdit_2.text())
        c = a + b  # 简单整形加法运算
        self.lineEdit_3.setText(str(a + b))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = Ui_Form()

    ui.show()
    sys.exit(app.exec())

多窗口调用

在自主设计所需要的应用程序时,经常遇到这样的情形:用户端需要通过点击某个按钮进入到下一个页面、打开新的窗口。比如,设计简单图书管理系统,需要有登录页面,主页面,添加书籍的页面等等。

如何在A.py中连接某个信号至另一个B.py函数的ui类以达到多窗口的调用呢?

简单实例

综上,制作一个欢迎页面,点击进入按钮后进入简易加法计算器页面,点击退出按钮即退出窗口。

按照上述方法得到:

import sys
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtWidgets import QWidget, QApplication


# 更改此ui类名,避免重复
class Welcome_Form(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()
        self.setupUi(self)

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 200)
        self.Label = QtWidgets.QLabel(parent=Form)
        self.Label.setGeometry(QtCore.QRect(90, 30, 201, 71))
        font = QtGui.QFont()
        font.setPointSize(36)
        self.Label.setFont(font)
        self.Label.setObjectName("Label")
        self.PushButton_Queren = QtWidgets.QPushButton(parent=Form)
        self.PushButton_Queren.setGeometry(QtCore.QRect(240, 120, 111, 61))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.PushButton_Queren.setFont(font)
        self.PushButton_Queren.setObjectName("PushButton_Queren")
        self.PushButton_Quxiao = QtWidgets.QPushButton(parent=Form)
        self.PushButton_Quxiao.setGeometry(QtCore.QRect(40, 120, 111, 61))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.PushButton_Quxiao.setFont(font)
        self.PushButton_Quxiao.setObjectName("PushButton_Quxiao")

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.Label.setText(_translate("Form", "欢迎页面"))
        self.PushButton_Queren.setText(_translate("Form", "确定"))
        self.PushButton_Quxiao.setText(_translate("Form", "取消"))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = Ui_Form()

    ui.show()
    sys.exit(app.exec())

多窗口调用代码

import sys
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtWidgets import QWidget, QApplication
from PyQt6_Learn.CSDN_Demo_Exe import Ui_Form


class Welcome_Form(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()
        self.setupUi(self)

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 200)
        self.Label = QtWidgets.QLabel(parent=Form)
        self.Label.setGeometry(QtCore.QRect(90, 30, 201, 71))
        font = QtGui.QFont()
        font.setPointSize(36)
        self.Label.setFont(font)
        self.Label.setObjectName("Label")
        self.PushButton_Queren = QtWidgets.QPushButton(parent=Form)
        self.PushButton_Queren.setGeometry(QtCore.QRect(240, 120, 111, 61))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.PushButton_Queren.setFont(font)
        self.PushButton_Queren.setObjectName("PushButton_Queren")
        # 确认按钮的点击信号
        self.PushButton_Queren.clicked.connect(self.pbt_Queren)

        self.PushButton_Quxiao = QtWidgets.QPushButton(parent=Form)
        self.PushButton_Quxiao.setGeometry(QtCore.QRect(40, 120, 111, 61))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.PushButton_Quxiao.setFont(font)
        self.PushButton_Quxiao.setObjectName("PushButton_Quxiao")
        # 取消按钮的点击信号
        self.PushButton_Quxiao.clicked.connect(self.pbt_Quxiao)

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.Label.setText(_translate("Form", "欢迎页面"))
        self.PushButton_Queren.setText(_translate("Form", "确定"))
        self.PushButton_Quxiao.setText(_translate("Form", "取消"))

    def pbt_Queren(self): 
        welcome.close()
        ui.show()

    def pbt_Quxiao(self):
        welcome.close()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    welcome = Welcome_Form()
    ui = Ui_Form()

    welcome.show()
    sys.exit(app.exec())

结语与预告

如果本文对你有帮助,还请点赞评论哦!

系列后期内容:

HTML网页调用

Pyserial串口通信

OpenCV与PyQt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值