我们目前大多数的model是使用ListModel.它是基于QML语言的.虽然我们也可以使用QStringList来做一个简单的Model来供我们的ListView或GridView来使用.对于有些复杂的项目,数据来源于有些算法或来源于互联网,大家可能会基于C++来开发自己的引擎.我们需要把我们得到的数据展现在我们的界面中.利用QML来呈现自己的数据.在今天的例程中,我们尝试利用C++语言来设计一个通用的Model.这个Model将在我们的QML应用中被利用并呈现数据.
#ifndef DATALISTMODEL_H
#define DATALISTMODEL_H
#include
#include
class Data
{
public:
Data(const QString &type, const QString &size);
QString type() const;
QString size() const;
private:
QString m_type;
QString m_size;
};
class DataListModel : public QAbstractListModel
{
Q_OBJECT
public:
enum AnimalRoles {
TypeRole = Qt::UserRole + 1,
SizeRole1
};
DataListModel(QObject *parent = 0);
int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
Q_INVOKABLE void insert(int index, const Data &data);
Q_INVOKABLE void append(const Data &data);
Q_INVOKABLE void remove(int index);
Q_INVOKABLE void append(const QVariantMap map);
signals:
void countChanged(int arg);
private:
int count() const;
protected:
QHash roleNames() const;
private:
QList m_list;
};
#endif // DATALISTMODEL_H
int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
#include "datalistmodel.h"
#include
Data::Data(const QString &type, const QString &size)
:m_type(type), m_size(size)
{
}
QString Data::type() const
{
return m_type;
}
QString Data::size() const
{
return m_size;
}
DataListModel::DataListModel(QObject *parent)
: QAbstractListModel(parent)
{
}
void DataListModel::insert(int index, const Data &data)
{
if(index < 0 || index > m_list.count()) {
return;
}
emit beginInsertRows(QModelIndex(), index, index);
m_list.insert(index, data);
emit endInsertRows();
emit countChanged(m_list.count());
}
void DataListModel::remove(int index)
{
if(index < 0 || index >= m_list.count()) {
return;
}
emit beginRemoveRows(QModelIndex(), index, index);
m_list.removeAt( index );
emit endRemoveRows();
emit countChanged(m_list.count());
}
void DataListModel::append(const Data &data)
{
insert(count(), data);
}
void DataListModel::append(const QVariantMap map)
{
QString type = map["type"].toString();
QString size = map["size"].toString();
Data data(type, size);
insert(count(), data);
}
int DataListModel::rowCount(const QModelIndex & parent) const {
Q_UNUSED(parent);
return m_list.count();
}
QVariant DataListModel::data(const QModelIndex & index, int role) const {
if (index.row() < 0 || index.row() >= m_list.count())
return QVariant();
const Data &data = m_list[index.row()];
// qDebug() << "row: " << index.row();
if (role == TypeRole)
return data.type();
else if (role == SizeRole1)
return data.size();
return QVariant();
}
QHash DataListModel::roleNames() const {
QHash roles;
roles[TypeRole] = "type";
roles[SizeRole1] = "size";
return roles;
}
int DataListModel::count() const
{
return rowCount(QModelIndex());
}
#include "datalistmodel.h"
#include
Data::Data(const QString &type, const QString &size)
:m_type(type), m_size(size)
{
}
QString Data::type() const
{
return m_type;
}
QString Data::size() const
{
return m_size;
}
DataListModel::DataListModel(QObject *parent)
: QAbstractListModel(parent)
{
}
void DataListModel::insert(int index, const Data &data)
{
if(index < 0 || index > m_list.count()) {
return;
}
emit beginInsertRows(QModelIndex(), index, index);
m_list.insert(index, data);
emit endInsertRows();
emit countChanged(m_list.count());
}
void DataListModel::remove(int index)
{
if(index < 0 || index >= m_list.count()) {
return;
}
emit beginRemoveRows(QModelIndex(), index, index);
m_list.removeAt( index );
emit endRemoveRows();
emit countChanged(m_list.count());
}
void DataListModel::append(const Data &data)
{
insert(count(), data);
}
void DataListModel::append(const QVariantMap map)
{
QString type = map["type"].toString();
QString size = map["size"].toString();
Data data(type, size);
insert(count(), data);
}
int DataListModel::rowCount(const QModelIndex & parent) const {
Q_UNUSED(parent);
return m_list.count();
}
QVariant DataListModel::data(const QModelIndex & index, int role) const {
if (index.row() < 0 || index.row() >= m_list.count())
return QVariant();
const Data &data = m_list[index.row()];
// qDebug() << "row: " << index.row();
if (role == TypeRole)
return data.type();
else if (role == SizeRole1)
return data.size();
return QVariant();
}
QHash DataListModel::roleNames() const {
QHash roles;
roles[TypeRole] = "type";
roles[SizeRole1] = "size";
return roles;
}
int DataListModel::count() const
{
return rowCount(QModelIndex());
}
#include
#include
#include
#include
#include "datalistmodel.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
DataListModel model;
model.append( Data("wolf.jpg", "Medium") );
model.append( Data("polarbear.jpg", "Large") );
model.append( Data("quoll.jpg", "Small") );
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:///Main.qml")));
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.rootContext()->setContextProperty("myModel", &model);
view.show();
return app.exec();
}
import QtQuick 2.0
import Ubuntu.Components 1.1
/*!
\brief MainView with a Label and Button elements.
*/
MainView {
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"
// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "model.liu-xiao-guo"
/*
This property enables the application to change orientation
when the device is rotated. The default is false.
*/
//automaticOrientation: true
// Removes the old toolbar and enables new features of the new header.
useDeprecatedToolbar: false
width: units.gu(60)
height: units.gu(85)
Page {
title: i18n.tr("model")
ListView {
id: listview
clip: true
width: parent.width
height: parent.height - button.height
model: myModel
delegate: Item {
id: delegate
width: listview.width
height: units.gu(20)
Row {
spacing: units.gu(2)
Image {
source: "images/" + type
height: delegate.height *.9
width: height
}
Text {
anchors.verticalCenter: parent.verticalCenter
text: size
font.pixelSize: units.gu(5)
color: "red"
}
}
Image {
width: units.gu(4)
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: units.gu(1)
source: "images/remove.png"
MouseArea {
anchors.fill: parent
onClicked: {
myModel.remove(index);
}
}
}
}
}
Button {
id: button
anchors.bottom: parent.bottom
anchors.bottomMargin: units.gu(2)
anchors.horizontalCenter: parent.horizontalCenter
text: "Add a bear"
onClicked: {
// We are going to add a bear to the list
var o = {
"type" : "polarbear.jpg",
"size" : "large"
};
myModel.append( o );
listview.positionViewAtEnd()
}
}
}
}