Методы Q_PROPERTY не могут быть вызваны с помощью QMetaObject ::invokeMethod()

#qt4 #invoke

#qt4 #вызвать

Вопрос:

Добрый день!

Из документов Qt 4.7.3 неясно, могут ли свойства вызываться с помощью QMetaObject::invokeMethod() или нет. Но что действительно странно, что оба вызова завершились неудачно:

 class A : public QObject
{
  Q_OBJECT

  public:

    Q_PROPERTY( int value READ value )

    int value() { return 0; }

    Q_PROPERTY( int invokableValue READ invokableValue )

    Q_INVOKABLE int invokableValue() { return 0; }
};

...

int returnValue;

QMetaObject::invokeMethod( aPtr, "value"
                           , Q_RETURN_ARG( int, returnValue ) );

QMetaObject::invokeMethod( aPtr, "invokableValue"
                           , Q_RETURN_ARG( int, returnValue ) );
  

Это означает, что Q_PROPERTY запрещает использование Q_INVOKABLE .

Давайте посмотрим a_moc.cpp:

       if (_c == QMetaObject::InvokeMetaMethod) {
    // no calls here
    }
    #ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
    void *_v = _a[0];
    switch (_id) {
    case 0: *reinterpret_cast< int*>(_v) = value(); break;
    case 1: *reinterpret_cast< int*>(_v) = invokableValue(); break;
    }
  

Я думаю, пришло время сообщить об ошибке и запросе функций, но, может быть, как-то эти проблемы можно решить?

Обновить:

Сообщение об ошибке.

Получено сообщение о предложении.

Комментарии:

1. Возможно, мне не следует публиковать это здесь, потому что это описание проблемы, а не вопрос.

2. Вы всегда можете превратить это в вопрос, например, спросив, был ли у кого-нибудь еще подобная проблема или удалось ее решить…

Ответ №1:

Проблема в том, что moc не является полноценным анализатором C , и он может легко неправильно интерпретировать ваш код.

Он не видит Q_INVOKABLE макрос, потому что он появляется сразу после Q_PROPERTY объявления. Если вы добавите точку с запятой после свойства (подсветке синтаксиса QtCreator это не понравится), или если вы измените порядок строк, он будет работать правильно.

Итак, например, работает следующий код:

 class A : public QObject
{
    Q_OBJECT
    Q_PROPERTY( int value READ value )
    Q_PROPERTY( int invokableValue READ invokableValue )
public:
    int value() { return 0; }
    Q_INVOKABLE int invokableValue() { return 0; }
};
  

Но я не уверен, зачем вам нужно иметь вызываемое свойство, поскольку вы уже можете прочитать любое свойство QObject::property .

Комментарии:

1. Это только для единообразия, потому что много кода использует «invoke»-путь.

2. Вы абсолютно правы насчет точки с запятой. В любом случае, я передам эти проблемы разработчикам qt.