PyQt5多窗口数据传递:属性调用与信号槽机制详解
本文详细介绍PyQt5中多窗口数据传递的两种核心方式:通过对话框属性直接获取返回值,以及利用信号与槽机制进行解耦通信。文章包含单一窗口与多窗口实例,演示如何实例化对话框、调用静态函数,以及发射内置和自定义信号,帮助开发者掌握主窗口与子窗口间参数交互的最佳实践。
在PyQt5开发中,常需处理多参数输入或选择场景。若将所有参数集中于主窗口,会导致界面臃肿。因此,常规做法是添加一个按钮以调用独立对话框,在对话框中完成参数选择后,关闭对话框并将结果返回给主窗口。
PyQt5提供了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_())
运行效果如图所示。

多窗口数据传递:调用属性
新建名为“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_())
运行程序,界面显示如图。

代码分析
主窗口调用对话框主要有两种实现路径,本例中两者效果一致:均需点击按钮弹出对话框,在对话框的时间日期控件中选择日期,随后将选中的日期返回至主窗口的lineEdit文本控件中。
第一种方法:在主窗口程序中直接实例化该对话框,并调用其函数以获取返回值。根据用户点击确认还是取消按钮,执行后续操作。针对上述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_())
运行程序,效果如下。

代码分析
以下代码表示,当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信号与槽的知识请查看下面的相关链接
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









