Подтвердить что ты не робот

Когда следует использовать Q_OBJECT?

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

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