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

PyQt5子窗口完成时间段选择后关闭致主窗口退出问题求助

PyQt5 GUI应用异常问题排查与修复

问题描述

基于PyQt5开发的GUI应用中,主窗口包含一个按钮,点击后弹出子窗口,依次完成登录信息输入、TAN验证、时间段选择三步操作。前两步关闭子窗口时,仅子窗口关闭,主窗口正常运行;但完成时间段选择后关闭子窗口,整个应用会直接退出,不符合预期。子窗口为同一实例,仅通过切换组件实现不同步骤的界面展示。

原因分析

核心问题在于MainWindow类中自定义的close()方法重写了QMainWindow父类的close()方法:

  • QMainWindow本身自带close()方法,作用是关闭主窗口;
  • 自定义的close()方法本意是关闭子窗口,但方法名与父类冲突,导致执行self.w.ok_btn_2.clicked.connect(self.close)时,实际触发的是主窗口的关闭操作,而非子窗口,最终导致整个应用退出。

修复方案

将自定义的关闭子窗口方法改名,避免与父类方法名冲突,同时确保信号连接指向正确的方法:

修改主窗口代码关键部分

  1. 将close()方法重命名为close_child_window()
  2. 在get_period()方法中,将信号连接到新的方法名

修改后的完整主窗口代码

import sys
from PyQt5.QtWidgets import (
    QVBoxLayout, QPushButton, QLabel, QMainWindow, QApplication, QWidget)

from Banking_App_Login_form import LoginForm

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.w = None  # No external window yet.
        self.button = QPushButton("Push for Window")
        self.button.clicked.connect(self.show_new_window)
        self.setCentralWidget(self.button)

    def show_new_window(self):
        if self.w is None:
            self.w = LoginForm()
            self.w.login_btn.clicked.connect(self.get_tan)            
            self.w.closed.connect(self.quit)
            self.w.show()

        else:
            self.w.close()  # Close window.
            self.w = None  # Discard reference.
            self.show_new_window()
    
    def get_tan(self):
        self.w.change_form_tan()
        # 可添加disconnect避免多次点击导致信号重复绑定
        self.w.ok_btn.clicked.connect(self.get_period)

    def get_period(self):
        self.w.change_form_period()
        # 连接到改名后的子窗口关闭方法
        self.w.ok_btn_2.clicked.connect(self.close_child_window)

    def quit(self):
        """
        Function for tasks to be performed after the child window is closed.
        """
        print("Token revoked")
        self.w = None
        print(f"self.w is now {self.w}") 
    
    def close_child_window(self):
        """
        Function to close the child window.
        """
        self.w.close()

def main():
    app = QApplication(sys.argv)
    gui = MainWindow()
    gui.show()

    sys.exit(app.exec())


if __name__ == "__main__":
    main()

额外优化建议

  • 信号重复连接问题:每次点击login_btn都会绑定一次get_period,多次点击会导致信号重复触发。可以在连接前先断开旧连接:
    self.w.ok_btn.disconnect()
    self.w.ok_btn.clicked.connect(self.get_period)
    
  • 界面切换优化:当前通过删除重建组件实现界面切换,可改用QStackedWidget管理不同步骤的界面,代码更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 23:37:00