How to create a new window button PySide/PyQt?
Question: 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.

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


Answer: 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.

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

