描述:在QML中,当需要少量数据时,QML中直接用原生模型是非常方便。
当数据较为复杂或者想在c++里操纵数据时,可以在C++中自定义自己的Model并在qml中展示数据,这样会更加稳定可靠而且避免卡顿现象。
main.cpp
#include#include #include "MyListModel.h" #include int main(int argc, char *argv[]) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif QGuiApplication app(argc, argv); QQmlApplicationEngine engine; // engine.rootContext()->setContextProperty("MyListModel",MyListModel::getInstance());//方法1 注册自定义model qmlRegisterSingletonInstance("MyModel",1,0,"MyListModel",MyListModel::getInstance());//方法2 const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
MyListModel.(h/cpp)
#ifndef MYLISTMODEL_H #define MYLISTMODEL_H #includeclass MyData { public: MyData(QString s,int a):m_name(s),m_age(a){ }; QString m_name; int m_age; }; class MyListModel : public QAbstractListModel { Q_OBJECT enum myRole { Name = Qt::DisplayRole+1, Age }; public: explicit MyListModel(QObject *parent = nullptr); MyListModel(QString s,int age); static MyListModel *getInstance(); // Basic functionality: int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QHash roleNames() const override; private: QList m_data; static MyListModel *instance; }; #endif // MYLISTMODEL_H
#include "MyListModel.h"
MyListModel *MyListModel::instance = 0;
MyListModel::MyListModel(QObject *parent)
: QAbstractListModel(parent)
{
m_data.append(MyData("tom",12));
m_data.append(MyData("jack",23));
m_data.append(MyData("peter",43));
}
MyListModel *MyListModel::getInstance()
{
if(instance == nullptr){
instance = new MyListModel();
}
return instance;
}
int MyListModel::rowCount(const QModelIndex &parent) const
{
// For list models only the root node (an invalid parent) should return the list's size. For all
// other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
if (parent.isValid())
return 0;
// FIXME: Implement me!
return m_data.count();//返回数据一共有多少行,在listmodel里面一般列是1,所以这里只需要计算rowd的大小
}
QVariant MyListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if(myRole::Name == role){//根据对应的角色返回对应的值
return m_data[index.row()].m_name;
}else if(myRole::Age == role){
return m_data[index.row()].m_age;
}
return QVariant();
}
QHash MyListModel::roleNames() const
{
QHash roles;
roles.insert(myRole::Name,"name");//qml yu C++进行映射
roles.insert(myRole::Age,"age");//qml 使用字符串"age"就可以显示
return roles;
}
QML:
import QtQuick 2.12
import QtQuick.Window 2.12
import MyModel 1.0
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
ListView {
anchors.fill: parent
// model: ListModel {
// ListElement {
// name: "zhangsan"
// age: 12
// }
// ListElement {
// name: "tom"
// age: 33
// }
// ListElement {
// name: "jack"
// age: 23
// }
// }
model:MyListModel
delegate: Text {
id: txt
text: name + " " + age;
}
}
}
run:



