Crash on close and quit

我与影子孤独终老i 提交于 2019-12-04 13:21:33

Wrapping in function helped me

def main():
    ...

if __name__ == '__main__':
    main()

I know this is late, but I did find a solution. In my case there was no memory leaks, but some of the QObjects must not have been closing properly. Python 3, PySide 1.2.1

class CustomWindow(QtGui.QMainWindow):
    def cleanUp(self):
        # Clean up everything
        for i in self.__dict__:
            item = self.__dict__[i]
            clean(item)
     # end cleanUp
# end class CustomWindow

def clean(item):
    """Clean up the memory by closing and deleting the item if possible."""
    if isinstance(item, list) or isinstance(item, dict):
        for _ in range(len(item)):
            clean(list(item).pop())
    else:
        try:
            item.close()
        except (RuntimeError, AttributeError): # deleted or no close method
            pass
        try:
            item.deleteLater()
        except (RuntimeError, AttributeError): # deleted or no deleteLater method
            pass
# end clean

if __name__ == "__main__":
    app = Qtgui.QApplication(sys.argv)

    window = CustomWindow()
    window.show()

    app.aboutToQuit.connect(window.cleanUp)

    sys.exit(app.exec_())

This will loop through everything that is in the main window, and it will close and delete all of the items found if possible. It made my application close immediately with no memory leaks or problems. You may also have to specifically close some items and make sure that no errors are caused from trying to delete an item that was already deleted.

EDIT

I eventually got rid of all the above clean up code with an event filter that called QtGui.qApp.closeAllWindows(). However, later the issue came up again. I now believe it has something to do with the C++ and python objects getting out of sync and how the objects are cleaned up.

class CloseAllFilter(QtCore.QObject):
    """Event filter for closing all windows if the widget is closed."""
    def eventFilter(self, receiver, event):
        results = super().eventFilter(receiver, event)
        if event.type() == QtCore.QEvent.Close and event.isAccepted():
            for win in QtGui.qApp.topLevelWidgets():
                if win != receiver:
                    try:
                        win.close()
                        # win.deleteLater() # This seemed to make python crash more consistently.
                    except (AttributeError, RuntimeError):
                        pass
        return results
# end class CloseAllFilter

window.__close_all_filter = CloseAllFilter()
window.installEventFilter(window.__close_all_filter )

This seemed to work better for me. I also have my application and window wrapped in a function.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!