python GUI库图形界面开发之PyQt5结合Qt Designer创建信号与槽的详细方法与实例


Posted in Python onMarch 08, 2020

在下面这3篇文章中我们给出了手工输入代码的信号与槽的使用方法,因为采用这种方法介绍时,会简单一些,如果使用Qt Designer来介绍这些功能,那么任何一个简单的功能都会使用xxxx.ui xxxx.py call_xxxx.py三个文件 来实现,这样内容会显得很乱

在实战应用中,由于Qt Designer可以很好的实现界面显示与业务逻辑分离,所有能保住我们解决大量的代码,如果能够使用Qt Designer自动创建一些信号与槽机制,那就更好了。

本例要实现的功能是:通过一个模拟打印的界面来详细说明信号的使用,在打印时,可以设置打印的份数,纸张类型,触发打印按钮后,将执行结果显示在右侧,通过QCheckBox(全屏预览 复选框)来选择是否通过全屏模式进行预览,将执行结果显示在右侧

按F1键可以显示helpmessage帮助信息

第一步:Qt Designer

首先,使用Qt Designer新建一个模板名为widget的简单窗口,通过将widget box区域的控件拖曳到窗口中,实现如图的界面效果

python GUI库图形界面开发之PyQt5结合Qt Designer创建信号与槽的详细方法与实例

这里对窗口控件进行简要说明

控件类型 控件名称 作用
QSpinBox numberSpinBox 显示打印的分数
QComboBox styleCombo 显示打印的纸张类型,纸张类型包括A3,A4等
QPushButton printButton 连接emitPrintSiagnal函数的绑定,触发自定义信号printSignal的发射
QCheckBox prievewState 是否全屏预览
QPushButton priviewButton 连接emitPreviewSignal函数的绑定,触发自定义信号previewSignal的发射
QLabel resultLabel 显示执行结果

第二步:将界面文件ui转换为py文件

pyuic5 -o xxxxx.py xxxxx.ui

会在界面文件同级目录下生成一个py文件

查看所生成的.py文件,完整代码如下

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'MainWinSignalSlog02.ui'
#
# Created by: PyQt5 UI code generator 5.8.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
  def setupUi(self, Form):
    Form.setObjectName("Form")
    Form.resize(715, 225)
    self.controlsGroup = QtWidgets.QGroupBox(Form)
    self.controlsGroup.setGeometry(QtCore.QRect(10, 20, 451, 151))
    self.controlsGroup.setObjectName("controlsGroup")
    self.widget = QtWidgets.QWidget(self.controlsGroup)
    self.widget.setGeometry(QtCore.QRect(10, 40, 411, 30))
    self.widget.setObjectName("widget")
    self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
    self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
    self.horizontalLayout.setObjectName("horizontalLayout")
    self.label = QtWidgets.QLabel(self.widget)
    self.label.setObjectName("label")
    self.horizontalLayout.addWidget(self.label)
    self.numberSpinBox = QtWidgets.QSpinBox(self.widget)
    self.numberSpinBox.setObjectName("numberSpinBox")
    self.horizontalLayout.addWidget(self.numberSpinBox)
    self.styleCombo = QtWidgets.QComboBox(self.widget)
    self.styleCombo.setObjectName("styleCombo")
    self.styleCombo.addItem("")
    self.styleCombo.addItem("")
    self.styleCombo.addItem("")
    self.horizontalLayout.addWidget(self.styleCombo)
    self.label_2 = QtWidgets.QLabel(self.widget)
    self.label_2.setObjectName("label_2")
    self.horizontalLayout.addWidget(self.label_2)
    self.printButton = QtWidgets.QPushButton(self.widget)
    self.printButton.setObjectName("printButton")
    self.horizontalLayout.addWidget(self.printButton)
    self.widget1 = QtWidgets.QWidget(self.controlsGroup)
    self.widget1.setGeometry(QtCore.QRect(10, 100, 201, 30))
    self.widget1.setObjectName("widget1")
    self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget1)
    self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
    self.horizontalLayout_2.setObjectName("horizontalLayout_2")
    self.previewStatus = QtWidgets.QCheckBox(self.widget1)
    self.previewStatus.setObjectName("previewStatus")
    self.horizontalLayout_2.addWidget(self.previewStatus)
    self.previewButton = QtWidgets.QPushButton(self.widget1)
    self.previewButton.setObjectName("previewButton")
    self.horizontalLayout_2.addWidget(self.previewButton)
    self.resultGroup = QtWidgets.QGroupBox(Form)
    self.resultGroup.setGeometry(QtCore.QRect(470, 20, 231, 151))
    self.resultGroup.setObjectName("resultGroup")
    self.resultLabel = QtWidgets.QLabel(self.resultGroup)
    self.resultLabel.setGeometry(QtCore.QRect(20, 30, 191, 101))
    self.resultLabel.setObjectName("resultLabel")
    self.retranslateUi(Form)
    QtCore.QMetaObject.connectSlotsByName(Form)
  def retranslateUi(self, Form):
    _translate = QtCore.QCoreApplication.translate
    Form.setWindowTitle(_translate("Form", "打印控件"))
    self.controlsGroup.setTitle(_translate("Form", "打印控制"))
    self.label.setText(_translate("Form", "打印份数:"))
    self.styleCombo.setItemText(0, _translate("Form", "A3"))
    self.styleCombo.setItemText(1, _translate("Form", "A4"))
    self.styleCombo.setItemText(2, _translate("Form", "A5"))
    self.label_2.setText(_translate("Form", "纸张类型:"))
    self.printButton.setText(_translate("Form", "打印"))
    self.previewStatus.setText(_translate("Form", "全屏预览"))
    self.previewButton.setText(_translate("Form", "预览"))
    self.resultGroup.setTitle(_translate("Form", "操作结果"))
    self.resultLabel.setText(_translate("Form", "<html><head/><body><p><br/></p></body></html>"))

第三步:新建调用窗口

为了使窗口的显示与业务逻辑分离,在建一个调用窗口显示的文件,在调用类中添加多个自定义信号,并与槽函数进行绑定,其完整代码如下

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from jia_07 import Ui_Form
from PyQt5.QtCore import pyqtSignal, Qt
class MyMainWindow(QMainWindow, Ui_Form):
  helpSignal = pyqtSignal(str)
  printSignal = pyqtSignal(list)
  # 声明一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及带str参数的信号
  previewSignal = pyqtSignal([ int, str ], [ str ])
  def __init__( self, parent=None ):
    super(MyMainWindow, self).__init__(parent)
    self.setupUi(self)
    self.initUI()
  def initUI( self ):
    self.helpSignal.connect(self.showHelpMessage)
    self.printSignal.connect(self.printPaper)
    self.previewSignal[ str ].connect(self.previewPaper)
    self.previewSignal[ int, str ].connect(self.previewPaperWithArgs)
    self.printButton.clicked.connect(self.emitPrintSignal)
    self.previewButton.clicked.connect(self.emitPreviewSignal)
  # 发射预览信号
  def emitPreviewSignal( self ):
    if self.previewStatus.isChecked() == True:
      self.previewSignal[ int, str ].emit(1080, " Full Screen")
    elif self.previewStatus.isChecked() == False:
      self.previewSignal[ str ].emit("Preview")
  # 发射打印信号
  def emitPrintSignal( self ):
    pList = [ ]
    pList.append(self.numberSpinBox.value())
    pList.append(self.styleCombo.currentText())
    self.printSignal.emit(pList)
  def printPaper( self, list ):
    self.resultLabel.setText("打印: " + "份数:" + str(list[ 0 ]) + " 纸张:" + str(list[ 1 ]))
  def previewPaperWithArgs( self, style, text ):
    self.resultLabel.setText(str(style) + text)
  def previewPaper( self, text ):
    self.resultLabel.setText(text)
    # 重载点击键盘事件
  def keyPressEvent( self, event ):
    if event.key() == Qt.Key_F1:
      self.helpSignal.emit("help message")
  # 显示帮助消息
  def showHelpMessage( self, message ):
    self.resultLabel.setText(message)
    self.statusBar().showMessage(message)
if __name__ == "__main__":
  app = QApplication(sys.argv)
  win = MyMainWindow()
  win.show()
  sys.exit(app.exec_())

运行程序,显示效果如图

python GUI库图形界面开发之PyQt5结合Qt Designer创建信号与槽的详细方法与实例

代码分析

在上面的例子中,通过PyQtSignal()定义了三个信号,一个str参数类型的信号,一个list类型参数类型的信号,一个多重载版本的信号,包括一个int和str类型参数的信号,以及带str类型参数的信号

    helpSignal = pyqtSignal(str)

    printSignal = pyqtSignal(list)

    # 声明一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及带str参数的信号

    previewSignal = pyqtSignal([ int, str ], [ str ])

对于绑定信号与槽,这里着重说明多重版本的信号绑定,prieviewSignal有两个版本,即previewSignal(str)和prievewSignal(int ,str),由于两个版本,因此在绑定的时候,需要显示指定信号与槽的绑定

        self.helpSignal.connect(self.showHelpMessage)

        self.printSignal.connect(self.printPaper)

        self.previewSignal[ str ].connect(self.previewPaper)

        self.previewSignal[ int, str ].connect(self.previewPaperWithArgs)

在Qt的机制中,根据所传递信号的参数类型和个数,连接到不同的槽函数

    def emitPreviewSignal( self ):

        if self.previewStatus.isChecked() == True:

            self.previewSignal[ int, str ].emit(1080, " Full Screen")

        elif self.previewStatus.isChecked() == False:

            self.previewSignal[ str ].emit("Preview")

信号发射可以传递python数据类型的参数,本例中的printSignal信号可以传递list类型的参数plist

 def emitPrintSignal( self ):

        pList = [ ]

        pList.append(self.numberSpinBox.value())

        pList.append(self.styleCombo.currentText())

        self.printSignal.emit(pList)

通过复写KeyPressEvent()方法,对F1键进行功能扩展,这里通过复写keyPressEvent()方法模拟发射所需的信号,来完成对应的任务

  def keyPressEvent( self, event ):

        if event.key() == Qt.Key_F1:

          self.helpSignal.emit("help message")

本文主要讲解了PyQt5结合Qt Designer创建信号与槽的详细方法与实例,另外一篇关于PyQt5结合Qt Designer创建信号与槽的文章 python GUI库图形界面开发之PyQt5信号与槽基本操作 大家也可以结合阅读下,更多关于 PyQt5信号与槽的知识请查看下面的相关链接

Python 相关文章推荐
Python增强赋值和共享引用注意事项小结
May 28 Python
远程部署工具Fabric详解(支持Python3)
Jul 04 Python
python处理RSTP视频流过程解析
Jan 11 Python
np.dot()函数的用法详解
Jan 17 Python
python+Selenium自动化测试——输入,点击操作
Mar 06 Python
pyecharts调整图例与各板块的位置间距实例
May 16 Python
使用 django orm 写 exists 条件过滤实例
May 20 Python
解决PDF 转图片时丢文字的一种可能方式
Mar 04 Python
python中Tkinter 窗口之输入框和文本框的实现
Apr 12 Python
python 远程执行命令的详细代码
Feb 15 Python
Python matplotlib安装以及实现简单曲线的绘制
Apr 26 Python
Python使用Web框架Flask开发项目
Jun 01 Python
python输出第n个默尼森数的实现示例
Mar 08 #Python
Tensorflow之梯度裁剪的实现示例
Mar 08 #Python
Django自定义全局403、404、500错误页面的示例代码
Mar 08 #Python
Django 自定义404 500等错误页面的实现
Mar 08 #Python
Python loguru日志库之高效输出控制台日志和日志记录
Mar 07 #Python
Centos7下源码安装Python3 及shell 脚本自动安装Python3的教程
Mar 07 #Python
Django接收照片储存文件的实例代码
Mar 07 #Python
You might like
php字符串截取中文截取2,单字节截取模式
2007/12/10 PHP
PHP HTML代码串 截取实现代码
2009/06/29 PHP
php的list()的一步操作给一组变量进行赋值的使用
2011/05/18 PHP
session在PHP大型web应用中的使用
2011/06/25 PHP
PHP JS Ip地址及域名格式检测代码
2013/09/27 PHP
php注册和登录界面的实现案例(推荐)
2016/10/24 PHP
PHP中的密码加密的解决方案总结
2016/10/26 PHP
Laravel 微信小程序后端搭建步骤详解
2019/11/26 PHP
Javascript 更新 JavaScript 数组的 uniq 方法
2008/01/23 Javascript
Jquery ThickBox插件使用心得(不建议使用)
2010/09/08 Javascript
推荐40个非常优秀的jQuery插件和教程【系列三】
2011/11/09 Javascript
jQuery性能优化28条建议你值得借鉴
2013/02/16 Javascript
实现只能输入数字的input不用replace方法
2013/09/12 Javascript
js获取触发事件元素在整个网页中的绝对坐标(示例代码)
2013/12/13 Javascript
简单理解Vue条件渲染
2016/12/03 Javascript
JavaScript实现的原生态兼容IE6可调可控滚动文字功能详解
2017/09/19 Javascript
Layui数据表格之获取表格中所有的数据方法
2018/08/20 Javascript
最简单的vue消息提示全局组件的方法
2019/06/16 Javascript
Python冒泡排序注意要点实例详解
2016/09/09 Python
请不要重复犯我在学习Python和Linux系统上的错误
2016/12/12 Python
Python自定义线程池实现方法分析
2018/02/07 Python
Python向excel中写入数据的方法
2019/05/05 Python
基于Numpy.convolve使用Python实现滑动平均滤波的思路详解
2019/05/16 Python
python读取当前目录下的CSV文件数据
2020/03/11 Python
基于Python第三方插件实现西游记章节标注汉语拼音的方法
2020/05/22 Python
Python SMTP发送电子邮件的示例
2020/09/23 Python
利用CSS3实现动态的二级三级菜单效果实例源码
2017/01/04 HTML / CSS
Columbia美国官网:美国著名的户外服装品牌
2016/11/24 全球购物
法警的竞聘演讲稿
2014/01/02 职场文书
店面销售职位的职责
2014/03/09 职场文书
初中生期末评语大全
2014/04/24 职场文书
小学生安全演讲稿
2014/04/25 职场文书
环保建议书500字
2014/05/14 职场文书
创建文明城市标语
2014/06/16 职场文书
植树节新闻稿
2015/07/17 职场文书
如何解决php-fpm启动不了问题
2021/11/17 PHP