关于qt:QML,将Combobox与QStringList模型一起使用时,错误“未定义modelData”

QML Error “modelData is not defined” when using Combobox with QStringList model

我是Qt和QML的新手。 我想使用带有QStringList模型的组合框显示我的列表。 但是,它根本不起作用。 以下是相关的源代码。

ListModelResourceManager.hpp

1
2
3
4
5
6
7
8
9
10
11
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

1
2
3
4
...
ListModelResourceManager lmResourceManager("MODEL_ResourceManagerList", engine);
...
engine.load(QUrl(QStringLiteral("qrc:/viewmain.qml")));

viewmain.qml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
      }

当使用带注释的模型定义(模型:[" First"," Second"," Third"])时,效果很好。

请让我知道我的代码部分出了什么问题。 谢谢


我发现了错误,所以我自己回答了我的问题。

要注册模型以查看组件,注册对象必须是模型类型类。 就我而言,我的ListModelResourceManager不是模型类。 因此需要使用QStringListModel作为模型类,而不是将此QStringListModel对象链接到QML Combobox组件。

我在这里更新了我的工作资源,供那些像我一样痛苦的人使用

ListModelResourceManager.hpp(管理QStringListMoel)

1
2
3
4
5
6
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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

1
2
3
4
5
6
int main(int argc, char *argv[])
{
// ...
    ListModelResourceManager lmResourceManager("MODEL_Resources","ResourceManagerList", engine);
// ...
}

view.qml

1
2
3
4
5
6
7
// ...
   ComboBox {
       id : idResourceSelector          
       model : MODEL_Resources
       textRole:"display"    
   }  
// ...

ps。 我想将本机资源管理器与QT界面分开,所以我使用了回调侦听器。 如果不是您的情况,则可以使用信号/插槽等其他方法来更新模型。