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 list 合并连接字符串的方法
Mar 09 Python
Python代码的打包与发布详解
Jul 30 Python
解决Python中由于logging模块误用导致的内存泄露
Apr 23 Python
Windows平台Python连接sqlite3数据库的方法分析
Jul 12 Python
Python实现统计给定字符串中重复模式最高子串功能示例
May 16 Python
Django 连接sql server数据库的方法
Jun 30 Python
Django model序列化为json的方法示例
Oct 16 Python
详解Python装饰器
Mar 25 Python
Python编程实现tail-n查看日志文件的方法
Jul 08 Python
Python文件读写w+和r+区别解析
Mar 26 Python
python实例化对象的具体方法
Jun 17 Python
利用python为PostgreSQL的表自动添加分区
Jan 18 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广告加载类用法实例
2014/09/23 PHP
PHP四种排序算法实现及效率分析【冒泡排序,插入排序,选择排序和快速排序】
2018/04/27 PHP
PHP通过bypass disable functions执行系统命令的方法汇总
2018/05/02 PHP
PHP观察者模式示例【Laravel框架中有用到】
2018/06/15 PHP
作为PHP程序员你要知道的另外一种日志
2018/07/30 PHP
javascript window对象属性整理
2009/10/24 Javascript
IE下js调试工具Companion.JS
2010/10/15 Javascript
利用Angularjs和Bootstrap前端开发案例实战
2016/08/27 Javascript
使用JS实现图片展示瀑布流效果的实例代码
2016/09/12 Javascript
JQuery学习总结【二】
2016/12/01 Javascript
搭建简单的nodejs http服务器详解
2017/03/09 NodeJs
使用D3.js构建实时图形的示例代码
2018/08/28 Javascript
JavaScript模板引擎原理与用法详解
2018/12/24 Javascript
layui实现数据表格隐藏列的示例
2019/10/25 Javascript
创建与框架无关的JavaScript插件
2020/12/01 Javascript
pygame实现简易飞机大战
2018/09/11 Python
Python解析Excle文件中的数据方法
2018/10/23 Python
TensorFlow车牌识别完整版代码(含车牌数据集)
2019/08/05 Python
解决Jupyter NoteBook输出的图表太小看不清问题
2020/04/16 Python
Python+logging输出到屏幕将log日志写入文件
2020/11/11 Python
Python调用高德API实现批量地址转经纬度并写入表格的功能
2021/01/12 Python
python利用appium实现手机APP自动化的示例
2021/01/26 Python
利用CSS3实现动态的二级三级菜单效果实例源码
2017/01/04 HTML / CSS
女装和独特珠宝:Sundance Catalog
2018/09/19 全球购物
Whistles官网:英国女装品牌
2020/08/14 全球购物
职业生涯规划怎么写
2013/12/29 职场文书
工程质量月活动方案
2014/02/19 职场文书
2014村务公开实施方案
2014/02/25 职场文书
公司财务流程之主管工作流程
2014/03/03 职场文书
初中优秀班集体申报材料
2014/05/01 职场文书
政府四风问题整改措施
2014/10/04 职场文书
公安机关党的群众路线教育实践活动剖析材料
2014/10/10 职场文书
调解书格式范本
2015/05/20 职场文书
尼克胡哲观后感
2015/06/08 职场文书
python实现双链表
2022/05/25 Python
sql注入报错之注入原理实例解析
2022/06/10 MySQL