【问题标题】:Python 3.4: PyQt on Windows: Crash on exit only on some computersPython 3.4:Windows 上的 PyQt:仅在某些计算机上退出时崩溃
【发布时间】:2016-07-26 12:44:18
【问题描述】:

我有一个 Python 程序,我使用 cx_freeze 打包以使其可执行。该程序严格来说是一个用于数据采集的桌面程序。它在每台计算机上都可以正常工作并且退出正常,但是在我们的一个装有 Windows 7 的协作者的一个桌面上,它仅在退出时崩溃(我强调没有给出 Pythonic 错误。只是一个低级崩溃,关于零信息它)。只需启动和退出程序就会崩溃!

我让那个人为我创建了一个内存转储,他做到了。奇怪的部分如下:从中创建内存转储并使用 WinDbg 对其进行分析会产生以下错误链:

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
0020f940 5c51b34e 5c7bd640 9d7a3385 03c93748 QtCore4!QHashData::free_helper+0x26
0020f974 76e314bd 00b30000 00000000 03e0c4c0 QtGui4!QGestureRecognizer::reset+0x1f9e
0020f9a0 5c51c968 03c93748 5d3608c2 00000001 kernel32!HeapFree+0x14
0020f9a8 5d3608c2 00000001 03c93748 03891250 QtGui4!QGestureRecognizer::reset+0x35b8
0020f9c0 5d3627b5 9d0dae1c 03891250 03cac0a0 QtCore4!QObjectPrivate::deleteChildren+0x72
00000000 00000000 00000000 00000000 00000000 QtCore4!QObject::~QObject+0x3e5

现在让我吃惊的是,收到了来自QGestureRecognizer(即part of QtGUI apparently)的投诉!但为什么?我不使用任何触摸功能!我使用的模块是:QtCoreQtGUI。这是从哪里来的?我可以强制禁用与该类相关的所有内容:QGestureRecognizer?在这种情况下你会怎么做?

更新:

这个问题似乎只发生在 Windows 7 计算机上。它在 2 台装有 Windows 7 的计算机上进行了测试,并且发生了同样的崩溃。

【问题讨论】:

    标签: python crash pyqt exit crash-dumps


    【解决方案1】:

    似乎无法释放内存。您可以尝试使用以下功能手动执行此操作:

    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
                try:
                    item.deleteLater()
                except (RuntimeError, AttributeError): # deleted or no deleteLater method
                    pass
    

    然后你在你的主部件中定义一个清理方法。

    class MyWindow(QWidget):
        def cleanUp(self):
            # Clean up everything
            for i in self.__dict__:
                item = self.__dict__[i]
                clean(item)
    

    最后,在调用qt_app._exec() 之前,您必须像这样连接:

    qt_app.aboutToQuit.connect(app.cleanUp)
    

    app 是您的主窗口。


    编辑:

    if __name__ == '__main__' 行下的所有内容包装到单个main() 函数中有时会起作用,但我不知道为什么。

    【讨论】:

    • 谢谢。我会试试这个并报告:)
    • 我实现了解决方案...在我的计算机上有效,但在有问题的计算机上无效...退出时仍然崩溃。
    • 我已经有了...一切都在if __name__ == '__main__': 之下。唯一不在其中的是单个导入。
    • 那我必须承认我不知道,我没有足够的元素给你答案。这篇文章可能会帮助其他有类似问题的人,所以我把它留在这里
    • 当然。请保留它,因为它仍然有用:)。感谢您提供帮助。
    【解决方案2】:

    原来所有我曾经遇到的这个程序崩溃的问题是因为 QThread(在 Windows 上)。我认识的所有在 Windows 上使用 QThread 的用户都遇到了类似的问题,并且由于某种原因没有人修复它。

    避免在 Python 上使用 QThread。它完全没用,而且比有用更有害。我现在去了multiprocessing。它好多了,而且不受 GIL 的影响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-13
      • 1970-01-01
      • 2018-07-27
      • 2012-11-27
      • 1970-01-01
      • 2013-11-26
      • 2015-12-24
      • 2017-09-01
      相关资源
      最近更新 更多