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

How to access dynamic role in qml listview?



  • Hi.
    In my application, I can send my Query from my database class to my Model class and run the query. but I can't get the role to show fields in my listview.
    this is my model class :

    #ifndef MYMODEL_H
    #define MYMODEL_H
    #include <QSqlQueryModel>
    #include <QSqlRecord>
    #include <QSqlField>
    #include "db.h"
    
    class MyModel : public QSqlQueryModel
    {
        Q_OBJECT
    public:
        explicit MyModel(QObject *parent = nullptr);
        QStringList userRoleNames() const {
              QStringList names;
               for (int i = 0; i < record().count(); i ++) {
                   names << record().fieldName(i).toUtf8();
               }
               return names;
           }
       //my function
        void setQuerystr(const QString &query);
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
        QHash<int , QByteArray>roleNames() const override{
            return m_roleNames;
        }
    public:
        void generateRoleNames();
        QHash<int , QByteArray> m_roleNames;
        DB db;
    };
    
    #endif // MYMODEL_H
    //==============================================================
     #include "mymodel.h"
    
    MyModel::MyModel(QObject *parent)
        : QSqlQueryModel(parent)
    {
    
    }
    
    void MyModel::setQuerystr(const QString &query)
    {
    
        QSqlQueryModel::setQuery(query,QSqlDatabase::database("MainDB"));
        generateRoleNames();
    }
    
    QVariant MyModel::data(const QModelIndex &index, int role) const
    {
        //    QVariant value;
        //    if (role<Qt::UserRole) {
        //        value = QSqlQueryModel::data(index,role);
        //    }
        //    else
        //    {
        //        int columnIdx = role - Qt::UserRole -1;
        //        QModelIndex modelindex = this->index(index.row(),columnIdx);
        //        value = QSqlQueryModel ::data(modelindex,Qt::DisplayRole);
        //    }
        //
        QVariant value;
        if (index.isValid()) {
            if (role < Qt::UserRole) {
                value = QSqlQueryModel::data(index, role);
            } else {
                int columnIdx = role - Qt::UserRole - 1;
                QModelIndex modelIndex = this->index(index.row(), columnIdx);
                value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
            }
        }
        return value;
    }
    void MyModel::generateRoleNames()
    {
        m_roleNames.clear();
    //    for (int i = 0; i < record().count(); ++i)
    //    {
    //        m_roleNames.insert(Qt::UserRole+1,record().fieldName(i).toUtf8());
    //    }
                for (int i = 0; i < this->record().count(); i ++) {
                    m_roleNames.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
               }
    }
    

    as you see I create dynamic roles. I want to show my query output to my list view :

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    import QtQuick.Controls 2.2
    import QtQuick.Controls.Material 2.2
    import QtQuick.VirtualKeyboard 2.1
    import io.myqt.UserManage 1.0
    import MyModel 1.0
    
    CustomeBackground {
        id:mngusr
        property StackView view
        UserManage{id:um}
        Component.onCompleted: myModel.updateModel();
        MyModel{id:myModel}
        MyButton {
            id:btnclose
            height: 45
            anchors.left: parent.left
            anchors.leftMargin: 575
            anchors.top: parent.top
            anchors.topMargin: 0
            txt: qsTr("X")
            fontsize: 20
           anchors.right: parent.right
            anchors.bottom: swipeView.top
            onClicked: {
                if(view.depth==1)
                {
                    mngusr.view.pop();
                    view.visible=false;
                }
                else
                    mngusr.view.pop();
            }
        }
        Pane{
            id: pane
           width: 400
            height: 400
            anchors.right: parent.right
            anchors.rightMargin: 2
            anchors.left: parent.left
            anchors.leftMargin: 2
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 317
            anchors.top: btnclose.bottom
            anchors.topMargin: 0
            RowLayout {
                x: -12
                y: 0
                width: 716
                height: 76
               
                MyLable
                {
                    id:lbl
                    Layout.preferredHeight: 30
                    Layout.preferredWidth: 100
                    Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
                    //                anchors.rightMargin: 2
                    txt : qsTr(" Personel ID :")
                }
               
               MyTextField{
                    id:mytxt
                    Layout.preferredHeight: 40
                    Layout.preferredWidth: 70
                    clip: true
                    Layout.maximumHeight: 40
                    Layout.maximumWidth: 200
                    hint: qsTr("Insert the personel id for search...")
               }
                MyButton{
                    id:btnsearch
                    txt:qsTr("SEARCH")
                    onClicked:
                    {
                        if(mytxt.text.length===0)
                            um.fillTableView(-1);
                        else
                            um.fillTableView(mytxt.text);
                        mylistView.model=myModel;
                    }
                }
            }
        }
        
       Frame{
            x: 21
            y: 162
            ListView{
            id:mylistView
            implicitHeight: 250
            implicitWidth: 250
            model: myModel
            resources:{
                        var roleList = myModel.userRoleNames
                        var temp = []
                        for(var i in roleList){
                           var role  = roleList[i]
                            temp.push(columnComponent.createObject(view, { "role": role, "title": role}))
                        }
                        return temp
            }
    //        delegate: RowLayout{
    //            width: parent.width
    //            TextField {
    //                //Layout.width: 100
    //                id: name
    //                text: card
    //            }
    
    //        }
        }
    }  
    }
    

    my main question is how to access the roles that create dynamically in Model class?



  • Based on this tutorial, you can simply use the names of your sql fields

    select id, name, city FROM employees
    

    delegate.qml

    Row {
            anchors.margins: 4
            anchors.fill: parent
            spacing: 4;
            Text {
                text: name
                width: 150
            }
            Text {
                text: city
                width: 150;
            }
    }
    

    https://wiki.qt.io/How_to_Use_a_QSqlQueryModel_in_QML



  • Hi @JoZCaVaLLo and thanks to answering, but I do that but nothing to show:

    Frame{
            x: 21
            y: 162
            ListView{
            id:mylistView
            implicitHeight: 250
            implicitWidth: 250
            model: myModel
    //        resources:{
    //                    var roleList = myModel.userRoleNames
    //                    var temp = []
    //                    for(var i in roleList){
    //                        var role  = roleList[i]
    //                        temp.push(columnComponent.createObject(view, { "role": role, "title": role}))
    //                    }
    //                    return temp
    //        }
            delegate: RowLayout{
                width: parent.width
                TextField {
                    //Layout.width: 100
                    id: name
                    text: UI_Active
                    width : 20
                }
                TextField {
                    //Layout.width: 100
                    id: name2
                    text: UI_PID
                    width : 20
                }
            }
        }
    }
    

Log in to reply