描述:在QML中,当需要少量数据时,QML中直接用原生模型是非常方便。
当数据较为复杂或者想在c++里操纵数据时,可以在C++中自定义自己的Model并在qml中展示数据,这样会更加稳定可靠而且避免卡顿现象。
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "MyListModel.h"
#include <QQmlContext>
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
#include <QAbstractListModel>
class 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<int, QByteArray> roleNames() const override;
private:
QList<MyData> 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<int, QByteArray> MyListModel::roleNames() const
{
QHash<int, QByteArray> 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:
|