2014-09-05 2 views
3

Я пытаюсь что-то сделать в QML, чтобы попытаться сделать его более легким для слияния двух более легко; если быть точным, я пытаюсь связать объект со структурированными данными с QML.QML: Ошибка типа с пользовательским QObject

У меня есть следующие настройки:

main.cpp:

#include <QApplication> 
#include <QQmlApplicationEngine> 
#include <QtQml> 
#include "dataobject.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    qmlRegisterType<DataObject>("DO", 1,0,"DataObject"); 

    QQmlApplicationEngine engine; 
    engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); 

    return app.exec(); 
} 

dataobject.h:

#ifndef DATAOBJECT_H 
#define DATAOBJECT_H 

#include <QObject> 
#include <QVariant> 
#include <iostream> 

class DataObject : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(qreal a MEMBER a NOTIFY aChanged) 
    Q_PROPERTY(qreal b MEMBER b NOTIFY bChanged) 
public: 
    explicit DataObject(QObject *parent = 0); 

signals: 
    void aChanged(); 
    void bChanged(); 

public slots: 
    void printState() { 
     using namespace std; 
     cout << a << ", " << b << endl; 
    } 

private: 
    qreal a; 
    qreal b; 
}; 

#endif // DATAOBJECT_H 

dataobject.cpp:

#include "dataobject.h" 

DataObject::DataObject(QObject *parent) : 
    QObject(parent) 
{ 
    connect(this, SIGNAL(aChanged()), this, SLOT(printState())); 
    connect(this, SIGNAL(bChanged()), this, SLOT(printState())); 
} 

main.qml :

import DO 1.0 

ApplicationWindow { 
    visible: true 
    width: 640 
    height: 480 
    title: qsTr("Hello World") 

    menuBar: MenuBar { 
     Menu { 
      title: qsTr("File") 
      MenuItem { 
       text: qsTr("Exit") 
       onTriggered: Qt.quit(); 
      } 
     } 
    } 
    Text { 
     text: qsTr("Hello World") 

     MouseArea { 
      property DataObject myData; 
      anchors.fill: parent 
      drag.target: parent 

      onReleased: { 
       myData.a = mouse.x; 
       myData.b = mouse.y; 
      } 
     } 
    } 
} 

qml.qrc:

<RCC> 
    <qresource prefix="/"> 
     <file>main.qml</file> 
    </qresource> 
</RCC> 

Теперь, что я надеялся, что значения, полученные с помощью QML можно кормить в объект в C++ непосредственно (т.е. обработчик onReleased в MouseArea пытается записать в поле myData). Однако это базовое доказательство концепции не работает, но я действительно не понимаю, почему.

Я получаю ошибку (на сопротивление и отпускании кнопки мыши) является: QRC: ///main.qml: 29: TypeError: Тип ошибки

Что совпадает с линией «myData.a = mouse.x; ", так что он не работает сразу.

Любая идея, в которой я ошибаюсь? Я пробовал использовать поля int, double, QVariant и qreal, ни один из которых не работал. Является ли фундаментальная неспособность в QML связывать такие объекты? Если да, то любая идея, как, например, anchors.fill реализуется в исходном коде Qt?

ответ

6

Это помогает, если вы разбиваете выражение на линии, откуда исходит ошибка. Попробуйте просто печать myData.a первый:

print(myData.a) 
myData.a = mouse.x; 
myData.b = mouse.y; 

qrc:///main.qml:31: TypeError: Cannot read property 'a' of null

Так, myData является null. Мы можем проверить это с другим QObject типа -На:

MouseArea { 
    property DataObject myData; 
    property Item item 
    anchors.fill: parent 
    drag.target: parent 

    onReleased: { 
     print(item) 
     myData.a = mouse.x; 
     myData.b = mouse.y; 
    } 
} 

qml: null

Таким образом, вы можете исправить эту ошибку инициализации свойства:

свойства
property DataObject myData: DataObject {} 

Вы можете думать о QObject основе как указатели для JavaScript; они могут быть null или указывать на действительный объект ... или быть undefined. :) Я не могу найти ничего упомянутого об этом here, но здесь следует упомянуть об этом поведении.

Если вы хотите, чтобы упростить вещи, вы можете иметь объект по-умолчанию, для вас, сделав его дочерний объект MouseArea, а не свойство:

MouseArea { 
    DataObject { 
     id: myData 
    } 
    anchors.fill: parent 
    drag.target: parent 

    onReleased: { 
     myData.a = mouse.x; 
     myData.b = mouse.y; 
    } 
} 

В настоящее время, вы выиграли» t иметь возможность ссылаться на это свойство из C++.Однако вы можете достичь этого двумя способами:

  1. Объявление property alias к деталю.
  2. Дайте objectName и используйте QObject::findChild, чтобы найти его.
+0

Спасибо большое! было бы гораздо яснее Qt, чтобы указать «нулевой указатель» или что-то в этом роде, но теперь он отлично работает :). И спасибо за советы re-C++ objects – Doug

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