python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例


Posted in Python onMarch 08, 2020

在pyqt5编程过程中,经常会遇到输入或选择多个参数的问题,把多个参数写到一个窗口中,主窗口会显得很臃肿,所以,一般是添加一个按钮,调用对话框,在对话框中进行参数的选择,关闭对话框将参数返回给主窗口

pyqt提供了一些标准的对话框类,用于输入数据,修改数据,更改应用的设置等,常见的有QFileDialog,QInputDialog,QColorDialog, QFontDialog等,在不同的窗口之间传参数有两种常用的方式,一种在自定义对话框之间通过属性传参,另一种在窗口之间使用信号与槽机制传参,这里主要介绍第一种

单一窗口的数据传递实例

对于具有单一窗口的程序来说,一个控件的变化会影响另一个控件的变化,这中变化利用信号与槽的关系非常容易解决

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class WinForm(QWidget):
  def __init__(self):
    super(WinForm, self).__init__()
    self.initUI()
  def initUI( self ):
    #先创建水平滑块和Lcd控件
    lcd=QLCDNumber(self)
    slider=QSlider(Qt.Horizontal,self)
    #垂直布局,添加控件
    vbox=QVBoxLayout()
    vbox.addWidget(lcd)
    vbox.addWidget(slider)
    #设置窗口布局
    self.setLayout(vbox)
    #设置滑块数值信号改变连接Lcd的更新
    slider.valueChanged.connect(lcd.display)
    #设置初始位置以及初始大小,设置标题
    self.setGeometry(300,300,350,150)
    self.setWindowTitle('信号与槽:连接滑块LCd')
if __name__ == '__main__':
  app=QApplication(sys.argv)
  form=WinForm()
  form.show()
  sys.exit(app.exec_())

运行效果如图

python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例

多窗口数据传递:调用属性

新建对话框子窗口属性,我这里的名字为: jia_13多窗口数据传递之调用属性

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class DateDialog(QDialog):
  def __init__(self,parent=None):
    super(DateDialog, self).__init__(parent)
    self.setWindowTitle('DateDialog')
    #在布局中添加控件
    layout=QVBoxLayout(self)
    self.datetime=QDateTimeEdit(self)
    self.datetime.setCalendarPopup(True)
    self.datetime.setDateTime(QDateTime.currentDateTime())
    layout.addWidget(self.datetime)
    buttons=QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel,Qt.Horizontal,self)
    buttons.accepted.connect(self.accept)
    buttons.rejected.connect(self.reject)
    layout.addWidget(buttons)
  def dateTime( self ):
    return self.datetime.dateTime()
  @staticmethod
  def getDateTime(parent=None):
    dialog=DateDialog(parent)
    result=dialog.exec_()
    date=dialog.dateTime()
    return (date.date(),date.time(),result==QDialog.Accepted)

再新建一个主窗口文件,用来调用上一个子窗口

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from jia_13多窗口数据传递之调用属性 import DateDialog
class WinForm(QWidget):
  def __init__(self,parent=None):
    super(WinForm, self).__init__(parent)
    self.resize(400,90)
    self.setWindowTitle('对话框关闭时返回值给主窗口的例子')
    self.lineEdit=QLineEdit(self)
    self.button1=QPushButton('弹出对话框1')
    self.button1.clicked.connect(self.onButton1Clicked)
    self.button2=QPushButton('弹出对话框2')
    self.button2.clicked.connect(self.onButton2Clicked)
    gridLayout=QGridLayout(self)
    gridLayout.addWidget(self.lineEdit)
    gridLayout.addWidget(self.button1)
    gridLayout.addWidget(self.button2)
  def onButton1Clicked( self ):
    dialog=DateDialog(self)
    result=dialog.exec_()
    date=dialog.dateTime()
    self.lineEdit.setText(date.date().toString())
    print('\n日期对话框的返回值')
    print('date=%s'%str(date.date))
    print('time=%s'%str(date.time()))
    print('result=%s'%result)
  def onButton2Clicked( self ):
    date,time,result=DateDialog.getDateTime()
    self.lineEdit.setText(date.toString())
    print('\n 日期对话框的返回值')
    print('date=%s' %str(date))
    print('time=%s' %str(time))
    print('result=%s' %result)
if __name__ == '__main__':
  app=QApplication(sys.argv)
  form=WinForm()
  form.show()
  sys.exit(app.exec_())

运行程序,显示如图

python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例

代码分析

在主窗口调用对话框有两种方法,本例中,这两种方法操作效果是一样的,都需要点击弹出对话框按钮,在对话框的时间日期控件中选择日期,则会把选中的日期返回到主窗口的lineTeXt文本控件中

第一中方法:直接在主窗口程序中实例化该对话框,然后调用该对话框的函数,来获取返回值,根据对话框的返回值单击确认按钮还是取消按钮来进行下一步的操作,同理,对于上面的DateDialog,主窗口程序代码如下

 def onButton1Clicked( self ):

        dialog=DateDialog(self)

        result=dialog.exec_()

        date=dialog.dateTime()

        self.lineEdit.setText(date.date().toString())

第二种方法:在主窗口程序中调用子窗口的静态函数,实际上这种方法与第一种方法是一样的,只不过他利用静态函数的特点,在子窗口的静态函数中的创建实例化对象

 def onButton2Clicked( self ):

        date,time,result=DateDialog.getDateTime()

        self.lineEdit.setText(date.toString())

多窗口数据传递信号与槽实例

对于多窗口的数据传递,一般是通过子窗口发射信号的,主窗口通过槽函数捕获这个信号,然后获取信号里面的数据,子窗口发射的信号有两种:一种是发射内置pyqt信号,一种是发射自定义的信号

发射自定义的信号,好处是它的参数可以自定义,可以为int list dict等各种类型与多个参数

新建一个子对话框文件,这里的名称为:jia_14多窗口信号传递之信号与槽

# -*- coding: utf-8 -*-
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class DateDialog(QDialog):
  Signal_OneParameter = pyqtSignal(str)
  def __init__(self, parent=None):
    super(DateDialog, self).__init__(parent)
    self.setWindowTitle('子窗口:用来发射信号')
    # 在布局中添加部件
    layout = QVBoxLayout(self)
    self.label = QLabel(self)
    self.label.setText('前者发射内置信号\n后者发射自定义信号')
    self.datetime_inner = QDateTimeEdit(self)
    self.datetime_inner.setCalendarPopup(True)
    self.datetime_inner.setDateTime(QDateTime.currentDateTime())
    self.datetime_emit = QDateTimeEdit(self)
    self.datetime_emit.setCalendarPopup(True)
    self.datetime_emit.setDateTime(QDateTime.currentDateTime())
    layout.addWidget(self.label)
    layout.addWidget(self.datetime_inner)
    layout.addWidget(self.datetime_emit)
    # 使用两个button(ok和cancel)分别连接accept()和reject()槽函数
    buttons = QDialogButtonBox(
      QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
      Qt.Horizontal, self)
    buttons.accepted.connect(self.accept)
    buttons.rejected.connect(self.reject)
    layout.addWidget(buttons)
    self.datetime_emit.dateTimeChanged.connect(self.emit_signal)
  def emit_signal(self):
    date_str = self.datetime_emit.dateTime().toString()
    self.Signal_OneParameter.emit(date_str)

创建主窗口,调用对话框文件

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from jia_14多窗口信号传递之信号与槽 import DateDialog
class WinForm(QWidget):
  def __init__(self, parent=None):
    super(WinForm, self).__init__(parent)
    self.resize(400, 90)
    self.setWindowTitle('信号与槽传递参数的示例')
    self.open_btn = QPushButton('获取时间')
    self.lineEdit_inner = QLineEdit(self)
    self.lineEdit_emit = QLineEdit(self)
    self.open_btn.clicked.connect(self.openDialog)
    self.lineEdit_inner.setText('接收子窗口内置信号的时间')
    self.lineEdit_emit.setText('接收子窗口自定义信号的时间')
    grid = QGridLayout()
    grid.addWidget(self.lineEdit_inner)
    grid.addWidget(self.lineEdit_emit)
    grid.addWidget(self.open_btn)
    self.setLayout(grid)
  def openDialog(self):
    dialog = DateDialog(self)
    '''连接子窗口的内置信号与主窗口的槽函数'''
    dialog.datetime_inner.dateTimeChanged.connect(self.deal_inner_slot)
    '''连接子窗口的自定义信号与主窗口的槽函数'''
    dialog.Signal_OneParameter.connect(self.deal_emit_slot)
    dialog.show()
  def deal_inner_slot(self, date):
    self.lineEdit_inner.setText(date.toString())
  def deal_emit_slot(self, dateStr):
    self.lineEdit_emit.setText(dateStr)
if __name__ == "__main__":
  app = QApplication(sys.argv)
  form = WinForm()
  form.show()
  sys.exit(app.exec_())

运行程序,效果如下

python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例

代码分析

下面代码表示,当空间datetime_emit的时间发生变化时,就会触发,子窗口的槽函数emit_signal,而在这个槽函数中又会发射自定义信号Signal_OneParameter,这个信号函数是为了传递date_str参数给主函数

    def emit_signal(self):

        date_str = self.datetime_emit.dateTime().toString()

        self.Signal_OneParameter.emit(date_str)

对于主窗口,关键是获取子窗口的信号,并把它绑定在自己的槽函数上,这样就实现了子窗口的控件与主窗口控件的绑定,核心代码如下

  def openDialog(self):

        dialog = DateDialog(self)

        '''连接子窗口的内置信号与主窗口的槽函数'''

        dialog.datetime_inner.dateTimeChanged.connect(self.deal_inner_slot)

        '''连接子窗口的自定义信号与主窗口的槽函数'''

        dialog.Signal_OneParameter.connect(self.deal_emit_slot)

        dialog.show()

本文主要讲解了PyQt5窗口数据传递与PyQt5信号与槽多窗口数据传递详细使用方法与实例,更多关于PyQt5信号与槽的知识请查看下面的相关链接

Python 相关文章推荐
使用Python导出Excel图表以及导出为图片的方法
Nov 07 Python
python虚拟环境virtualenv的使用教程
Oct 20 Python
Django的分页器实例(paginator)
Dec 01 Python
Python实现的rsa加密算法详解
Jan 24 Python
python生成n个元素的全组合方法
Nov 13 Python
python网络应用开发知识点浅析
May 28 Python
linux下python中文乱码解决方案详解
Aug 28 Python
解决安装pyqt5之后无法打开spyder的问题
Dec 13 Python
python实现实时视频流播放代码实例
Jan 11 Python
.dcm格式文件软件读取及python处理详解
Jan 16 Python
Win10用vscode打开anaconda环境中的python出错问题的解决
May 25 Python
python中pyqtgraph知识点总结
Jan 26 Python
python GUI库图形界面开发之PyQt5多线程中信号与槽的详细使用方法与实例
Mar 08 #Python
python GUI库图形界面开发之PyQt5结合Qt Designer创建信号与槽的详细方法与实例
Mar 08 #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
You might like
ECSHOP完美解决Deprecated: preg_replace()报错的问题
2016/05/17 PHP
浅析Laravel5中队列的配置及使用
2016/08/04 PHP
JSON.parse 解析字符串出错的解决方法
2010/07/08 Javascript
jquery简单瀑布流实现原理及ie8下测试代码
2013/01/23 Javascript
javascript实现tabs选项卡切换效果(扩展版)
2013/03/19 Javascript
js如何获取file控件的完整路径具体实现代码
2013/05/15 Javascript
javascript实现锁定网页、密码解锁效果(类似系统屏幕保护效果)
2014/08/15 Javascript
jQuery插件multiScroll实现全屏鼠标滚动切换页面特效
2015/04/12 Javascript
深入分析Javascript跨域问题
2015/04/17 Javascript
javascript无刷新评论实现方法
2015/05/13 Javascript
老司机带你解读jQuery插件开发流程
2016/05/16 Javascript
nodejs中art-template模板语法的引入及冲突解决方案
2017/11/07 NodeJs
vue使用pdfjs显示PDF可复制的实现方法
2018/12/14 Javascript
vue多个元素的样式选择器问题
2019/11/29 Javascript
手把手教您实现react异步加载高阶组件
2020/04/07 Javascript
[02:20]DOTA2亚洲邀请赛 IG战队出场宣传片
2015/02/07 DOTA
[40:48]DOTA2上海特级锦标赛D组败者赛 Liquid VS COL第二局
2016/02/28 DOTA
python学习之面向对象【入门初级篇】
2017/01/21 Python
如何实现删除numpy.array中的行或列
2018/05/08 Python
Python简单获取网卡名称及其IP地址的方法【基于psutil模块】
2018/05/24 Python
Python实现繁?转为简体的方法示例
2018/12/18 Python
详解python读取image
2019/04/03 Python
Django返回HTML文件的实现方法
2020/09/17 Python
Pycharm同步远程服务器调试的方法步骤
2020/11/04 Python
css3高级选择器使用方法
2013/12/02 HTML / CSS
美国流行背包品牌:JanSport(杰斯伯)
2018/03/02 全球购物
专升本个人自我评价
2013/12/22 职场文书
两年的个人工作自我评价
2014/01/10 职场文书
会计专业毕业自荐书范文
2014/02/08 职场文书
销售人员职业生涯规划范文
2014/03/01 职场文书
演讲稿格式
2014/04/30 职场文书
企业战略合作意向书
2015/05/08 职场文书
公司年会开场白
2015/06/01 职场文书
煤矿安全生产管理协议书
2016/03/22 职场文书
导游词之太行山青龙峡
2020/01/14 职场文书
python中使用redis用法详解
2022/12/24 Redis