在Model-View_delegate框架中,C++自己定义的Model一直都没有完全掌握,现在对自己学到的做一些简单的总结和用例子来展示。
例子一:
main.qml中
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Frame {
ListView {
implicitWidth: 250
implicitHeight: 250
clip: true
model: ListModel {
ListElement {
description: "Wash the car"
}
ListElement {
description: "fix the sink"
}
}
delegate: RowLayout {
width: parent.width
TextField {
text: model.description
onEditingFinished:
{
model.description = text;
console.log("model.description is: ", model.description);
}
Layout.fillWidth : true
}
}
}
}
}
运行效果:
在Qt Creator中可以看到每次编辑完,能看到:
说明这个是可以编辑的,也就是编辑的数据能反馈到model中。
看到这个简单的ListView例子,现在用C++来写Model。
一、只读模型
explicit MyStringListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
virtual QHash<int, QByteArray> roleNames() const override;
要重写这个四个接口。
stringlistmodel.h
#ifndef STRINGLISTMODEL_H
#define STRINGLISTMODEL_H
#include <QAbstractListModel>
#include <QStringList>
class MyStringListModel : public QAbstractListModel
{
Q_OBJECT
public:
enum {
DescriptionRole = Qt::UserRole,
};
explicit MyStringListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = DescriptionRole) const override;
virtual QHash<int, QByteArray> roleNames() const override;
private:
QStringList stringList;
};
#endif // STRINGLISTMODEL_H
实现文件stringlistmodel.cpp:
#include "stringlistmodel.h"
MyStringListModel::MyStringListModel(QObject *parent)
{
Q_UNUSED(parent);
stringList.append("111111");
stringList.append("222222");
}
int MyStringListModel::rowCount(const QModelIndex &) const
{
return stringList.count();
}
QVariant MyStringListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() >= stringList.size())
return QVariant();
if (role == DescriptionRole)
return stringList.at(index.row());
else
return QVariant();
}
QHash<int, QByteArray> MyStringListModel::roleNames() const
{
QHash<int, QByteArray> names;
names[DescriptionRole] = "description";
return names;
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "stringlistmodel.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<MyStringListModel>("RegStringListModel", 1, 0, "MyStringListModel");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import RegStringListModel 1.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Frame {
ListView {
implicitWidth: 250
implicitHeight: 250
clip: true
model: MyStringListModel {}
delegate: RowLayout {
width: parent.width
TextField {
text: model.description
onEditingFinished:
{
model.description = text;
console.log("model.description is: ", model.description);
}
Layout.fillWidth : true
}
}
}
}
}
运行效果:
在console.log输出的可以看出,其实model的数据是没有改变的。
接下来就在C++的model类中重写两个接口,就可以实现对model数据的修改。