Access `QMap<K,V>` "where V QObject` from qml
-
I have a fairly basic Hello World Qt Quick Application (Qt+Qml) at:
https://github.com/paulpv/QtQmlHelloQVariantMap/In it I am trying to [learn how to] expose a
QMap<K,V>to qml (read-only is fine for now).
My end-goal is to expose aQMap<int, HotkeyInfo>, where HotkeyInfo is defined as:class HotkeyInfo : public QObject { Q_OBJECT ... Q_PROPERTY(QString computerName MEMBER m_computerName) Q_PROPERTY(QString appName MEMBER m_appName) ... private: QString m_computerName; QString m_appName; }; using MapHotkeys = QMap<QString, QVariant>; class HotkeyManager : public QObject { Q_OBJECT ... Q_PROPERTY(MapHotkeys hotkeys MEMBER m_hotkeys) void add(const int key, HotkeyInfo* hotkeyInfo) { m_hotkeys[QString::number(key)] = QVariant::fromValue(hotkeyInfo); } void remove(const int key) { auto hotkeyInfo = m_hotkeys.take(QString::number(key)).value<HotkeyInfo*>(); if (hotkeyInfo != nullptr) { delete hotkeyInfo; } } ... private: MapHotkeys m_hotkeys; }I populate the Map with:
void initializeMessages(HotkeyManager& hotkeyManager) { // Ignore NewDeleteLeaks; ~HotkeyManager frees all added HotkeyInfos. hotkeyManager.add(1, new HotkeyInfo("computer1", "app2")); hotkeyManager.add(2, new HotkeyInfo("computer2", "app4")); }Qml code to read the HotkeyInfo properties...
import QtQuick import QtQuick.Window ApplicationWindow { width: 640 height: 480 visible: true title: qsTr("Hello World") Component.onCompleted: { console.log(`Component.onCompleted`) console.log(`hotkeyManager=${hotkeyManager}`) var hotkeys = hotkeyManager.hotkeys console.log(`hotkeys=${hotkeys}`) var hotkeyInfo1 = hotkeys[1] console.log(`hotkeyInfo1=${hotkeyInfo1}`) console.log(`hotkeyInfo1.computerName=${hotkeyInfo1.computerName}`) console.log(`hotkeyInfo1.appName=${hotkeyInfo1.appName}`) var hotkeyInfo2 = hotkeys[2] console.log(`hotkeyInfo2=${hotkeyInfo2}`) console.log(`hotkeyInfo2.computerName=${hotkeyInfo2.computerName}`) console.log(`hotkeyInfo2.appName=${hotkeyInfo2.appName}`) } }My qml can see properties of the
HotkeyInfoclass just fine if I useQMap<String,QVariant>and convert the key to and from anintand values to and fromHotkeyInfo*.qml: Component.onCompleted qml: hotkeyManager=HotkeyManager(0x930095fb78) qml: hotkeys=[object Object] qml: hotkeyInfo1=HotkeyInfo(0x263748f66a0) qml: hotkeyInfo1.computerName=computer1 qml: hotkeyInfo1.appName=app2 qml: hotkeyInfo2=HotkeyInfo(0x263748f6520) qml: hotkeyInfo2.computerName=computer2 qml: hotkeyInfo2.appName=app4I am naive enough to think that I should not have to add extra code to convert to/from key and value types, and/or think that doing that means I might be doing something wrong; I would like to remove that extra code.
If I just change the map to
QMap<QString,HotkeyInfo*>then it can no longer access the map entries (ie: "stops working")qml: Component.onCompleted qml: hotkeyManager=HotkeyManager(0x16e5cff978) qml: hotkeys=QVariant(QMap<QString,HotkeyInfo*>, QMap(("1", HotkeyInfo(0x1b975ff7800))("2", HotkeyInfo(0x1b975ff8500)))) qml: hotkeyInfo1=undefined qrc:/qt/qml/QtQmlHelloQVariantMap/Main.qml:21: TypeError: Cannot read property 'computerName' of undefinedNOTE that the debug output still shows it knows the object types well enough to
toString()them.If I just change the map to
QMap<int,QVariant>then strangely also stops working.qml: Component.onCompleted qml: hotkeyManager=HotkeyManager(0x22c22ff618) qml: hotkeys=QVariant(QMap<int,QVariant>, QMap((1, QVariant(HotkeyInfo*, 0x1314e128ac0))(2, QVariant(HotkeyInfo*, 0x1314e1294c0)))) qml: hotkeyInfo1=undefined qrc:/qt/qml/QtQmlHelloQVariantMap/Main.qml:21: TypeError: Cannot read property 'computerName' of undefinedInterestingly, the qml code has no problem accessing the working
QMap<String,QVariant>values using anintkey; something seems to auto-convert that to a string.
It seems odd that anintkey does not work on aQMap<int,QVariant>, but anintkey does work on aQMap<String,QVariant>.If I change the map to
QMap<int,HotkeyInfo*>then it obviously also stops working.qml: Component.onCompleted qml: hotkeyManager=HotkeyManager(0xf7969afb58) qml: hotkeys=QVariant(QMap<int,HotkeyInfo*>, QMap((1, HotkeyInfo(0x2a033aeaab0))(2, HotkeyInfo(0x2a033ae8cb0)))) qml: hotkeyInfo1=undefined qrc:/qt/qml/QtQmlHelloQVariantMap/Main.qml:21: TypeError: Cannot read property 'computerName' of undefinedCan anyone suggest how to accomplish reading a
QMap<?,QObject>from qml?AI chatbots seem useless on this.
Thanks!
Pv