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

PySide2跨窗口调用函数创建QStackedWidget报错解决

问题根因

报错本质是方法调用时的self绑定错误:

  • 你写的win1.creat_stackedwidget(self)属于类直接调用实例方法,传入的self是当前win2窗口的实例对象,不是win1的实例
  • creat_stackedwidget方法内部访问self.centralwidget时,实际是在win2对象上找该属性,而centralwidget是QMainWindow子类win1才有的UI元素,win2本身没有这个属性,直接抛出AttributeError

错误写法示例

你当前win2内的信号绑定逻辑大概率是这样:

# 错误:类直接调用实例方法,传入的self是win2实例
self.target_btn.clicked.connect(lambda: win1.creat_stackedwidget(self))

这也是为什么你在win1内部绑定按钮调用自身方法不报错——此时方法内的self就是win1实例本身,能正常访问centralwidget属性。


正确跨窗口调用实现

核心逻辑是:win2持有win1的实例引用,通过实例调用方法,不要直接用类名调用未绑定的实例方法。

第一步:修改win2类构造逻辑,接收主窗口实例

class win2(QtWidgets.QMainWindow, Ui_Form):
    def __init__(self, main_window, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        # 保存传入的win1实例作为自身属性
        self.main_window = main_window
        # 绑定按钮点击信号
        self.create_stack_btn.clicked.connect(self._trigger_create_stack)

    def _trigger_create_stack(self):
        # 通过win1实例调用方法,此时方法内的self就是win1对象
        self.main_window.creat_stackedwidget()

第二步:修改win1打开win2的逻辑,传入自身实例

class win1(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.open_win2_btn.clicked.connect(self.open_win2)
        self._win2_ins = None  # 持有win2实例引用,避免窗口被GC回收
        self._stack_ins = None # 持有堆叠控件引用,避免重复创建

    def open_win2(self):
        if not self._win2_ins:
            # 初始化win2时,把当前win1实例self传入
            self._win2_ins = win2(main_window=self)
        self._win2_ins.show()

    def creat_stackedwidget(self):
        # 加重复判断,避免多次点击重复创建控件
        if self._stack_ins:
            return
        self._stack_ins = QtWidgets.QStackedWidget()
        # 添加两个子页面
        page_a = QtWidgets.QWidget()
        page_b = QtWidgets.QWidget()
        self._stack_ins.addWidget(page_a)
        self._stack_ins.addWidget(page_b)
        # 将堆叠控件加入主窗口中心部件的垂直布局
        self.verticalLayout.addWidget(self._stack_ins)

避坑要点
  • 所有Qt窗口类的实例方法,必须通过对应实例调用,不要直接用类名调用,除非你明确知道未绑定方法的传参规则
  • 跨窗口交互时,通过构造函数传参传递目标对象引用即可,不要使用全局变量存窗口实例,避免出现作用域混乱、内存泄漏问题
  • 动态创建UI控件时建议加重复判断,避免多次触发信号重复创建相同控件导致布局异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 08:27:24