Это потому, что, кстати, дизайн python вряд ли сработает. Python предназначен для определения методов или функций в контексте, где неявные this
(a-la Java / C ++) или явные @
(a-la ruby) не будут работать. Давайте рассмотрим пример с явным подходом с соглашениями python:
def fubar(x):
self.x = x
class C:
frob = fubar
Теперь функция fubar
не будет работать, так как предположим, что self
является глобальной переменной (и в frob
также). Альтернативой было бы выполнить метод с замененной глобальной областью (где self
- это объект).
Неявный подход будет
def fubar(x)
myX = x
class C:
frob = fubar
. Это будет означать, что myX
будет интерпретироваться как локальная переменная в fubar
(а также в frob
). Альтернативой здесь будет выполнение методов с замененной локальной областью, которая сохраняется между вызовами, но это устранит возможность локальных переменных метода.
Однако текущая ситуация работает хорошо:
def fubar(self, x)
self.x = x
class C:
frob = fubar
здесь, когда вызывается как метод frob
, получит объект, по которому он вызывается через параметр self
, и fubar
все еще можно вызвать с объектом в качестве параметра и работать одинаково (это [] совпадает с C.frob
, я думаю).
Вы должны использовать макрос Q_OBJECT
для любых не templated классов, которые происходят из QObject
.
Помимо сигналов и слотов, макрос Q_OBJECT
предоставляет информацию метаобъекта, которая связана с данный класс.
Как указано в документации :
, мы настоятельно рекомендуем, чтобы все подклассы QObject использовали макрос Q_OBJECT независимо от того, они действительно используют сигналы, слоты и свойства.
blockquote>Предположим, что у нас есть следующий класс:
class Class : public QObject { public: Class() {} };
Без
Q_OBJECT
следующие функции системы метаобъектов (среди другие) не будут работать дляClass
:
qobject_cast<Class>()
- из-за отсутствия метаданныхQObject::tr()
- из-за отсутствия метаданных- слоты и invokables, впервые объявленные в
Class
, при вызове или поиске по имени - ни один из методовQMetaObject
не будет работать для этих методов, и Qt 4connect
- из-за отсутствия метаданных- сигналы - поскольку
moc
не будет генерировать свои реализации, и код не будет компилироваться.Вы можете опустить это, конечно, но если вы когда-либо используете эти функции, вам нужно будет запомнить макрос в объявлении класса. Это довольно хрупкая практика, и ее лучше избегать. Экономия не стоит. Итак, не ждите - добавьте макрос
Q_OBJECT
к каждому классу, который получен изQObject
в качестве политики кодирования.Макрос
Q_OBJECT
должен never использовать для классов, которые не относятся кQObject
. Чтобы добавить invokables и свойства к таким классам, используйте макросQ_GADGET
.
Правильно сказал @liaK (вкратце: вы всегда должны использовать макрос Q_OBJECT в любом классе, который происходит из QObject).
Одна вещь, которую я не видел, - это то, что если вы не явно помещает макрос Q_OBJECT, а затем иногда очень удобно qobject_cast не будет работать !!!
Если вы хотите использовать сигналы / слоты, вы ДОЛЖНЫ включать макрос Q_OBJECT и выводить класс из QObject.
В противном случае вы можете его оставить, но он не вредит, чтобы включить его в все классы Qt gui