PyQt5多窗口数据传递:属性调用与信号槽机制详解

花开有时
花开有时
发布时间:2026-10-14| 1人浏览过
原创

本文详细介绍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信号与槽的知识请查看下面的相关链接

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。