2014-09-05 109 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++中直接在對象(即MouseArea中的onReleased處理程序試圖寫入myData字段)。然而,這個概念的基本證明不起作用,但我不明白爲什麼。

我得到(上拖動和鬆開鼠標按鍵)的錯誤是: QRC:///main.qml:29:類型錯誤:錯誤類型

與行相匹配「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

所以,myDatanull。我們可以用另一種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

所以,你可以通過初始化屬性修正此錯誤:

基於QObject的
property DataObject myData: DataObject {} 

你能想到的性能指針適用於JavaScript;他們可以是null或指向一個有效的對象...或者是undefined。 :)我找不到任何關於此here的提及,但這就是應該提及此行爲的地方。

如果您想簡化事情,你可以通過它MouseArea的子對象,而不是一個擁有房產的對象缺省構造爲您提供:

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

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

目前,你贏了」無法從C++中引用該屬性。但是,您可以通過以下兩種方式實現此目的:

  1. 聲明property alias到項目。
  2. 給它一個objectName並使用QObject::findChild來找到它。
+0

非常感謝!本來Qt更清楚地說明'空指針'或類似的東西,但它現在工作正常:)。並感謝提示重新C++對象 – Doug 2014-09-06 12:31:10