PyQt5使用setCentralWidget如何切回主窗口?返回按钮无响应问题
返回主窗口失效的核心原因
- QMainWindow执行
setCentralWidget()时,会完全接管传入控件的内存所有权,新控件替换旧控件的瞬间,旧控件会被Qt对象树机制自动销毁 - 原代码中所有用于页面切换的布局(
self.mainbox/self.leftbox/self.rightbox),在初始化阶段就被绑定到临时创建的QWidget上,布局内挂载的所有按钮、标签控件,会自动成为这个临时widget的子对象,随临时widget被销毁而连带回收。第一次切换到左侧页面时,存放主页面控件的临时widget被销毁,主页面的两个功能按钮也被连带释放 - Qt布局对象不支持被反复跨不同顶层widget重复绑定,重复设置会导致布局内控件的父对象关系混乱。最终点击返回按钮时,虽然触发了页面切换逻辑,但主页面布局内的控件已经全部丢失,页面内容空白,表现为「点击返回无响应」
可正常运行的实现方案
核心逻辑:提前为每个页面创建独立的QWidget实例,作为类的成员属性长期持有,切换页面时直接传入已创建的完整页面,不再临时新建widget、重复绑定布局
修改后的完整可运行代码:
import sys,os from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * class Class_MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Main Window") self.initUI() def initUI(self): self.widgets() self.layouts() def widgets(self): self.Masterbtn = QPushButton("Master") self.transbtn = QPushButton("tanscation") self.reportbtn = QPushButton("Reports") self.masterlbl = QLabel("Master Label") self.translbl = QLabel("transcation label") self.reportlbl = QLabel("Report Label") self.leftboxbtn = QPushButton("Open Left Box") self.leftboxbtn.clicked.connect(self.leftboxopn) self.rightboxbtn = QPushButton("Open Right Box") self.rightboxbtn.clicked.connect(self.rightboxopn) self.backbtn =QPushButton("Back") self.backbtn.clicked.connect(self.mainwindow) def layouts(self): self.mainbox = QVBoxLayout() self.mainbox.addWidget(self.leftboxbtn) self.mainbox.addWidget(self.rightboxbtn) self.leftbox = QVBoxLayout() self.leftbox.addWidget(self.Masterbtn) self.leftbox.addWidget(self.transbtn) self.leftbox.addWidget(self.reportbtn) self.leftbox.addWidget(self.backbtn) self.rightbox = QVBoxLayout() self.rightbox.addWidget(self.masterlbl) self.rightbox.addWidget(self.translbl) self.rightbox.addWidget(self.reportlbl) # 提前创建三个独立页面,作为类属性长期持有引用,避免切换时被销毁 self.main_page = QWidget() self.main_page.setLayout(self.mainbox) self.left_page = QWidget() self.left_page.setLayout(self.leftbox) self.right_page = QWidget() self.right_page.setLayout(self.rightbox) # 初始加载主页面 self.setCentralWidget(self.main_page) def leftboxopn(self): self.setWindowTitle("Left Box ") self.setCentralWidget(self.left_page) def rightboxopn(self): self.setWindowTitle("Right Box") self.setCentralWidget(self.right_page) def mainwindow(self): self.setWindowTitle("Main Window") self.setCentralWidget(self.main_page) def main(): app = QApplication(sys.argv) mainwindow = Class_MainWindow() mainwindow.show() sys.exit(app.exec_()) if __name__ == "__main__": main()
注意:只要Python代码中保留了对页面widget的强引用,即使页面被从主窗口中心区域替换下来,Qt也不会销毁该控件,后续切换时可以直接复用,无需重复初始化控件。
内容的提问来源于stack exchange,提问作者Kumar
相关产品推荐
相关产品推荐

