У меня есть полиморфное дерево типов C ++, с которым мне нужно работать из QML. Использование памяти и производительность являются ключевыми здесь, поэтому мне интересно, какой подход будет более эффективным:
Q_GADGET
— без сомнения, более простой и быстрый способ сделать это. Я могу напрямую использовать свойства (без уведомлений, поэтому и без привязок) и слоты для доступа к элементам каждого объекта. Он основан на генерации метаданных и некоторой идентификации объекта во время выполнения qtquick.
Используйте глобальный объект доступа для доступа ко всему, получения или установки свойств объекта, вызова функций и так далее. Это определенно медленное и более подробное решение.
Я ранее пробовал с QObject
производные типы зарегистрированы как типы QML, но использование памяти было ужасающим. У меня были огромные накладные расходы от QObject
один — около 140 байтов для базового 16-байтового набора данных, и создание экземпляров объектов в QML сделало это еще хуже, взлетев до 2000 байтов. Что недопустимо, учитывая большое количество объектов, с которыми я имею дело.
Так что теперь я иду по длинному пути, отказываясь от предыдущего дизайна, и задаюсь вопросом, что будет наиболее эффективной реализацией. Кроме того, мета вещи, связанные с Q_GADGET
будет хорошо работать в полиморфном сценарии.
Поэтому я решил проверить оба подхода и провести сравнение.
Мои усилия были прерваны, к счастью, в зачаточном состоянии обычным обязательным ограничением Qt — получается Q_GADGET
не работает с указателями, ни свойства, ни функции недоступны при работе с ними по указателю.
Для доступа к элементу поддерживаются только экземпляры, поэтому эта опция неприменима в полиморфном сценарии. Ручной объект доступа это!
Обновить:
Для этого есть обходной путь, но он требует дополнительной работы. Реализуя идиому PIMPL, вы можете иметь экземпляр объекта, реализующий свойства, просто являясь указателем на фактическую реализацию, делая все копирование применимым и эффективным.
Однако в итоге я не использовал этот подход, главным образом из-за того, что он все еще не поддерживал уведомления, а реализация уведомлений «третьей стороны» оказалась слишком неэффективной. Вместо этого я пошел на QObject
основанный «прокси» или «метод доступа» для каждого объекта, на который ссылается элемент QML. Прокси-сервер создается по требованию и подсчитывается по ссылке, поэтому он существует только тогда, когда необходим мост «object -> qml», который всегда предназначен только для очень небольшого подмножества всех объектов. Прокси тесно связан с объектом, чтобы избежать штрафов за его поиск, в то время как сам графический интерфейс по-прежнему абстрагируется.
Реальное преимущество этой реализации по сравнению со старыми объектами на основе QML впечатляет. Из-за нехватки памяти в 32-битной сборке около 300 тыс. Объектов он теперь способен обрабатывать около 500 Мб, что в 1666 раз больше.
Других решений пока нет …