Я хотел бы использовать механизм отражения Qt, поскольку в C ++ этой функции нет. Кажется, это работает, но вызов всех макросов и вспомогательных функций очень утомителен. Например, чтобы зарегистрировать перечисление как правильный метатип, мне пришлось пройти все следующие шаги:
Q_GADGET
макро.Q_ENUM
макрос сразу после этого. Q_DECLARE_METATYPE(MyClass)
qRegisterMetaType<..>()
для типа класса упаковки иТеперь я знаю, что некоторые из шагов могут быть пропущены, если часть полной функциональности не требуется. Но это не то, что я ищу, мне нужно использовать перечисления внутри сигналов, и мне нужно иметь возможность получить мета-метод сигнала и запросить его для его типа параметров.
Но все же я не могу не думать, что должен быть лучший / более простой способ сделать это.
К сожалению, вы не можете сделать меньше, чем это.
Q_GADGET
(или же Q_OBJECT
, для подклассов QObject) означает «генерировать мета-объектную информацию для этого класса».Q_ENUM
означает «генерировать мета-перечисление информации для этого конкретного перечисления». Теперь можно утверждать, что все (публичные?) Перечисления в зарегистрированном классе также должны быть автоматически зарегистрированы. Но так как это имеет стоимость (двоичный размер), и мы используем C ++, мы не хотим платить за перечисления, которые мы никогда не собираемся использовать в мета-объектной системе, так что это опция.Q_DECLARE_METATYPE
(не требуется для самого перечисления, если вы используете Q_ENUM
; не требуется в общем случае в вашем сценарии) позволяет использовать тип внутри QVariant
s (Q ++ C ++ 98, RTTI-менее воплощение C ++ 17 std::any
). Хотите вы этого или нет, зависит от типа. Я бы сказал, что все «типы значений» должны иметь его, но опять же, это генерирует дополнительный код, за который вы, возможно, не захотите платить. Кроме того, это действительно относится только к «типам значений» — эта регистрация требует, чтобы тип имел общедоступный конструктор по умолчанию, общедоступный конструктор копирования, общедоступное назначение копирования, публичный деструктор. Если у вас есть класс, у которого его нет, вы не можете использовать этот макрос => вы не можете обернуть его в QVariant
,qRegisterMetaType
регистрирует вышеупомянутые конструкторы / деструкторы в таблице во время выполнения, позволяя вам иметь уникальный идентификатор для типа (требуется, если вы хотите идентифицировать типы в сигнатурах методов), динамически создавать или уничтожать экземпляры типа (требуются, среди прочего, для реализации соединений в очереди: Qt нужен общий способ скопировать аргументы сигнала в событие, которое будет отправлено в целевой поток, и уничтожить такие аргументы позже), используйте подсистему Q_PROPERTY.В зависимости от того, что именно вам нужно сделать, вам нужно подмножество всего этого.
Других решений пока нет …