#python #pyqt #pyqt5
#python #pyqt #pyqt5
Вопрос:
Предыстория
Я создаю приложение PyQt5 и столкнулся с проблемой
Internal c Object Already Deleted
которая вызвана ошибкой, описанной на этой странице:
Если QObject выпадает из области видимости в Python, он будет удален.
Итак, я смог избежать этой проблемы, используя необязательный parent =
параметр или сохранив ссылки на объекты, из-за которых у меня возникла проблема
Вопрос
В целях тестирования я хотел бы знать, возможно ли вручную вызвать эту проблему ( Internal c Object Already Deleted
)
Это периодически возникающая проблема, поэтому, чтобы иметь возможность протестировать это, мне нужен какой-то надежный способ ее воспроизведения
(Я не хочу хранить ссылки на все объекты, а сохраняю ссылки только тогда, когда они необходимы)
Я использую PyQt5.15 и Python 3.8
Ответ №1:
Предыдущее примечание: Сообщения об ошибках различаются в зависимости от привязки:
-
PyQt5
RuntimeError: wrapped C/C object of type <QtClass> has been deleted
-
PySide2
RuntimeError: Internal C object (PySide2.<QtModule>.<QtClass>) already deleted.
Проблема вызвана тем, что объект C , который управляет объектом python, был удален, и, следовательно, желание изменить какое-либо свойство объекта C с помощью объекта python, очевидно, не может быть выполнено.
Если вы хотите воспроизвести ту же проблему, просто удалите объект C , используя метод удаления sip или shiboken, в зависимости от того, используете ли вы PyQt5 или PySide2 соответственно.
-
PyQt5
from PyQt5 import QtCore import sip o = QtCore.QObject() o.setProperty("foo", "bar") sip.delete(o) o.setProperty("foo", "bar")
-
PySide2
from PySide2 import QtCore import shiboken2 o = QtCore.QObject() o.setProperty("foo", "bar") shiboken2.delete(o) o.setProperty("foo", "bar")
Комментарии:
1. Спасибо вам за вашу помощь! — Я все еще не уверен, что понимаю базовую архитектуру, но возможно ли запустить что-то вроде (глобальной) сборки мусора. В IIRC c этого нет, так что, я полагаю, это было бы на уровне Python? (Я действительно пробовал использовать Python
gc.collect()
, но это не вызвало ни одной из проблем, которые я видел). — Я предполагаю, что я спрашиваю вот о чем: возможно ли сделать что-то подобное тому, что вы описываете, но глобально для всех объектов? С точки зрения практического тестирования сложно добавить свой код для всех объектов (есть риск, что я могу что-то пропустить).