Q_ENUMS based model
-
Hello all!
I have faces with the following question: let's suppose that I have Q_ENUMS:
class ColorType{ Q_GADGET public: enum Value { RED_COLOR, GREEN_COLOR, BLUE_COLOR, }; Q_ENUM(Value); static void registerQML() { qmlRegisterUncreatableType<ColorType>("My.Enums", 1, 0, "ColorType", "ColorType"); qRegisterMetaType<ColorType::Value>("ColorType::Value"); } };
In the QML-side I have combobox, where I want to display this enum, but with the "correct" displaying style ("Red", "Green", "Blue"). So corresponding Q_ENUMS values should be connected with the combobox items. What is the most correct (and simple) way to do this?
-
Hello all!
I have faces with the following question: let's suppose that I have Q_ENUMS:
class ColorType{ Q_GADGET public: enum Value { RED_COLOR, GREEN_COLOR, BLUE_COLOR, }; Q_ENUM(Value); static void registerQML() { qmlRegisterUncreatableType<ColorType>("My.Enums", 1, 0, "ColorType", "ColorType"); qRegisterMetaType<ColorType::Value>("ColorType::Value"); } };
In the QML-side I have combobox, where I want to display this enum, but with the "correct" displaying style ("Red", "Green", "Blue"). So corresponding Q_ENUMS values should be connected with the combobox items. What is the most correct (and simple) way to do this?
@St-Stanislav
the most generic way (if you do not want to do static mapping) would most probably be to use QMetaEnum inside a QAbstractListModel and publish it to QML.
Otherwise you simply can use a ListModel and add each list item yourself with it with all custom roles you like. -
Thank you for the reply!
So based on your answer, I have implemented it in the following way:
- Have created
ColorTypeModel
:
class ColorTypeModel : public QAbstractListModel { enum { ColorTypeIDRole = Qt::UserRole, ColorTypeNameRole };
- Have made it singleton:
public: static ColorTypeModel& Instance() { static ColorTypeModel colorTypeModel; return colorTypeModel; } virtual ~ColorTypeModel() {} private: explicit ColorTypeModel(QObject *parent = nullptr);
- Have added
QStringList
and staticQMap
anyway:
private: QStringList m_data; static QMap<ColorType::Value, QString> m_namesMap;
- Then I have implemented
fillModel()
method and call it in the model's constructor:
void ColorTypeModel::fillModel() { m_data.clear(); const QMetaEnum metaEnum = QMetaEnum::fromType<ColorType::Value>(); assert((m_namesMap.size() == metaEnum.keyCount()) && "ColorTypeModel map should be filled with names for the every enum item!"); for (int i = 0; i < metaEnum.keyCount(); ++i) { m_data.append(ColorTypeModel::m_namesMap.value(static_cast<ColorType::Value>(metaEnum.value(i)))); } }
- Have implemented in my backend class (which is set as
ContextPropery
) method to publish it to QML:
QVariant Backend::getColorTypeModel() const { return QVariant::fromValue(&ColorTypeModel::Instance()); }
- Have created
ComboBox
in QML and connect with the aforementioned model:
ComboBox { textRole: "colorTypeName" valueRole: "colorTypeID" model: backend.getColorTypeModel() }
Everything works well! So here is my question: is my approach correct (and match with the described one in your reply)? And can it be simplified somewhere?
- Have created