1

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

2
  • I set context property in my constructor. ex) engine.rootContext()->setContextProperty(ctx_id, this); and I already said that it works fine. Commented May 15, 2020 at 2:42
  • One more thing : check using the debugger in method update() . my model data is updated well as I expected.... Commented May 15, 2020 at 2:50

1 Answer 1

1

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...

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.