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中的闭包
Nov 30 Python
利用PyInstaller将python程序.py转为.exe的方法详解
May 03 Python
python中requests小技巧
May 10 Python
Python中new方法的详解
Jan 15 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
Mar 18 Python
使用Python操作ArangoDB的方法步骤
Feb 02 Python
flask项目集成swagger的方法
Dec 09 Python
python接口自动化框架实战
Dec 23 Python
PyQt5 QThread倒计时功能的实现代码
Apr 02 Python
Python通过m3u8文件下载合并ts视频的操作
Apr 16 Python
Python list列表删除元素的4种方法
Nov 01 Python
Python闭包的定义和使用方法
Apr 11 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 导出数据到淘宝助手CSV的方法分享
2010/02/27 PHP
PHP逐行输出(ob_flush与flush的组合)
2012/02/04 PHP
php 操作符与控制结构
2012/03/07 PHP
php获取apk包信息的方法
2014/08/15 PHP
php实现用户注册密码的crypt加密
2017/06/08 PHP
如何用javascript去掉字符串里的所有空格
2007/02/08 Javascript
Mootools 1.2教程 滚动条(Slider)
2009/09/15 Javascript
去掉gridPanel表头全选框的小例子
2013/07/18 Javascript
JavaScript返回网页中超链接数量的方法
2015/04/03 Javascript
javascript实现点击按钮弹出一个可关闭层窗口同时网页背景变灰的方法
2015/05/13 Javascript
基于javascript实现图片懒加载
2016/01/05 Javascript
浅谈js和css内联外联注意事项
2016/06/30 Javascript
详解ES6之用let声明变量以及let loop机制
2017/07/15 Javascript
vue-router 起步步骤详解
2019/03/26 Javascript
JS实现随机抽选获奖者
2019/11/07 Javascript
原生JS封装拖动验证滑块的实现代码示例
2020/06/01 Javascript
element el-table表格的二次封装实现(附表格高度自适应)
2021/01/19 Javascript
[50:44]DOTA2-DPC中国联赛 正赛 SAG vs Dragon BO3 第二场 2月22日
2021/03/11 DOTA
python xml解析实例详解
2016/11/14 Python
Python工厂函数用法实例分析
2018/05/14 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
Python3实现监控新型冠状病毒肺炎疫情的示例代码
2020/02/13 Python
关于Python字符串显示u...的解决方式
2020/03/06 Python
tensorflow模型转ncnn的操作方式
2020/05/25 Python
Python Selenium操作Cookie的实例方法
2021/02/28 Python
巴西体育用品商店:Lojão dos Esportes
2018/07/21 全球购物
如何删除一个表里面的重复行
2013/07/13 面试题
艺术应用与设计个人的自我评价
2013/11/23 职场文书
《胖乎乎的小手》教学反思
2014/02/26 职场文书
颂军魂爱军营演讲稿
2014/09/13 职场文书
群众路线对照检查材料思想汇报怎么写
2014/09/18 职场文书
夫妻分居协议书范文
2014/11/26 职场文书
2015年出纳个人工作总结
2015/04/02 职场文书
2016年“5.12”国际护士节活动总结
2016/04/06 职场文书
Flutter集成高德地图并添加自定义Maker的实践
2022/04/07 Java/Android
css3 选择器
2022/05/11 HTML / CSS