You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于.ui文件实现Python Qt双窗口切换及数据交互

实现Qt UI文件动态加载与窗口间数据传递(无需转Py文件)

核心思路

直接用QUiLoader动态加载.ui文件,避免转换py文件的繁琐;通过模态窗口实现关闭后主窗口自动恢复焦点;子窗口通过控件对象名或自定义接口传递数据给主窗口。

实现步骤与代码示例

1. 主窗口核心代码

主窗口加载自身UI文件,绑定菜单点击事件,弹出子窗口并获取返回数据:

from PyQt5.QtWidgets import QApplication, QDialog, QAction, QLineEdit, QLabel, QPushButton
from PyQt5.QtUiTools import QUiLoader
import sys

class MainWindow:
    def __init__(self):
        # 动态加载主窗口UI文件
        loader = QUiLoader()
        self.window = loader.load("main_window.ui", None)
        
        # 绑定菜单点击事件(替换为你实际的菜单action的objectName)
        open_action = self.window.findChild(QAction, "action_open_subwindow")
        open_action.triggered.connect(self.open_sub_window)
        
        self.window.show()
    
    def open_sub_window(self):
        # 加载子窗口UI文件
        sub_loader = QUiLoader()
        sub_ui = sub_loader.load("sub_window.ui", None)
        
        # 将子UI包装为模态对话框,关闭后主窗口自动获焦点
        dialog = QDialog()
        dialog.setLayout(sub_ui.layout())
        dialog.setWindowTitle(sub_ui.windowTitle())
        
        # 绑定子窗口按钮事件(替换为你实际的按钮objectName)
        confirm_btn = sub_ui.findChild(QPushButton, "btn_confirm")
        confirm_btn.clicked.connect(dialog.accept)
        cancel_btn = sub_ui.findChild(QPushButton, "btn_cancel")
        cancel_btn.clicked.connect(dialog.reject)
        
        # 模态显示,等待窗口关闭
        if dialog.exec_() == QDialog.Accepted:
            # 从子窗口读取数据(替换为你实际的输入控件objectName)
            input_text = sub_ui.findChild(QLineEdit, "input_content").text()
            # 在主窗口显示数据(替换为你实际的显示控件objectName)
            show_label = self.window.findChild(QLabel, "data_display_label")
            show_label.setText(f"获取到的内容:{input_text}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_win = MainWindow()
    sys.exit(app.exec_())

2. 子窗口优化(可选)

如果子窗口逻辑复杂,可单独封装类,更便于维护:

class SubWindowHandler:
    def __init__(self):
        loader = QUiLoader()
        self.ui = loader.load("sub_window.ui", None)
    
    def get_input_data(self):
        # 封装数据读取逻辑
        return self.ui.findChild(QLineEdit, "input_content").text()

# 主窗口中调用方式修改为:
def open_sub_window(self):
    sub_handler = SubWindowHandler()
    dialog = QDialog()
    dialog.setLayout(sub_handler.ui.layout())
    
    # 绑定按钮事件...
    
    if dialog.exec_() == QDialog.Accepted:
        data = sub_handler.get_input_data()
        # 处理数据

关键说明

  • 动态加载UI:使用QUiLoader直接读取.ui文件,后续在Qt Designer修改UI后,无需重新转换代码,直接运行即可生效。
  • 模态窗口:dialog.exec_()以模态方式显示子窗口,关闭后主窗口会自动获得焦点,无需额外处理焦点逻辑。
  • 控件定位:通过findChild方法,根据Qt Designer中设置的objectName定位控件,确保操作的是目标元素。

注意事项

  • 所有需要代码操作的控件,必须在Qt Designer中设置唯一的objectName,否则findChild无法定位到目标控件。
  • 若子窗口有自定义信号需求,可在封装类中定义信号,主窗口连接信号获取数据,替代直接读取控件的方式。

内容的提问来源于stack exchange,提问作者Xavier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 23:37:23