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

PySide2额外窗口仅在调试模式可打开 非调试模式无报错不显示

问题原因

你的判断完全正确,未持有窗口实例的引用就是故障的核心原因。
new_window是additional_window函数内的局部变量,当函数执行完毕后,局部变量会超出作用域,被Python垃圾回收机制自动销毁。new_window.show()确实会执行,但窗口对象刚被创建显示就被回收,自然无法在界面上稳定存在,整个过程也不会抛出任何异常。
调试模式下窗口能正常弹出,是因为PyCharm的调试进程会额外持有所有局部变量的引用(方便开发者调试时查看变量值),阻止了垃圾回收触发;而正常运行模式、shell脚本启动、cmd启动时不存在这个调试层的额外引用,窗口就会被立刻回收。
你看到的部分教程未持有引用仍能运行,基本都是因为运行环境特殊——比如在交互式Python shell、持续运行的调试上下文里,全局作用域会自动暂存变量引用,这种写法本身不符合Qt的对象生命周期管理规则,不能直接用于正式代码。

修复方案

只要保证新窗口的实例在显示期间有持续有效的引用即可,有两种常见实现方式:

  • 方式1:使用全局变量持有窗口引用
    修改后的可运行代码:
import sys
from PySide2 import QtWidgets
from PySide2.QtWidgets import QApplication, QMainWindow

app = QApplication(sys.argv)
win = QMainWindow()
add_win_button = QtWidgets.QPushButton(win)
# 全局作用域声明子窗口引用
new_window = None

def additional_window():
    global new_window
    new_window = QMainWindow()
    new_window.setGeometry(150, 150, 300, 300)
    new_window.setWindowTitle("Additional Window")
    new_window.show()

def window():
    win.setGeometry(200, 200, 600, 600)
    win.setWindowTitle("Main Window")
    add_win_button.setText("Add a Window")
    add_win_button.move(380, 70)
    add_win_button.clicked.connect(additional_window)
    add_win_button.adjustSize()
    win.show()
    sys.exit(app.exec_())

window()
  • 方式2(推荐):使用面向对象写法,通过类属性(即你提到的self参数)持有窗口引用
    这种写法更符合Qt的常规开发规范,窗口生命周期管理更清晰,适合工具包这类有一定复杂度的项目:
import sys
from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 类属性持有子窗口引用,生命周期和主窗口绑定
        self.new_window = None
        self.setGeometry(200, 200, 600, 600)
        self.setWindowTitle("Main Window")
        
        self.add_win_button = QPushButton(self)
        self.add_win_button.setText("Add a Window")
        self.add_win_button.move(380, 70)
        self.add_win_button.clicked.connect(self.additional_window)
        self.add_win_button.adjustSize()

    def additional_window(self):
        self.new_window = QMainWindow()
        self.new_window.setGeometry(150, 150, 300, 300)
        self.new_window.setWindowTitle("Additional Window")
        self.new_window.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_win = MainWindow()
    main_win.show()
    sys.exit(app.exec_())

内容的提问来源于stack exchange,提问作者Marco Frag Delle Monache

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:34:13