Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Using C++ Models with Qt Quick Views not working



  • Hello,

    I have customtype as a model for qml.
    Registering on Qt side is working.
    But the data isn't shown in QML.
    This is the QML:

    import QtQuick 2.8
    import QtQuick.Controls 2.3
    import QtQuick.Window 2.2
    import com.powertune 2.0
    import QtQuick.Extras 1.4
    
    ApplicationWindow  {
        visible: true
        width: 800
        height: 480
        minimumWidth: 800
        minimumHeight: 480
        title: qsTr("PowerTune 2.0")
        color: "grey"
    
    
        ListView {
            width: 100; height: 100
    
            model: qmlDataSourceModel
            delegate: Rectangle {
                height: 25
                width: 100
                Text { text: name }
            }
        }
    }
    

    Here it is registered:

    #include "connect.h"
    #include "updreceiver.h"
    #include "datasourceobject.h"
    #include <QDebug>
    #include <QQmlContext>
    #include <QQmlApplicationEngine>
    #include <QQmlEngine>
    
    
    Connect::Connect(QObject *parent) : QObject(parent)
    {
    
    
         m_UpdReceiver = new UpdReceiver();
        //this Object contains all datasources as Object! Definition in datasourceobject.h!
        auto m_datasourcelist = m_UpdReceiver->initDataSources();
    
    
        //Create connection to QML Application
        QQmlApplicationEngine *engine = dynamic_cast<QQmlApplicationEngine*>( parent );
        if (engine == Q_NULLPTR) return;
        //Link m_datasourcelist to Model on QML side
        qmlRegisterType<DataSourceObject>("com.powertune", 2 , 0, "dataSourceModelObject");
        engine->rootContext()->setContextProperty("qmlDataSourceModel", QVariant::fromValue(m_datasourcelist));
    
        //m_UpdReceiver starts now to listen to incoming UDP packages
        m_UpdReceiver->startUdpReceiver();
    
    }
    

    And this the class for the model:

    #ifndef DATASOURCEOBJECT_H
    #define DATASOURCEOBJECT_H
    
    #include <QObject>
    
    //![0]
    class DataSourceObject : public QObject
    {
        Q_OBJECT
    
        Q_PROPERTY(int id READ id WRITE setid NOTIFY idChanged)
        Q_PROPERTY(QString name READ name WRITE setname NOTIFY nameChanged)
        Q_PROPERTY(QString displayname READ displayname WRITE setdisplayname NOTIFY displaynameChanged)
    //![0]
    public:
    
        //Constructors and destructors
        DataSourceObject(QObject *parent=nullptr);
        DataSourceObject(const int &id, const QString &name, const QString &displayname, QObject *parent=nullptr);
        DataSourceObject(const DataSourceObject&); //copy constructor
        ~DataSourceObject()=default;
    
    
        int id() const;
        void setid(const int &id);
    
        QString name() const;
        void setname(const QString &name);
    
        QString displayname() const;
        void setdisplayname(const QString &displayname);
    
    signals:
    
        void idChanged();
        void nameChanged();
        void displaynameChanged();
    
    private:
    
        int m_id;
        QString m_name;
        QString m_displayname;
    //![1]
    };
    //![1]
    Q_DECLARE_METATYPE(DataSourceObject)
    
    
    #endif // DATASOURCEOBJECT_H
    
    

    Debugging shows that m_datasourcelist has 8 *QObjects, so data is available.
    Output shows no errors


  • Moderators

    @Slash200
    http://doc.qt.io/qt-5/qqmllistproperty.html

    The QQmlListProperty class allows applications to expose list-like properties of QObject-derived classes to QML.



  • @raven-worx
    I'm coming from this manual:
    http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html
    So this is no the correct way to do it?


  • Moderators

    @Slash200 said in QObjectList-based Model not working:

    Rectangle {
    height: 25
    width: 100
    color: "black"
    Text { text: name }
    }

    may it be possible that you show black text on black background? :)



  • @raven-worx
    No, I changed the color and there is also nothing visible



  • @raven-worx
    I found out, when I add items to the QList directly in the class that has engine->rootContext()->setContextProperty("qmlDataSourceModel", QVariant::fromValue(m_datasourcelist)); in it, it's working.

    But in my code the QList is "filled" with QObjects* that are returned from class m_UpdReceiver.

    Any Ideas how to solve this?



  • @Slash200 Hi,

    I guess you have followed the QObjectList based model, which is not really a good one. Did you notify the note at the end which say "Note: There is no way for the view to know that the contents of a QList has changed. If the QList changes, it is necessary to reset the model by calling QQmlContext::setContextProperty() again." ?

    This means that when using this kind of "model", you need to recall QQmlContext::setContextProperty() each time your list as changed, otherwise you will not see the changes on the QML side.

    I would recommend to follow the QAbstractItemModel Subclass to make your model. This also offers the advantage that you can eventually remove inheritance from QObject with your class DataSourceObject, which is, in my opinion, a better architecture. Try to avoid as much as possible to use list of QObject* to store data.



  • Hello,

    I solved the problem by changing the type QList from <datasourceobject*> to <QObject*>
    Thank you very much for your help!


Log in to reply