Я пишу программу, которая требует от пользователя быть очень гибким в манипулировании данными с данным объектом. Я подумал, что я бы использовал какой-то браузер свойств; Qtilities’ ObjectDynamicPropertyBrowser
бросилось в глаза.
Однако мне нужно иметь возможность добавлять свои собственные типы данных. В документации не ясно, как это сделать.
Как я могу позволить своим собственным типам данных быть представленными в виджетах браузера свойств Qtilities?
Кроме того, больше о моих потребностях:
Q_OBJECT
s.Q_DECLARE_METATYPE
хорошо.Браузер, на который вы ссылаетесь, зависит от QObject
система собственности. Так что, если ваши классы не являются объектами QObject, они не будут работать — но не отчаивайтесь, Qt 5.5 в помощь (читайте дальше). Браузер, кажется, использует QTreeView
и предоставляет модель адаптера, которая предоставляет QObject
система собственности. Таким образом, он использует тип Qt и систему делегатов.
В Qt 5.5 существует система свойств общего назначения, известная как гаджеты, которая может использоваться в любом классе, если есть QMetaObject
описывая этот класс. Добавляя Q_GADGET
макрос в класс, производный от предметного класса и описывающий свойства с использованием Q_PROPERTY
макрос, вы можете использовать moc
и система гаджетов для доступа к свойствам ваших неизмененных типов.
Единственная причина, по которой вы должны это сделать, — это потребовать минимальных изменений в ObjectPropertyBrowser
система. Вы не хотите ObjectDynamicPropertyBrowser
, поскольку он работает с динамическими свойствами, а ваши объекты не имеют их. Они имеют статические свойства, передаваемые через Q_PROPERTY
макросы и код, сгенерированный moc.
Итак, вы будете действовать так же, как и для реализации собственной поддержки типов для QVariant
и взгляды в целом. Вам также нужен Qt 5.5, так как вам нужна поддержка гаджетов для его работы. Решение для Qt 5.4 и ниже требует другого подхода и может быть менее громоздким для реализации другим способом.
Увидеть этот ответ для справки об использовании системы свойств гаджета для сериализации объектов, это в основном то, что должен делать браузер свойств, конечно же, без самой сериализации.
Есть три шага. Во-первых, вам нужно обратиться к простым пользовательским типам, которые не имеют структуры, но представляют одно значение (например, дату или время, или географическое положение и т. Д.), Или набор простых значений (например, матрицу). ).
Убедиться, что QVariant
может нести простые типы. Добавить Q_DECLARE_METATYPE
макрос сразу после определения типа в интерфейсе (заголовочный файл).
Воплощать в жизнь делегаты для типов. Для типов со структурой таблицы, таких как матрица, вы можете использовать QTableView
и предоставить модель адаптера, которая отображает содержимое типа в виде табличной модели.
Во-вторых, вы попадаете в ваши сложные типы, которые имеют внутреннюю структуру:
Создайте класс-оболочку, который наследуется от сложного типа, объявляет все свойства, используя Q_PROPERTY
и имеет Q_GADGET
макрос (не Q_OBJECT
так как они не QObjects). Такой класс не должен иметь своих собственных членов. Его единственными методами должны быть дополнительные методы доступа к свойствам. Q_GADGET
макрос добавляет статический (класс) член staticMetaObject
,
Базовый тип может быть static_cast
к классу-обертке, если это необходимо, но обычно это не нужно.
На этом этапе любой класс, для которого вы написали оболочку, доступен для QMetaProperty
Система напрямую, без литья! Вы бы использовали обертку staticMetaObject
для его статического метаобъекта, но QMetaProperty
readOnGadget
а также writeOnGadget
будет принимать указатели на базовый класс напрямую.
В-третьих, так как ObjectPropertyBrowser
Скорее всего, в Qt 5.5 не реализована поддержка гаджетов, так как это довольно ново, вам придется изменить ее, чтобы обеспечить такую поддержку. Изменения будут минимальными и связаны с использованием QMetaProperty::readOnGadget
а также QMetaProperty::writeOnGadget
вместо QMetaProperty::read
а также QMetaProperty::write
, Увидеть ответ сериализации для сравнения между двумя.