关闭时崩溃并退出 [英] Crash on close and quit

查看:39
本文介绍了关闭时崩溃并退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 PySide 应用程序,它在 QWidget 中托管一个 VLC MediaPlayer 实例.当通过 QMainWindow 的关闭事件或使用 QApplication.quit() 关闭应用程序时,UI 消失,然后出现 Windows 对话框python.exe 已停止工作".

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".

QApplication 托管一个自定义 QMainWindow 类,其中包含一个自定义 QWidget(它处理所有 UI 任务,QMainWindow 处理线程之间的消息传递 - 应用程序记录击键并在后台线程中写入输出文件).还有一个运行主 QWidget 的计时器,该计时器使用视频中的当前位置更新 LineEdit.

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

我是否需要执行某种类型的垃圾收集,或者可能以特定顺序处理我的对象?我尝试停止计时器,将 MediaPlayer、Instance 和承载 MediaPlayer 的框架全部设置为 None,然后销毁框架 (self.videoFrame.destroy()),但应用程序仍然崩溃.

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.

基本代码基于 vlc 存储库中的示例 Qt 应用程序 示例,它没有特殊的垃圾收集或对象处理.

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.

我在 Windows XP 上运行 Python 2.6.现在我直接从命令行运行 Python,但是一旦我修复了这个崩溃,就将它设置为使用 Py2Exe 创建一个 exe.

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.

推荐答案

我知道这已经晚了,但我确实找到了解决方案.就我而言,没有内存泄漏,但某些 QObject 一定没有正确关闭.Python 3,PySide 1.2.1

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.

编辑

我最终使用名为 QtGui.qApp.closeAllWindows() 的事件过滤器去除了上述所有清理代码.不过,后来这个问题又出现了.我现在相信这与 C++ 和 python 对象不同步以及对象如何清理有关.

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.

这篇关于关闭时崩溃并退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆