qml QListView or QGridView C++提供model笔记
主要说明:继承 QAbstractListModel 类
细则说明:
重写 rowCoun() ,data() ,roleNames() 函数
注:上面的函数主要是给qml获取参数用的一定要重写
还有 insert(),remove() append()。
注:这三个函数主要是C++用来数据更新用的
基础类
SDInfo.h
#ifndef SDINFO_H
#define SDINFO_H
#include <QObject>
class SDInfo : public QObject
{
Q_OBJECT
Q_PROPERTY(QByteArray name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QByteArray longName READ longName WRITE setLongName NOTIFY longNameChanged)
Q_PROPERTY(int size READ size WRITE setSize NOTIFY sizeChanged)
Q_PROPERTY(QString folder READ folder WRITE setFolder NOTIFY folderChanged)
public:
explicit SDInfo(QObject *parent = nullptr);
SDInfo(const SDInfo&sdinfo);
SDInfo(QByteArray name_,QByteArray loneName_,int size_,QString folder,QObject*parent=nullptr);
SDInfo operator=(const SDInfo&info);
public slots:
Q_INVOKABLE QByteArray name()const {return m_name;};
Q_INVOKABLE QByteArray longName()const {return m_longName;};
Q_INVOKABLE int size()const{return m_size;};
Q_INVOKABLE QString folder()const{return m_folder;};
Q_INVOKABLE void setName(QByteArray str){ m_name = str;emit nameChanged(m_name);};
Q_INVOKABLE void setLongName(QByteArray str){ m_longName = str;emit longNameChanged(m_name);};
Q_INVOKABLE void setSize(int size_){m_size = size_; emit sizeChanged(m_size);};
Q_INVOKABLE void setFolder(QString fol){m_folder = fol;emit folderChanged(m_folder);};
signals:
void nameChanged(QByteArray);
void longNameChanged(QByteArray);
void folderChanged(QString);
void sizeChanged(int);
private:
QByteArray m_name;
QByteArray m_longName;
QString m_folder;//is folder
int m_size;//file size
};
#endif // SDINFO_H
注:上面我的类我使用啦四个变量,可根据自己需求改。
注:上面的实现方式我使用了,qml的实现方式也就是Q_PROPERTY 不是必须的。普通的c++类也是可以的。
#include "SDInfo.h"
SDInfo::SDInfo(QObject *parent)
: QObject{parent}
,m_name("???")
,m_longName("???")
,m_folder("???")
,m_size(0)
{
}
SDInfo::SDInfo(const SDInfo &sdinfo)
{
this->m_name = sdinfo.name();
this->m_longName = sdinfo.longName();
this->m_folder = sdinfo.folder();
this->m_size = sdinfo.size();
// return sdinfo;
}
SDInfo::SDInfo(QByteArray name_,QByteArray longName_, int size_, QString folder, QObject *parent)
: QObject{parent}
,m_name(name_)
,m_longName(longName_)
,m_folder(folder)
,m_size(size_)
{
}
SDInfo SDInfo::operator=(const SDInfo &info) {
this->m_name = info.name();
this->m_longName = info.longName();
this->m_folder = info.folder();
this->m_size = info.size();
return info;
}
重点来了,重点来了。重写一个 继承 QAbstractListModel的类
#ifndef SDLIST_H
#define SDLIST_H
#include <QObject>
#include <QAbstractListModel>
#include "SDInfo.h"
class SDList : public QAbstractListModel
{
Q_OBJECT
Q_ENUMS(SDInfoRoles)
public:
explicit SDList(QObject *parent = nullptr);
enum SDInfoRoles {
nameRole = Qt::UserRole + 1,
lengNameRole,
sizeRole,
folderRole
};
public:
int rowCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index,int role = Qt::DisplayRole) const;
QHash<int,QByteArray> roleNames()const;
void insert(int index,const SDInfo &info);
void remove(int index);
void append(const SDInfo &info);
public slots:
signals:
private:
QList<SDInfo> m_SDlist;
};
#endif // SDLIST_H
#include "sdlist.h"
#include <QDebug>
SDList::SDList(QObject *parent)
: QAbstractListModel{parent}
{
this->append(SDInfo("hahah.GC","1sd.gcode",10,"./../"));
this->append(SDInfo("a.GC","2d.gcode",10,"./../"));
this->append(SDInfo("B.GC","3sd.gcode",10,"./../"));
this->append(SDInfo("c.GC","4sd.gcode",10,"./../"));
this->append(SDInfo("DDDD.GC","5sd.gcode",10,"./../"));
}
int SDList::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_SDlist.count();
}
QVariant SDList::data(const QModelIndex &index, int role) const
{
if (index.row() < 0 || index.row() >= m_SDlist.count())
return QVariant();
const SDInfo *info = &m_SDlist[index.row()];
if (role == nameRole)
return info->name();
else if (role == sizeRole)
return info->size();
else if (role == lengNameRole)
return info->longName();
else if (role == folderRole)
return info->folder();
return QVariant();
}
QHash<int, QByteArray> SDList::roleNames() const
{
QHash<int, QByteArray> roles;
roles[nameRole] = "name"; //!这个很重要,qml主要使用这个名字来获取数据
roles[lengNameRole] = "lengName";
roles[sizeRole] = "size";
roles[folderRole] = "folder";
return roles;
}
void SDList::insert(int index, const SDInfo &info)
{
if(index < 0 || index > m_SDlist.count())
{
qCritical()<<"insert error,index="<<index;
return;
}
//!如果数据发生改变 告诉qml刷新
beginInsertRows(QModelIndex(),index,index);
m_SDlist.insert(index,info);
endInsertRows();
}
void SDList::remove(int index)
{
if(index < 0 || index > m_SDlist.count())
{
qCritical()<<"insert error,index="<<index;
return;
}
//!如果数据发生改变 告诉qml刷新
beginInsertRows(QModelIndex(),index,index);
m_SDlist.removeAt(index);
endInsertRows();
}
void SDList::append(const SDInfo &info)
{
m_SDlist.append(info);
}
注:好啦基本完事了,把主函数完善。
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "sdlist.h"
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;
qmlRegisterType<SDList>("com.booler.test",1,0,"SDlist");
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();
}
然后就是qml中的使用,
import QtQuick 2.15
import QtQuick.Window 2.15
import com.booler.test 1.0
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
SDlist{
id:sdList
}
ListView{
id:listView
anchors.fill: parent
model:sdList
spacing: 10
delegate:numberDelegate
}
Component{
id:numberDelegate
Rectangle{
width:240
height:20
color: "blue"
Text {
color: "#c73939"
text: lengName // 这里我用的是长文件名,也就是 roleNames 函数中定义的名字
font.pointSize: 14
}
}
}
}