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

QML ComboBox and a C++ enum list



  • Hi guys,

    I keep bumping into a problem of using QML ComboBox to choose an option from a list of enum values provided by C++ backend. Since I'm sort of new to QML this might be a stupid question, however I haven't found an acceptable answer anywhere yet.

    Suppose there is a C++ class that exposes a property

    Q_PROPERTY(Color color READ color WRITE setColor NOTIFY colorChanged)
    

    Color is an enum defined by the class

    enum class Color {
        Red,
        Green,
        Blue,
    };
    

    And the class provides a list of currently available options to choose from - the list can contain all the defined enum values or even none. There is a corresponding "changed" signal as well.

    QList<Color> availableColors() const;
    signals:
    void availableColorsChanged(QList<Color>);
    

    All this is basic stuff on C++ side. But now I need a QML ComboBox in the user interface that would list translatable names of all currently available colors and that would set the "color" property based on user input.

    I have tried several approaches so far (wrapping Color enum in a class to provide the list as QList<QObject*>, using models with named roles, using strings instead of enum values, ...) but all of them require a lot of boilerplate code and/or feel hackish.

    What is the "right" way to handle this?


  • Qt Champions 2017

    If you want translatable color name, you need to implement your own logic. It can be either in C++ or QML. You need to write the boiler plate code.

    Instead of exposing the color enums, can you expose color names itself ?


  • Qt Champions 2018

    You could get the string representations of your enums by using QMetaObject and QMetaEnum.
    There's no such thing existing out of the box though, you would have to implement a C++ helper accessible in QML.



  • @dheerendra said in QML ComboBox and a C++ enum list:

    If you want translatable color name, you need to implement your own logic. It can be either in C++ or QML. You need to write the boiler plate code.

    Of course, translation logic has to exist. My idea would be to put it somewhere in the QML frontend as close to the combo itself as possible so the values are expressed as enums everywhere and the program doesn't have to shuffle strings around (making it more efficient and easier to maintain).
    Something like using a following model for the combo:

    ListModel {
        ListElement { text: qsTr("Red") value: Color.Red }
        ListElement { text: qsTr("Green") value: Color.Green }
        ListElement { text: qsTr("Blue") value: Color.Blue }
    }
    

    However I haven't found an easy way to remove unavailable options from a model like this.

    @dheerendra said in QML ComboBox and a C++ enum list:

    Instead of exposing the color enums, can you expose color names itself ?

    Exposing names themselves would mean using hard-to-maintain strings instead of simple enum values. The code is more clear if you use Color.Red instead of "red". Also if classes' color parameter is used by other C++ code as well, it would be necessary to duplicate setter and getter functions (one set with enums and second with strings).

    @GrecKo said in QML ComboBox and a C++ enum list:

    You could get the string representations of your enums by using QMetaObject and QMetaEnum.
    There's no such thing existing out of the box though, you would have to implement a C++ helper accessible in QML.

    That is possible, however you get untranslated strings only. So you basically have to convert
    enum <---> untranslated string <---> translated string
    which feels a bit clumsy.


Log in to reply