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

PyQt5切换窗口后按钮失效求助:单独运行窗口功能正常

问题描述

我使用PyQt5 Designer创建了两个窗口,点击第一个主窗口的按钮可切换至第二个窗口,该功能运行正常。但第二个窗口中用于显示隐藏标签的按钮点击后无响应,单独将第二个窗口作为主程序运行时,按钮功能完全正常。

第一个窗口代码

from PyQt5 import QtCore, QtGui, QtWidgets
from SecondWindow import *


class Ui_FirstWindow(object):
    def setupUi(self, FirstWindow):
        FirstWindow.setObjectName("FirstWindow")
        FirstWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(FirstWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton_ChangeWindow = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_ChangeWindow.setGeometry(QtCore.QRect(280, 330, 281, 91))
        self.pushButton_ChangeWindow.setObjectName("pushButton_ChangeWindow")
        self.pushButton_ChangeWindow.clicked.connect(self.change_window)   # Link button with funcion
        FirstWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(FirstWindow)
        QtCore.QMetaObject.connectSlotsByName(FirstWindow)

    def retranslateUi(self, FirstWindow):
        _translate = QtCore.QCoreApplication.translate
        FirstWindow.setWindowTitle(_translate("FirstWindow", "MainWindow"))
        self.pushButton_ChangeWindow.setText(_translate("FirstWindow", "Change Window"))

    def change_window(self):
        ui = Ui_SecondWindow()
        ui.setupUi(FirstWindow)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    FirstWindow = QtWidgets.QMainWindow()
    ui = Ui_FirstWindow()
    ui.setupUi(FirstWindow)
    FirstWindow.show()
    sys.exit(app.exec_())

第二个窗口代码

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_SecondWindow(object):
    def setupUi(self, SecondWindow):
        SecondWindow.setObjectName("SecondWindow")
        SecondWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(SecondWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton_ShowLabel = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_ShowLabel.setGeometry(QtCore.QRect(270, 260, 241, 81))
        self.pushButton_ShowLabel.setObjectName("pushButton_ShowLabel")
        self.pushButton_ShowLabel.clicked.connect(self.show_hidden_label)
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(320, 130, 121, 51))
        self.label.setObjectName("label")

        # Hide label
        self.label.hide()
        SecondWindow.setCentralWidget(self.centralwidget)
    

        self.retranslateUi(SecondWindow)
        QtCore.QMetaObject.connectSlotsByName(SecondWindow)

    def retranslateUi(self, SecondWindow):
        _translate = QtCore.QCoreApplication.translate
        SecondWindow.setWindowTitle(_translate("SecondWindow", "MainWindow"))
        self.pushButton_ShowLabel.setText(_translate("SecondWindow", "Show Label"))
        self.label.setText(_translate("SecondWindow", "Hello"))

    def show_hidden_label(self):
        self.label.show()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    SecondWindow = QtWidgets.QMainWindow()
    ui = Ui_SecondWindow()
    ui.setupUi(SecondWindow)
    SecondWindow.show()
    sys.exit(app.exec_())

我接触编程仅1个月,若代码存在混乱之处还请谅解,恳请各位提供帮助与建议。


解决方案

问题原因

你在change_window方法里,直接把第二个窗口的UI加载到第一个FirstWindow实例上,且创建的Ui_SecondWindow对象是局部变量,方法执行完毕后会被Python垃圾回收机制销毁,导致按钮的信号与槽连接失效,所以点击第二个窗口的按钮无响应。

修改方法

修改第一个窗口的change_window方法,创建新的QMainWindow实例承载第二个窗口的UI,并保留窗口实例的引用(作为类属性)避免被回收:

from PyQt5 import QtCore, QtGui, QtWidgets
from SecondWindow import *


class Ui_FirstWindow(object):
    def setupUi(self, FirstWindow):
        FirstWindow.setObjectName("FirstWindow")
        FirstWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(FirstWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton_ChangeWindow = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_ChangeWindow.setGeometry(QtCore.QRect(280, 330, 281, 91))
        self.pushButton_ChangeWindow.setObjectName("pushButton_ChangeWindow")
        self.pushButton_ChangeWindow.clicked.connect(self.change_window)
        FirstWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(FirstWindow)
        QtCore.QMetaObject.connectSlotsByName(FirstWindow)
        # 保存主窗口实例,方便后续操作
        self.first_window = FirstWindow

    def retranslateUi(self, FirstWindow):
        _translate = QtCore.QCoreApplication.translate
        FirstWindow.setWindowTitle(_translate("FirstWindow", "MainWindow"))
        self.pushButton_ChangeWindow.setText(_translate("FirstWindow", "Change Window"))

    def change_window(self):
        # 创建新的窗口实例
        self.second_window = QtWidgets.QMainWindow()
        ui = Ui_SecondWindow()
        ui.setupUi(self.second_window)
        # 显示新窗口
        self.second_window.show()
        # 可选:隐藏原主窗口
        self.first_window.hide()

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    FirstWindow = QtWidgets.QMainWindow()
    ui = Ui_FirstWindow()
    ui.setupUi(FirstWindow)
    FirstWindow.show()
    sys.exit(app.exec_())

额外建议

对于PyQt5项目,更规范的做法是让窗口类直接继承QMainWindow(或QWidget),在类中初始化UI,更好地管理窗口生命周期和信号槽:

from PyQt5.QtWidgets import QApplication, QMainWindow
from SecondWindow import Ui_SecondWindow


class FirstWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 导入Designer生成的UI类并初始化
        from FirstWindowUI import Ui_FirstWindow
        self.ui = Ui_FirstWindow()
        self.ui.setupUi(self)
        # 连接按钮信号
        self.ui.pushButton_ChangeWindow.clicked.connect(self.change_window)

    def change_window(self):
        self.second_window = SecondWindow()
        self.second_window.show()
        self.hide()


class SecondWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_SecondWindow()
        self.ui.setupUi(self)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    window = FirstWindow()
    window.show()
    sys.exit(app.exec_())

这种方式将UI与窗口逻辑分离,代码结构更清晰,也能避免局部变量被回收的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:50:30