如何在PySide/PyQt中创建一个新的窗口按钮?

4
我使用Python 2.7的PyQt4/PySide遇到了“新窗口”功能的问题。我将initNewWindow()函数与操作连接,并将其放置在菜单栏中,以创建新窗口。然而,与桌面软件中的普通函数不同的是,新窗口弹出并立即关闭,而不是在其他窗口旁边持久存在。由于我正在处理专有代码,因此我在下面创建了一个示例,演示相同的错误。有没有方法可以让这个功能正常工作?该功能在Windows环境中编写和测试,可在PySide中运行。请注意保留HTML标记。
from PySide.QtCore import QSize
from PySide.QtGui import QAction
from PySide.QtGui import QApplication
from PySide.QtGui import QLabel
from PySide.QtGui import QMainWindow
from PySide.QtGui import QMenuBar
from PySide.QtGui import QMenu
from sys import argv

def main():
    application = QApplication(argv)
    window = QMainWindow()
    window.setWindowTitle('New Window Test')
    menu = QMenuBar(window)
    view = QMenu('View')
    new_window = QAction('New Window', view)
    new_window.triggered.connect(initNewWindow)
    view.addAction(new_window)
    menu.addMenu(view)
    label = QLabel()
    label.setMinimumSize(QSize(300,300))
    window.setMenuBar(menu)
    window.setCentralWidget(label)
    window.show()
    application.exec_()


def initNewWindow():
   window = QMainWindow()
   window.setWindowTitle('New Window')
   window.show() 


if __name__ == '__main__':
   main()
2个回答

5

如果一个函数创建了一个PyQt对象,而应用程序需要继续使用该对象,则需要确保以某种方式保留对它的引用。否则,在函数返回后,它可能会被Python垃圾收集器立即删除。

因此,要么给该对象指定一个父对象,要么将其作为其他对象的属性保留。(原则上,该对象也可以作为全局变量,但通常被认为是不好的实践)。

这里是您示例脚本的修订版本,演示了如何解决您的问题:

from PySide import QtGui, QtCore

class Window(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        menu = self.menuBar().addMenu(self.tr('View'))
        action = menu.addAction(self.tr('New Window'))
        action.triggered.connect(self.handleNewWindow)

    def handleNewWindow(self):
        window = QtGui.QMainWindow(self)
        window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        window.setWindowTitle(self.tr('New Window'))
        window.show()
        # or, alternatively
        # self.window = QtGui.QMainWindow()
        # self.window.setWindowTitle(self.tr('New Window'))
        # self.window.show()

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.resize(300, 300)
    window.show()
    sys.exit(app.exec_())

3
initNewWindow()返回时,window变量被删除,窗口的引用计数降为零,导致新创建的C++对象被删除。这就是为什么你的窗口会立即关闭的原因。
如果你想保持它打开,请确保保留一个引用。最简单的方法是将你的新窗口作为调用窗口的子窗口,并设置它的WA_DeleteOnClose小部件属性(参见Qt::WidgetAttribute)。

也许你的意思是 WA_DeleteOnClose - John Doe
2
@JohnDoe:是的,当然。我把它和WA_SantaClause混淆了...谢谢 ;) - Ferdinand Beyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接