2013-10-15 2 views
4

Я новичок в QML и имеет проблемы при доступе к property.property в Си ++ объект:QML свойства свойства C++ объект

C++, частота и станция оба являются Qt метатипа зарегистрированы объекты:

CStation *station = new CStation(...); // QObject 
CFrequency *frequency = new CFrequency(..); // QObject 
QQmlContext *qmlContext = viewer.rootContext(); 
qmlContext->setContextProperty("myatcstation", station); 
qmlContext->setContextProperty("myfrequency", frequency); 

QML:

RowLayout { .... 
     TextField { 
      text: myatcstation.toQString(true) 
     } 
    } 
....  text: myfrequency.toQString(true) 

Это работает, но когда я пишу: text: myatcstation.frequency.toQString(true) я получить TypeError: Object [object Object] has no method 'toQString'

frequency является свойством класса CStation множества, как Q_PROPERTY(CFrequency frequency READ getFrequency)

перепроверить в C++ работает:

CFrequency test = station->property("frequency").value<CFrequency>(); 

- Edit: ответ Франка -

Оба класса являются производными от QObject, и это не в соответствии с учебником, поскольку они сделаны скопированными. Я знаю ситуацию Identity vs value.

В основном частота - объект значения, но я сделал его QObject, поэтому я могу использовать с ним свойства (см. Any chance to use non QObject classes with QML). В этом примере toString - Q_INVOKABLE, частота в нерабочем случае возвращает копию QObject, полученного CFrequency.

- Edit: Дополнительные данные -

Когда я изменить свойство частоты, чтобы вернуть CFrequency* вместо CFrequency он не работает. Когда я получаю TypeError: Cannot call method 'toQString' of undefined, ситуация кажется такой же. CFrequency работает только один, но QML не понимает, что myatcstation.frequency является частотным объектом, который имеет toString.

ответ

1

CFrequency не является объектом QObject Я полагаю, иначе вы бы не возвращали его по значению, а указателем. Чтобы сделать toQString() вызываемым из QML, он должен быть либо Q_INVOKABLE, либо слотом, что означает, что CF-частота также должна быть QObject.

Если станция имеет только одну частоту, подумайте над перемещением соответствующей информации в объект станции, то есть добавьте информацию о частоте, необходимую вам в качестве свойств для CStation.

Чтобы получать обновления при изменении частоты, рассмотрите возможность использования такого свойства, как Q_PROPERTY(QString frequencyAsString READ frequencyAsString NOTIFY frequencyAsStringChanged), а не toQString(). В свойствах есть механизм обновления «встроенный» через привязки свойств, в то время как нет хорошего способа сказать QML, что он должен снова вызвать toQString, потому что частота изменилась.

+0

Хороший совет, добавленная информация выше. Вопрос в том, должен ли он работать, если CFrequency (который является возвратом QObject по значению) возвращается как копия (даже если не требуется копировать QObjects). –

1

я решил аналогичную проблему:

class TopObject : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(ValueObject* theValue ... 
    ... 
} 

class ValueObject : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QString value ... 
    ... 
} 

В главном приложении:

qRegisterMetaType<ValueObject>("ValueObject"); 
qmlRegisterType<ValueObject>("com.name.comp", 1, 0, "ValueObject"); 

...->setContextProperty("topObject", new TopObject()); 

И в коде QML:

import com.name.comp 1.0 

... { 
    text: topObject.theValue.value 
... 

Это необходимо как, возврате имущества (ValueObject) в качестве указателя и регистрации его с помощью qmlRegisterType.

См. Также Exchange Data and Objects between C++ and QML and vice versa

Смежные вопросы