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

Getting the Value of a Enum Name from QML



  • Hello,

    I use a self-declared QAbstractListModel on which I add Objects to it with initialized Base values. To change the Values or set Values not initialized on start I override the setData Function.

    This all works fine but I to Change a Property I need int of the Role I want to Change. So I wonder if there is a way to get the integer of the role by its name to use it in the setData Function. At the Moment if change a Property of an Item I call something like:

    MovieClientModel.setData(MovieClientModel.index(row, 0), "New Value", 256);
    

    where 256 is the Integer of the Role in the Enum. Is there a way to access the Integer of the Enum by its name from QML?



  • @Throndar Hi, you probably need to implement method QAbstractListModel::rolesNames() in your model.

    //.cpp
    QHash<int, QByteArray> MyModel::roleNames() const
    {
        QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
        roles[MyRole1] = "role1";
        roles[MyRole2] = "role2";
        return roles;
    }
    

    Then you can use

    MovieClientModel.setData(MovieClientModel.index(row, 0), "New Value", "role1");
    


  • @Throndar you may want to take a look at this post, as it may give you an idea of using C++ stuff in QML by registering the class(es)



  • Hello @Gojir4 ,

    I am a little bit confused, I allready use the "roleNames()" Function (cut to only a few Values): (added the= QAbstractListModel::rolesNames() which I didn't have in my Function

    QHash<int, QByteArray> MovieClientModel::roleNames() const
    {
        QHash<int, QByteArray> roles  = QAbstractListModel::roleNames();
        roles[NameRole] = "name";
        roles[AddressRole] = "address";
        roles[VersionRole] = "version";
        roles[PortRole] = "port";
        return roles;
    }
    

    but when I trie to use

    MovieClientModel.setData(MovieClientModel.index(row, 0), "new Value", "name");
    

    the Property don't get set (like if I use the integer of the Enum).

    To be sure the setData isn't wrong:

    bool MovieClientModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if(!hasIndex(index.row(), index.column(), index.parent()) || !value.isValid())
                return false;
    
        MovieClient &movieClient = m_movieClients[index.row()];
        if(role == NameRole)
            movieClient.setName(value.toString());
        else if(role == AddressRole)
            movieClient.setAddress(value.toString());
    
        emit dataChanged(index, index, {role});
        return true;
    }
    

    But the setData only works with the Integer, on the name of the Role it didn't switch



  • @Throndar You are right, my bad, so in this case the solution from @Pablo-J-Rogina seems better.

    But I'm not sure why you need to call setData from your code. Usually it is called by the model itself to handle data modification from a view.
    From the delegate, you should be able to set the new value with something like:

    name = "new value"
    //or
    styleData.name = "new value"
    


  • @Throndar
    You already got the answer to that in your other post
    https://forum.qt.io/topic/94461/access-list-of-objects-in-qml/8

    The C++ enum item NameRole is not directly accessible in QML: You must register it using the Q_ENUM macro, but this requires you to register the MoveClientModel type too.
    http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#enumeration-types
    When you do all the above, you can access the data as:
    console.log(movieClientModel.data(movieClientModel.index(0,0), MovieClientModel.NameRole))

    So:

    1. You need to use the Q_ENUM macro
      http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#enumeration-types
    2. You must register your class MovieClientModel
      http://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterType

    Then, you can access the enum value in QML as e.g.

    MovieClientModel.NameRole
    

    And use that in your setData() function.



  • Hello @Pablo-J.-Rogina,

    thank you very much. It works perfectly now.



  • Hello @Diracsbracket ,

    thank you for your help, I really appreciate you helping me again.


Log in to reply