PyQt中第二个窗口打开后立即关闭的问题排查与修复求助
问题分析与修复方案
嘿,我一眼就揪出问题所在啦——你的第二个窗口打开就闪退,核心是局部变量生命周期太短,还有几个小细节需要调整,我一步步给你拆解:
问题1:局部变量导致窗口被立刻回收
在原来的start_clicked()函数里,你创建的window是个局部变量。当函数执行完最后一行代码后,Python的垃圾回收机制会自动销毁这个局部对象,窗口自然跟着关闭了。
问题2:主窗口引用不规范
你代码里的win.hide(),这里的win是main()函数里的局部变量,在全局的start_clicked()里直接访问其实是不规范的(没报错可能是你之前全局声明过,但这绝不是好的编码习惯)。
修复方案
最好的做法是把窗口切换逻辑整合到MainWindow类内部,把start_clicked改成类的方法,同时把新窗口保存为实例属性,让它的生命周期和主窗口绑定。
修改后的完整代码如下:
import sys from PyQt5.QtWidgets import (QMainWindow, QLabel, QPushButton, QApplication, QMessageBox, QIcon) from PyQt5.QtCore import pyqtSignal, QFont class MainWindow(QMainWindow): switch_window = pyqtSignal(str) def __init__(self): super().__init__() self.initUI() def initUI(self): # Initialize self.setGeometry(1000, 300, 1200, 800) self.setWindowTitle('Sensorlyze') self.setWindowIcon(QIcon('biosensor.jpg')) # Add Text l1 = QLabel("Welcome to SensorLyze", self) l1.move(25, 350) l1.setFont(QFont('Calibri',15)) l1.adjustSize() l2 = QLabel("A software to simply sensor analytics", self) l2.move(25, 400) l2.setFont(QFont('Calibri', 10)) l2.adjustSize() # Add Buttons button1 = QPushButton('Start', self) button1.resize(button1.sizeHint()) # 改为连接到类的内部方法 button1.clicked.connect(self.start_clicked) button1.move(60, 450) button2 = QPushButton('Exit', self) button2.resize(button2.sizeHint()) button2.clicked.connect(self.exit_clicked) button2.move(240, 450) def start_clicked(self): # 将新窗口保存为实例属性,避免被垃圾回收 self.second_window = QMainWindow() self.second_window.setGeometry(300, 500, 500, 500) self.second_window.setWindowTitle('Hello') self.second_window.show() # 用self.hide()直接操作当前主窗口实例 self.hide() def exit_clicked(self): msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Information) msgBox.setText("Are you sure you want to exit?") msgBox.setWindowTitle("Exit Sensorlyze") msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msgBox.buttonClicked.connect(self.msgButtonClick) returnValue = msgBox.exec() if returnValue == QMessageBox.Ok: # 用PyQt规范的退出方式 QApplication.instance().quit() def msgButtonClick(self, i): print("Button clicked is:", i.text()) stylesheet = """ QMainWindow { background-image: url("C:/Users/admin/Desktop/Sensorlyze/biosensor.jpg"); background-repeat: no-repeat; background-position: center; } """ def main(): app = QApplication(sys.argv) app.setStyleSheet(stylesheet) win = MainWindow() win.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
关键修改点说明
- 把
start_clicked、exit_clicked、msgButtonClick都改成了MainWindow类的方法,所有窗口操作都封装在类内部,更符合面向对象设计规范。 - 新窗口
self.second_window作为实例属性存在,只要主窗口实例没被销毁,它就会一直保留,不会被垃圾回收。 - 用
self.hide()代替原来的win.hide(),直接操作当前主窗口实例,彻底摆脱全局变量的依赖。 - 退出操作改用
QApplication.instance().quit(),比直接调用exit()更符合PyQt的运行逻辑。
这样修改后,点击Start按钮打开的第二个窗口就不会闪退啦!
内容的提问来源于stack exchange,提问作者Siba
相关产品推荐
相关产品推荐

