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

Accessing delegates in QML from C++



  • I am trying to access the delegate component of the listview in C++ and want to alter it. Like in the code below, I am using QAbstractListModel to provide model to the listview and i have a delegate defined inside the listview which takes two String properties.

    Now, at runtime i want to add another property to it from C++, based on the upper layer request. For eg: If i get a request to show 2 textfield along with an imageview in the delegate, in that case i have already two String properties but i dont have an imageview properties inside the delegate. Since, i do not know what exact request will come, i want to add the properties inside the delegate from C++. But i am not sure how to do it.

    Any help/suggestion will be appreciated. Below are the code snippet.

    listviewComponent.qml

    ListView {
       required model
    
        delegate: Text {
            required property string type
            required property string size
    
            text: type + ", " + size
            }
    }
    

    Model.h

    class Model
    {
    public:
        Model(const QString& type, const QString& size);
    
        QString type() const;
        QString size() const;
    
    private:
        QString m_type;
        QString m_size;
    };
    
    class CustomModel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        enum Roles {
            TypeRole = Qt::UserRole + 1,
            SizeRole
        };
    
        CustomModel(QObject* parent = 0);
    
        void addElement(const Model& pElement);
    
        int rowCount(const QModelIndex& parent = QModelIndex()) const;
    
        QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
    
    protected:
        QHash<int, QByteArray> roleNames() const;
    private:
        QList<Model> m_list;
    };
    

    Model.cpp

    Model::Model(const QString& type, const QString& size)
        : m_type(type), m_size(size)
    {
    }
    
    QString Model::type() const
    {
        return m_type;
    }
    
    QString Model::size() const
    {
        return m_size;
    }
    
    CustomModel::CustomModel(QObject* parent)
        : QAbstractListModel(parent)
    {
    }
    
    void CustomModel::addElement(const Model &pElement)
    {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_list << pElement;
        endInsertRows();
    }
    
    int CustomModel::rowCount(const QModelIndex& parent) const {
        Q_UNUSED(parent);
        return m_list.count();
    }
    
    QVariant CustomModel::data(const QModelIndex& index, int role) const {
        if (index.row() < 0 || index.row() >= m_list.count())
            return QVariant();
    
        const Model& mod = m_list[index.row()];
        if (role == TypeRole)
            return mod.type();
        else if (role == SizeRole)
            return mod.size();
        return QVariant();
    }
    
    QHash<int, QByteArray> CustomModel::roleNames() const {
        QHash<int, QByteArray> roles;
        roles[TypeRole] = "type";
        roles[SizeRole] = "size";
        return roles;
    }
    

    Myclass.h

    class myclass : public QObject
    {
        Q_OBJECT
    public:
        myclass();
    
        inline int createUI(QQmlApplicationEngine &engine){
            QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().at(0));
            if (!window) {
                qFatal("Error: Your root item has to be a window.");
                return -1;
            }
    
            QQuickItem *root = window->contentItem();
    
            window->setWidth(600);
            window->setHeight(500);
    
            QQmlComponent listviewComp(&engine, QUrl(QStringLiteral("qrc:/listviewComponent.qml")));
           
            CustomModel model = new CustomModel(window);
            model.addElement(Model("Wolf", "Medium"));
            model.addElement(Model("Polar bear", "Large"));
            model.addElement(Model("Quoll", "Small"));
    
            QQuickItem *listview = qobject_cast<QQuickItem*>(listviewComp.createWithInitialProperties({ {"model", QVariant::fromValue(&model)} }));
            QQmlEngine::setObjectOwnership(listview, QQmlEngine::CppOwnership);
            listview->setParentItem(root);
            listview->setParent(&engine);
            listview->setProperty("objectName", "lv");
            listview->setWidth(200);
            listview->setHeight(100);
            listview->setX(250);
            listview->setY(30);
     
           window->show();
    
            return 0;
    }
    };
    

    main.cpp

    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        engine.load(url);
    
        QQmlContext *item = engine.rootContext();
        myclass myClass;
        item->setContextProperty("_myClass", &myClass);
    
        myClass.createUI(engine);
    
        return app.exec();
    }
    

Log in to reply