Qt QML डेटा मॉडल C++ के साथ काम करने के लिए नहीं लगता



model-view-controller datamodel (1)

यह पता चला है कि एक बहुत ही सरल कारण है कि cppModel की count संपत्ति उपलब्ध नहीं है - ऐसा इसलिए है क्योंकि न तो QAbstractListModel और न ही QList<> एक count संपत्ति है!

मैंने यह मान लिया था कि एक ListModel को एक सी ++ आधारित ऑब्जेक्ट के साथ प्रतिस्थापित किया जा सकता है जैसे कि QList <> इसका मतलब था कि वे बहुरूपक थे और एक सूचीदृश्य या पथव्यू एक count संपत्ति का उपयोग सही ढंग से उन्हें संभालना होगा

सबसे पहले, न तो QAbstractListModel और न ही QList<> एक ListModel साथ बहुरूप हैं। यह पता चला है कि वे सभी केवल विशेष-स्थिति वाले हैं - एक ListView जानता है कि इसमें एक ListModel या QList<> या एक QAbstractListModel और प्रत्येक का उपयोग करने के लिए अलग कोड पथ हैं ListView को QList<> या QList<> प्रबंधित करने के लिए कोई भी count संपत्ति की आवश्यकता नहीं है। वास्तव में, यह मुझे स्पष्ट नहीं है कि ListView और PathView भी ListModel की count संपत्ति का उपयोग करें count संपत्ति ज्यादातर QML प्रोग्रामर के लाभ के लिए प्रतीत होती है। मेरे उदाहरण में, मैं PathView में Path ऑब्जेक्ट बनाने के लिए count गुण का उपयोग कर रहा था। मेरा उदाहरण पूरी तरह से काम करता है अगर मैं इसके बजाय एक length प्रॉपर्टी का उपयोग करता हूं क्योंकि QList<> length संपत्ति होती है

ब्लैक और टॉइसर के लिए धन्यवाद इस पर मुझे मदद करने के लिए # क्यूटी-क्यूएमएल पर (इस जवाब को पोस्ट करके स्टैकवर्फरफ्लो पॉइंट्स एकत्र नहीं करना चाहते थे, इसलिए मैं इसे समुदाय के लाभ के लिए पोस्ट कर रहा हूं)।

मैं http://doc.qt.digia.com/4.7/qdeclarativemodels.html में उदाहरणों के साथ काम कर रहा हूं जो QML घोषणात्मक डेटा मॉडल पर क्यूटी पेज है। विशेष रूप से, मैं objectlistmodel उदाहरण के साथ काम कर रहा हूं जो क्यूटी एसडीके (उदाहरण / घोषणात्मक / मॉडल दृश्य / वस्तुसूची मॉडल में) के साथ आता है। यह सब ठीक से काम करने लगता है, जब तक कि मैं इसे http://www.developer.nokia.com/Community/Wiki/How_to_create_a_Page_Control_component_in_QML पर QMLPageControl उदाहरण के साथ संयोजित करने का प्रयास नहीं करता।

जब मैं QML- आधारित लिस्ट मॉडेल (QML लिस्टइलेमेंट्स के साथ आबादी) को एक QML ListView के साथ प्रदर्शित करने का प्रयास करता हूं:

import QtQuick 1.0

Rectangle {
   width: 200; height: 200

   ListModel {
       id: qmlModel
       ListElement { name: "qml entry1 (red)"; colour: "red" }
       ListElement { name: "qml entry2 (orange)"; colour: "orange" }
       ListElement { name: "qml entry3 (yellow)"; colour: "yellow" }
       ListElement { name: "qml entry4 (green)"; colour: "green" }
       ListElement { name: "qml entry5 (blue)"; colour: "blue" }
       ListElement { name: "qml entry6 (purple)"; colour: "purple" }
   }


   ListView {

       id: list_view

       anchors.fill: parent
       model: qmlModel
       delegate: Rectangle {
           height: 20
           width: 200
           color: colour
           Text { text: name }

       }
    }
}

... सब कुछ बहुत अच्छी तरह से काम करता है यह पूरी तरह से अपेक्षित काम करता है - एक विंडो बैंड के रंगीन पृष्ठभूमि में कुछ पाठ के साथ फ़ैशन करती है।

फिर, मैं थोड़ा और अधिक जटिल कर सकता हूं, जैसे कि पथव्यू का उपयोग करें:

import QtQuick 1.0

Rectangle {
    width: 200; height: 200

    ListModel {
        id: qmlModel
        ListElement { name: "qml entry1 (red)"; colour: "red" }
        ListElement { name: "qml entry2 (orange)"; colour: "orange" }
        ListElement { name: "qml entry3 (yellow)"; colour: "yellow" }
        ListElement { name: "qml entry4 (green)"; colour: "green" }
        ListElement { name: "qml entry5 (blue)"; colour: "blue" }
        ListElement { name: "qml entry6 (purple)"; colour: "purple" }
    }


    //       ListView {
    //           id: list_view
    //           anchors.fill: parent
    //           model: qmlModel
    //           delegate: Rectangle {
    //               height: 20
    //               width: 200
    //               color: colour
    //               Text { text: name }
    //           }
    //       }

    PathView {
        id: my_path_view

        anchors.fill: parent

        Keys.onRightPressed: if (!moving && interactive) incrementCurrentIndex()
        Keys.onLeftPressed: if (!moving && interactive) decrementCurrentIndex()

        flickDeceleration: 500

        preferredHighlightBegin: 0.5
        preferredHighlightEnd: 0.5
        focus: true
        interactive: true
        model: qmlModel

        delegate: Rectangle {
            width: 100
            height: 100
            color: colour
            Text {
                anchors.centerIn: parent
                text: name
            }
        }


        path: Path {
            startX: - my_path_view.width * my_path_view.model.count / 2 + my_path_view.width / 2
            startY: my_path_view.height / 2
            PathLine {
                x: my_path_view.width * my_path_view.model.count / 2 + my_path_view.width / 2
                y: my_path_view.height / 2
            }
        }
    }
}

फिर से, यह सब अपेक्षित काम करता है - एक खिड़की रंगीन बक्से की एक झीझने योग्य, ड्रैगनीय सूची के साथ चली जाती है।

बैक अप, मैं उसके बाद सी ++ में डेटा ऑब्जेक्ट परिभाषित कर सकता हूं:

dataobject.h

#ifndef DATAOBJECT_H
#define DATAOBJECT_H

#include <QObject>

class DataObject : public QObject
{
    Q_OBJECT

    Q_PROPERTY( QString name READ name WRITE setName NOTIFY nameChanged )
    Q_PROPERTY( QString colour READ colour WRITE setColour NOTIFY colourChanged )


public:
    DataObject( QObject * parent = 0 );
    DataObject( const QString &_name, const QString &_color, QObject * parent=0 );

    QString name() const;
    void setName(const QString &);

    QString colour() const;
    void setColour(const QString &);

signals:
    void nameChanged();
    void colourChanged();


private:
    QString m_name;
    QString m_colour;
};


#endif // DATAOBJECT_H

dataobject.cpp

#include "dataobject.h"
#include <QDebug>

DataObject::DataObject( QObject * parent )
    : QObject( parent )
{
    qDebug() << "DataObject::DataObject() has been called.\n";

}

DataObject::DataObject( const QString &_name, const QString &_colour, QObject * parent )
    : QObject( parent )
    , m_name( _name )
    , m_colour( _colour )
{
    qDebug() << "DataObject::DataObject(name, color) has been called.\n";

}


QString DataObject::name() const {
    qDebug() << "name() has been called.\n";
    return m_name;
}

void DataObject::setName(const QString &name) {
    qDebug() << "setName has been called.\n";
    if ( name != m_name ) {
        m_name = name;
        emit nameChanged();
    }
}

QString DataObject::colour() const {
    qDebug() << "colour() has been called.\n";
    return m_colour;
}

void DataObject::setColour(const QString &colour) {
    qDebug() << "setColour has been called.\n";
    if ( colour != m_colour ) {
        m_colour = colour;
        emit colourChanged();
    }
}

और फिर मैं इसे QML संदर्भ में जोड़ता हूं:

#include <QApplication>
#include <QDialog>
#include <QDeclarativeView>
#include <QDeclarativeContext>
#include <QLayout>
#include <QDir>
#include "qmlapplicationviewer.h"
#include "dataobject.h"

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

    QList<QObject*> dataList;
    dataList.append( new DataObject( "c++ entry1 (red)", "red" ) );
    dataList.append( new DataObject( "c++ entry2 (orange)", "orange" ) );
    dataList.append( new DataObject( "c++ entry3 (yellow)", "yellow" ) );
    dataList.append( new DataObject( "c++ entry4 (green)", "green" ) );
    dataList.append( new DataObject( "c++ entry5 (blue)", "blue" ) );
    dataList.append( new DataObject( "c++ entry6 (purple)", "purple" ) );

    QmlApplicationViewer viewer;
    viewer.rootContext()->setContextProperty( "cppModel", QVariant::fromValue(dataList) );
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
#if defined( Q_OS_MAC )
    viewer.setMainQmlFile("../Resources/qml/main.qml");
#elif defined( Q_OS_WIN32 )
    viewer.setMainQmlFile("qml/main.qml");
#else
#error - unknown platform
#endif
    viewer.showExpanded();

    return app.exec();
}

और अंत में, QML में, मैं इस C ++ मॉडल को ListView में जोड़ता हूं:

import QtQuick 1.0

Rectangle {
    width: 200; height: 200

    ListModel {
        id: qmlModel
        ListElement { name: "qml entry1 (red)"; colour: "red" }
        ListElement { name: "qml entry2 (orange)"; colour: "orange" }
        ListElement { name: "qml entry3 (yellow)"; colour: "yellow" }
        ListElement { name: "qml entry4 (green)"; colour: "green" }
        ListElement { name: "qml entry5 (blue)"; colour: "blue" }
        ListElement { name: "qml entry6 (purple)"; colour: "purple" }
    }


           ListView {

               id: list_view

               anchors.fill: parent
               //model: qmlModel
               model: cppModel
               delegate: Rectangle {
                   height: 20
                   width: 200
                   color: colour
                   Text { text: name }

               }
           }

}

एक बार फिर, यह सिर्फ ठीक काम करता है - बैंड में व्यवस्थित रंगीन पृष्ठभूमि के पाठ के साथ एक संवाद प्रकट होता है। एक सी + + मॉडल द्वारा समर्थित सूचीदृश्य प्रदर्शित करना प्रत्येक बिट के साथ-साथ एक QML ListModel द्वारा समर्थित सूचीदृश्य को प्रदर्शित करता है।

मैं क्या काम करना चाहता हूं एक ऐसा सी + + मॉडल है जिस तरह से एक पाथव्यू का समर्थन किया जाता है:

import QtQuick 1.0

Rectangle {
    width: 200; height: 200

    ListModel {
        id: qmlModel
        ListElement { name: "qml entry1 (red)"; colour: "red" }
        ListElement { name: "qml entry2 (orange)"; colour: "orange" }
        ListElement { name: "qml entry3 (yellow)"; colour: "yellow" }
        ListElement { name: "qml entry4 (green)"; colour: "green" }
        ListElement { name: "qml entry5 (blue)"; colour: "blue" }
        ListElement { name: "qml entry6 (purple)"; colour: "purple" }
    }


//    ListView {

//       id: list_view

//       anchors.fill: parent
//       model: qmlModel
//       //model: cppModel
//       delegate: Rectangle {
//           height: 20
//           width: 200
//           color: colour
//           Text { text: name }

//       }
//    }

    PathView {
        id: my_path_view

        anchors.fill: parent

        Keys.onRightPressed: if (!moving && interactive) incrementCurrentIndex()
        Keys.onLeftPressed: if (!moving && interactive) decrementCurrentIndex()

        flickDeceleration: 500

        preferredHighlightBegin: 0.5
        preferredHighlightEnd: 0.5
        focus: true
        interactive: true
        //model: qmlModel
        model: cppModel

        delegate: Rectangle {
            width: 100
            height: 100
            color: colour
            Text {
                anchors.centerIn: parent
                text: name
            }
        }


        path: Path {
            startX: - my_path_view.width * my_path_view.model.count / 2 + my_path_view.width / 2
            startY: my_path_view.height / 2
            PathLine {
                x: my_path_view.width * my_path_view.model.count / 2 + my_path_view.width / 2
                y: my_path_view.height / 2
            }
        }
    }
}

यह काम नहीं करता है मैं जो देख रहा हूं वह रंगीन आयत है, लेकिन उन्हें माउस के साथ बातचीत नहीं की जा सकती है और वे qmlviewer संवाद में केंद्रित नहीं हैं।

और डीबग कंसोल पर मैं यह देखता हूं:

QDeclarativeDebugServer: Waiting for connection on port 3768...
QDeclarativeDebugServer: Connection established
QPainterPath::lineTo: Adding point where x or y is NaN or Inf, ignoring call
QPainterPath::lineTo: Adding point where x or y is NaN or Inf, ignoring call
colour() has been called.

name() has been called.

colour() has been called.

name() has been called.

colour() has been called.

name() has been called.

colour() has been called.

name() has been called.

colour() has been called.

name() has been called.

colour() has been called.

name() has been called.

QPainterPath::lineTo: Adding point where x or y is NaN or Inf, ignoring call
QPainterPath::lineTo: Adding point where x or y is NaN or Inf, ignoring call
QPainterPath::lineTo: Adding point where x or y is NaN or Inf, ignoring call
QPainterPath::lineTo: Adding point where x or y is NaN or Inf, ignoring call
QPainterPath::lineTo: Adding point where x or y is NaN or Inf, ignoring call

ऐसा प्रतीत होता है कि QList की एक मूल आकृति है जो कि एक सूची दृश्य के लिए एक QML ListModel / ListItem संग्रह के लिए पर्याप्त है, लेकिन प्रदर्शित करने के लिए पथव्यू के लिए पर्याप्त नहीं है।

क्या किसी को पता है कि क्या गलत हो सकता है? दुर्भाग्य से क्यूएमएल क्लास दस्तावेज वास्तव में कन्फॉर्मेंट सी ++ स्टैंड-इन लिखने के लक्ष्य के साथ नहीं जुटाए गए हैं उदाहरण के लिए, http://kt-project.org/doc/qt-4.8/qml-pathview.html पर PathView ऑब्जेक्ट दस्तावेज यह नहीं कहता कि इसके मॉडल को किस प्रकार समर्थन की आवश्यकता है इसके अलावा, लिस्टमोडल प्रलेखन निश्चित नहीं है - यह बिल्कुल नहीं बताता है कि सूचीमॉडल का क्या गुण है और कोई स्पष्ट दस्तावेज नहीं है कि किस प्रकार QList उन आवश्यकताओं को ठीक करता है और यह कैसे नहीं करता।

अद्यतनः मैंने विंडोज पर क्यूटी 5 के साथ यह कोशिश की है, और मुझे अभी भी यही समस्या है।





datamodel