Python 3.4: PyQt в Windows: сбой при выходе только на некоторых компьютерах

У меня есть программа Python, которую я упаковал с cx_freeze, чтобы сделать исполняемый файл. Программа является строго настольной программой для сбора данных. Он отлично работает и отлично завершается на всех компьютерах, но на одном рабочем столе одного из наших сотрудников с Windows 7 происходит сбой только при выходе (я подчеркиваю, что никаких питонических ошибок не выдается. Просто сбой низкого уровня с нулевой информацией о Это). Простой запуск и выход из программы приводит к ее сбою!

Я попросил парня создать для меня дамп памяти, и он это сделал. Странная часть заключается в следующем: создание из этого дампа памяти и его анализ с помощью 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 (который, по-видимому, является частью QtGUI, очевидно) дано! Но почему? Никакими сенсорными возможностями не пользуюсь! Я использую следующие модули: QtCore и QtGUI. Откуда это взялось? Могу ли я принудительно отключить все, что связано с этим классом: QGestureRecognizer? Что бы вы сделали в этом случае?

Обновлять:

Эта проблема возникает ТОЛЬКО на компьютерах с Windows 7. Он был протестирован на 2 компьютерах с Windows 7, и произошел такой же сбой.


person The Quantum Physicist    schedule 26.07.2016    source источник


Ответы (2)


Кажется, проблемы с освобождением памяти. Вы можете попробовать сделать это вручную с помощью такой функции:

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(), иногда срабатывает, но я понятия не имею, почему.

person AdrienW    schedule 26.07.2016
comment
Спасибо. Я попробую это и доложу :) - person The Quantum Physicist; 26.07.2016
comment
Я реализовал решение ... работает на моем компьютере, но не работает на компьютере, на котором возникла проблема ... он все еще вылетает при выходе. - person The Quantum Physicist; 26.07.2016
comment
Это у меня уже есть ... все под if __name__ == '__main__':. Единственное, чего нет в этом, так это разового импорта. - person The Quantum Physicist; 26.07.2016
comment
Тогда я должен признать, что не знаю, у меня недостаточно элементов, чтобы дать вам ответ. Этот пост может помочь другим решить аналогичную проблему, поэтому я оставлю его здесь. - person AdrienW; 26.07.2016
comment
Абсолютно. Пожалуйста, сохраните его, так как это все равно полезно :). Спасибо за попытку помочь. - person The Quantum Physicist; 26.07.2016

Оказалось, что ВСЕ проблемы, которые у меня возникали при сбое этой программы, были из-за QThread (в Windows). У всех знакомых мне пользователей, которые использовали QThread в Windows, были похожие проблемы, и по какой-то причине их никто не исправляет.

Избегайте использования QThread на Python. Это совершенно бесполезно и скорее вредно, чем полезно. Я пошел сейчас на multiprocessing. Это намного лучше и не зависит от GIL.

person The Quantum Physicist    schedule 18.10.2016