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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8478210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 18:38:20  来源:igfitidea点击:

How to create a new window button PySide/PyQt?

pythonwindowspyqtpyside

提问by Christopher

I'm having problems with a "New Window" function in PyQt4/PySide with Python 2.7. I connected a initNewWindow()function, to create a new window, to an action and put it in a menu bar. Once a common function in desktop software. Instead of giving me a new persistent window alongside the other one the new window pops up and closes. The code I'm working on is proprietary so I created an example that does the same thing with the same error below. Is there any way to get this to work? Runs in PySide with Python 2.7. It was written in and tested in Windows.

我在使用 Python 2.7 的 PyQt4/PySide 中的“新窗口”函数有问题。我将一个initNewWindow()创建新窗口的函数连接到一个操作并将其放入菜单栏中。曾经是桌面软件中的常用功能。新窗口弹出并关闭,而不是在另一个窗口旁边给我一个新的持久窗口。我正在处理的代码是专有的,因此我创建了一个示例,该示例执行相同的操作,但出现以下相同的错误。有什么办法可以让它发挥作用吗?使用 Python 2.7 在 PySide 中运行。它是在 Windows 中编写和测试的。

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()

采纳答案by Ferdinand Beyer

When initNewWindow()returns, the windowvariable is deleted and the window's reference count drops to zero, causing the newly created C++ object to be deleted. This is why your window closes immediately.

initNewWindow()返回时,window变量被删除,并且该窗口的引用计数下降到零,从而导致新创建的C ++对象被删除。这就是为什么您的窗口会立即关闭。

If you want to keep it open, make sure to keep a reference around. The easiest way to do this is to make your new window a child of the calling window, and set its WA_DeleteOnClosewidget attribute (see Qt::WidgetAttribute).

如果您想保持开放,请务必保留参考资料。执行此操作的最简单方法是使您的新窗口成为调用窗口的子窗口,并设置其WA_DeleteOnClose小部件属性(请参阅 参考资料Qt::WidgetAttribute)。

回答by ekhumoro

If a function creates a PyQt object that the application needs to continue using, you will have to ensure that a reference to it is kept somehow. Otherwise, it could be deleted by the Python garbage collector immediately after the function returns.

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

So either give the object a parent, or keep it as an attribute of some other object. (In principle, the object could also be made a global variable, but that is usually considered bad practice).

所以要么给对象一个父对象,要么把它作为其他对象的一个​​属性。(原则上,对象也可以成为全局变量,但这通常被认为是不好的做法)。

Here's a revised version of your example script that demonstrates how to fix your problem:

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

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_())