Когда следует использовать Q_OBJECT? - PullRequest
44 голосов
/ 11 сентября 2010

В документации указано, что:

Макрос Q_OBJECT должен появиться в приватный раздел определения класса который объявляет свои собственные сигналы и слоты или что использует другие сервисы предоставлено мета-объектной системой Qt.

Но точно что это значит? В каких классах, производных от QObject, я могу его безопасно пропустить? Возникнут ли проблемы, если вы опустите Q_OBJECT в классе, производном от QObject, а затем унаследуете от него? По сути, я хотел бы получить немного больше информации о том, когда я могу опустить его в моих классах Qt.

Ответы [ 4 ]

35 голосов
/ 11 сентября 2010

Вы должны использовать макрос Q_OBJECT для любых не шаблонных классов, производных от QObject.

Кроме сигналов и слотов, макрос Q_OBJECT предоставляет информация мета-объекта , связанная с данным классом.

Как указано в документации :

, мы настоятельно рекомендуем все подклассыQObject использует макрос Q_OBJECT независимо от того, используют ли они на самом деле сигналы, слоты и свойства.

Предположим, у нас есть следующий класс:

class Class : public QObject {
public:
  Class() {}
};

БезQ_OBJECT, следующие функции системы метаобъектов (помимо прочего) не будут работать для Class:

  1. qobject_cast<Class>() - из-за отсутствия метаданных

  2. QObject::tr() - из-за отсутствия метаданных

  3. слотов и активируемых объектов, впервые объявленных в Class, при вызове или поиске по имени - ни один из QMetaObject методов не будет работать дляэти методы, также не будет Qt 4 connect - из-за отсутствующих метаданных

  4. сигналов - поскольку moc не будет генерировать их реализации и код не будет компилироваться.

Конечно, вы можете его опустить, но еслиВы когда-либо используете эти функции, вам нужно помнить, чтобы вставить макрос в объявление класса.Это довольно хрупкая практика, которую лучше избегать.Экономия не стоит.Так что не ждите - добавьте макрос Q_OBJECT в каждый класс, производный от QObject в соответствии с политикой кодирования.

Макрос Q_OBJECT не должен использоваться , никогда на классах, которые не являются производными от QObject.Чтобы добавить вызываемые и свойства к таким классам, используйте вместо этого макрос Q_GADGET.

6 голосов
/ 11 сентября 2010

Если вы хотите использовать сигналы / слоты, вы ДОЛЖНЫ включить макрос Q_OBJECT и получить класс из QObject.

В противном случае вы можете пропустить это, но не повредит включить его во все классы Qt GUI

4 голосов
/ 11 сентября 2010

Ну, первая часть довольно ясна, как вы, наверное, уже знаете ... сигналы и слоты, остальная часть системы мета-объектов немного менее известна. Возможно, одна из наиболее полезных функций - это динамические свойства. Хотя у них много применений, я использовал их, чтобы воспользоваться системой анимации Qt QPropertyAnimation.

Здесь немного больше информации о мета-объектной системе: http://doc.qt.io/archives/4.6/metaobjects.html

Я думаю, что суть в том, что если вы наследуете от иерархии QObject, добавьте макрос Q_OBJECT независимо. Это просто сделать и избавит вас от некоторых потенциально непонятных проблем в будущем.

2 голосов
/ 11 сентября 2010

То, что сказал @liaK, является правильным (короче: вы должны всегда использовать макрос Q_OBJECT в любом классе, производном от QObject).

Одна вещь, которую я не видел выделенной, это то, что если вы не явно добавили макрос Q_OBJECT , то использовали иногда очень удобный qobject_cast не будет работать !!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...