Crash on close and quit

2019-04-10 22:37发布

I have a PySide application that hosts a VLC MediaPlayer instance within a QWidget. When the application is closed via the QMainWindow's close event, or by using QApplication.quit(), the UI disappears and then I get a Windows dialog "python.exe has stopped working".

The QApplication hosts a custom QMainWindow class, which contains a custom QWidget (which handles all the UI tasks, with QMainWindow handling messaging between threads - the app records keystrokes and writes output files in background threads). There is also a timer running the the main QWidget that updates a LineEdit with the current position in the video.

The crash happens whether files are being written or not (code commented out).

Do I need to be performing some type of garbage collection, or perhaps disposing of my objects in a specific order? I've tried stopping the timer, setting the MediaPlayer, the Instance, and the frame that hosts the MediaPlayer all to None, and then detroying the frame (self.videoFrame.destroy()), but the app still crashes.

The basic code was based on the example Qt application from vlc's repo example, which has no special garbage collection or disposal of objects.

I'm running Python 2.6 on Windows XP. Right now I run Python straight from the command line, but have it set up to create an exe with Py2Exe once I get this crash fixed.

标签: pyqt pyside
2条回答
三岁会撩人
2楼-- · 2019-04-10 22:45

Wrapping in function helped me

def main():
    ...

if __name__ == '__main__':
    main()
查看更多
The star\"
3楼-- · 2019-04-10 22:59

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.

查看更多
登录 后发表回答