PySide2 QtCore.Signal失效 按钮点击无法切换QStackedWidget页面
问题根因
你的代码有4个核心错误,导致按钮点击后无响应:
- 自定义信号未完成绑定:你把信号和槽的连接逻辑写在了各个
show_xxx页面切换方法内部,但程序启动初始化时这些方法从未被执行,按钮点击时发射的信号没有任何对应的接收槽,自然不会触发任何逻辑。 - 重复创建无效页面实例:每次调用
show_xxx方法时你都会重新实例化新的页面对象,但这些新对象从来没有被添加到QStackedWidget控件栈中,就算执行了切换当前控件的逻辑,界面也不会显示未入栈的新实例。 - 类属性定义不规范:你把
QApplication、QStackedWidget、所有页面实例都定义为Controller的类属性而非实例属性,很容易出现初始化顺序混乱、跨实例访问异常的隐性问题。 - 页面类继承错误:你的主窗口类
MainWindowUi只继承了pyuic生成的Ui_MainWindow类,没有继承QtWidgets.QMainWindow,本身不属于合法的Qt窗口类,存在运行隐患。
修复方案
初始化Controller时一次性完成所有页面实例的创建、入栈、信号绑定,不要在切换页面时重复创建新实例,直接复用栈内已有的页面实例即可。
修复后的完整可运行代码:
from PySide2 import QtCore, QtWidgets from ui_Page_accueil import Ui_MainWindow from ui_NouvelleVerif import Ui_Dialog as Ui_NouvelleVerif from ui_NouvelleVerifEssieux import Ui_Dialog as Ui_NouvelleVerifEssieux import sys class MainWindowUi(QtWidgets.QMainWindow, Ui_MainWindow): to_NouvelleVerif = QtCore.Signal() def __init__(self): super().__init__() self.setupUi(self) self.pushButton_2.clicked.connect(self.pushbutton_handler2) def pushbutton_handler2(self): self.to_NouvelleVerif.emit() class NouvelleVerifUi(QtWidgets.QWidget, Ui_NouvelleVerif): to_MainWindow = QtCore.Signal() to_NouvelleVerifEssieux = QtCore.Signal() def __init__(self): super().__init__() self.setupUi(self) self.pushButton.clicked.connect(self.pushbutton_handler1) self.pushButton_3.clicked.connect(self.pushbutton_handler3) def pushbutton_handler1(self): self.to_MainWindow.emit() def pushbutton_handler3(self): self.to_NouvelleVerifEssieux.emit() class NouvelleVerifEssieuxUi(QtWidgets.QWidget, Ui_NouvelleVerifEssieux): to_NouvelleVerif = QtCore.Signal() def __init__(self): super().__init__() self.setupUi(self) self.pushButton.clicked.connect(self.pushbutton_handler1) def pushbutton_handler1(self): self.to_NouvelleVerif.emit() class Controller: def __init__(self): self.app = QtWidgets.QApplication(sys.argv) self.widget = QtWidgets.QStackedWidget() # 一次性创建所有页面实例 self.MainWindow = MainWindowUi() self.NouvelleVerif = NouvelleVerifUi() self.NouvelleVerifEssieux = NouvelleVerifEssieuxUi() # 所有页面加入控件栈 self.widget.addWidget(self.MainWindow) self.widget.addWidget(self.NouvelleVerif) self.widget.addWidget(self.NouvelleVerifEssieux) self.widget.setCurrentWidget(self.MainWindow) # 一次性绑定所有页面切换信号 self.MainWindow.to_NouvelleVerif.connect(lambda: self.widget.setCurrentWidget(self.NouvelleVerif)) self.NouvelleVerif.to_MainWindow.connect(lambda: self.widget.setCurrentWidget(self.MainWindow)) self.NouvelleVerif.to_NouvelleVerifEssieux.connect(lambda: self.widget.setCurrentWidget(self.NouvelleVerifEssieux)) self.NouvelleVerifEssieux.to_NouvelleVerif.connect(lambda: self.widget.setCurrentWidget(self.NouvelleVerif)) def run(self): self.widget.show() sys.exit(self.app.exec_()) def main(): controller = Controller() controller.run() if __name__ == '__main__': main()
额外说明
如果后续需要每次进入页面时刷新页面内容,不要重新创建实例,给每个页面类单独写一个刷新内容的公开方法,切换页面前调用对应方法刷新即可,重复创建实例会导致内存泄漏、信号绑定失效等问题。
内容的提问来源于stack exchange,提问作者Paleni Luca
相关产品推荐
相关产品推荐

