I'm new to Qt and QML. I want to show my list using combobox with the QStringList model. But, it doesn't work at all. Below is the related source code.
ListModelResourceManager.hpp
class ListModelResourceManager : public QObject {
Q_OBJECT
Q_PROPERTY(QStringList model MEMBER m_model NOTIFY modelChanged)
QStringList m_model;
public:
ListModelResourceManager(const QString& ctx_id, const QQmlApplicationEngine& engine, QObject* parent = nullptr);
public slots:
void update();
signals:
void modelChanged();
};
main.cpp
...
ListModelResourceManager lmResourceManager("MODEL_ResourceManagerList", engine);
...
engine.load(QUrl(QStringLiteral("qrc:/viewmain.qml")));
viewmain.qml
ComboBox {
id: idResourceList
height: 30
visible: true
//model: ["First", "Second", "Third"] // IT WORKS well!!!
model : MODEL_ResourceManagerList.model
onFocusChanged: {
MODEL_ResourceManagerList.update();
}
delegate: ItemDelegate {
width: parent.width
text: modelData
font.weight: idResourceList.currentIndex === index ? Font.DemiBold : Font.Normal
font.pixelSize: 30
highlighted: idResourceList.highlightedIndex == index
}
when using commented model definition ( model: ["First", "Second", "Third"] ) it works well.
please let me know what's wrong in my code part. thanks
I found my bug, so I replied to my answer by myself.
To register model to view components, the registering object must be the model type class. In my case, my ListModelResourceManager is not model class. so need to use QStringListModel as a model class than link this QStringListModel object to QML Combobox components.
I updated my working source here for someone who feel pain like me
ListModelResourceManager.hpp (managing QStringListMoel)
class ListModelResourceManager : public QObject {
Q_OBJECT
QStringListModel m_model;
public:
ListModelResourceManager(const QString& model_id, const QString& ctx_id, const QQmlApplicationEngine& engine, QObject* parent = nullptr);
};
ListModelResourceManager.cpp (m_model is updated by callback function registered to native resource manager)
ListModelResourceManager::ListModelResourceManager(const QString& model_id, const QString& ctx_id, const QQmlApplicationEngine& engine, QObject* parent)
: QObject(parent), m_model()
{
engine.rootContext()->setContextProperty(ctx_id, this);
engine.rootContext()->setContextProperty(model_id, &m_model);
rutResource::ResourceManager::getInstance().addResourceUpdatedListener([this](){
auto resources = rutResource::ResourceManager::getInstance().resources();
QStringList list;
for (auto item : resources)
{
list.append(QString::fromUtf8(item.first.c_str()));
}
m_model.setStringList(list);
});
}
main.cpp
int main(int argc, char *argv[])
{
// ...
ListModelResourceManager lmResourceManager("MODEL_Resources","ResourceManagerList", engine);
// ...
}
view.qml
// ...
ComboBox {
id : idResourceSelector
model : MODEL_Resources
textRole: "display"
}
// ...
ps. I want to separate my native resource manager from QT interface, so I use the callback listener. If it is not your case, you can update your model by using other method like signal/slot etc...