c++ qml 数组_【QML与C++混合编程】用QVariantList传递数组类型成员
2017.5.8 更新:Record类要用指针,QObject 不能有拷贝函数。
我有一个C++中自定义的ReaderModel,继承自QAbstractListModel类,传递给了QML。
它的me成员是一个Reader指针,Reader有个成员是RecordModel。
通过reader获取的recordModel,在qml中类型是QVariant(RecordModel),我没法把它作为一个ListView的model。
要怎么让它绑定给view呢?
我尝试者把数据拷贝到一个直接传给qml的recordModel,但是当数据之后发生了变化时,视图就不会更新,除非再次拷贝,这样效率不可观。
通过艰难地google查找相关问题,我最后的解决方案是:
取消这个RecordModel成员,用QVariantList来储存所有record。
简单地说就是传递自定义类中的自定义结构体数组。
作为解决方案的代码(如果不需要,完全可以不用ReaderModel,但是要用setContextProperty把reader变量传给qml):
record.h
#ifndef RECORD_H
#define RECORD_H
#include
class Record: public QObject
{
Q_OBJECT
Q_PROPERTY(QString bookId READ bookId WRITE setBookId NOTIFY bookIdChanged)
Q_PROPERTY(int state READ state WRITE setState NOTIFY stateChanged)
public:
Record(const QString &bookId="",int state=0):
bookId_(bookId),state_(state){}
Record(const Record &r){
bookId_ = r.bookId_;
state_ = r.state_;
}
QString bookId() const;
int state() const;
public slots:
void setBookId(const QString &);
void setState(int);
private:
QString bookId_;
int state_;
signals:
void bookIdChanged();
void stateChanged();
};
Q_DECLARE_METATYPE(Record*)//元类型注册
#endif // RECORD_H
reader.h
#ifndef READER_H
#define READER_H
#include
#include
class Reader: public QObject
{
Q_OBJECT
Q_PROPERTY(QString id READ id WRITE setId NOTIFY idChanged)
Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged)
Q_PROPERTY(QVariantList record READ record WRITE setRecord NOTIFY recordChanged)
public:
Reader(const QString &id = "",
const QString &password = "")
: id_(id),password_(password){}
QString id() const; //id
QString password() const; //密码
QVariantList record() const; //记录
Q_INVOKABLE void doSomething()const;
public slots:
void setId(const QString &);
void setPassword(const QString &);
void setRecord(const QVariantList &);
private:
QString id_;
QString password_;
QVariantList record_;//借书记录
signals:
void idChanged();
void passwordChanged();
void recordChanged();
};
#endif // READER_H
readerModel.h
#ifndef READERMODEL_H
#define READERMODEL_H
#include
#include
#include
#include "reader.h"
#include "record.h"
class ReaderModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(Reader* me READ me WRITE setMe NOTIFY meChanged)
public:
enum ReaderRole {
IdRole = Qt::DisplayRole, //0
PasswordRole = Qt::UserRole,
RecordRole
};
Q_ENUM(ReaderRole)
ReaderModel(QObject *parent = nullptr){Q_UNUSED(parent);}
int rowCount(const QModelIndex & = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QHash roleNames() const;
Q_INVOKABLE QVariantMap get(int row) const;
Q_INVOKABLE void append(const QString &id,
const QString &password);
Q_INVOKABLE void set(int row, const QString &id,
const QString &password);
Q_INVOKABLE void remove(int row);
Q_INVOKABLE Reader *me() const;//当前登录的用户对象指针
Q_INVOKABLE void setMe(Reader *r);
private:
QList m_readers;
Reader *me_;
signals:
void meChanged();
};
#endif // READERMODEL_H
reader.cpp
#include "reader.h"
#include "record.h"
#include
QString Reader::id() const
{
return id_;
}
QString Reader::password() const
{
return password_;
}
QVariantList Reader::record() const
{
return record_;
}
void Reader::setId(const QString &value)
{
if (id_ == value)
return;
id_ = value;
emit idChanged();
}
void Reader::setPassword(const QString &value)
{
if (password_ == value)
return;
password_ = value;
emit passwordChanged();
}
void Reader::setRecord(const QVariantList &value)
{
if (record_ == value)
return;
record_ = value;
emit recordChanged();
}
record.cpp
#include "record.h"
QString Record::bookId() const
{
return bookId_;
}
int Record::state() const
{
return state_;
}
void Record::setBookId(const QString &value)
{
if(bookId_ == value)
return;
bookId_ = value;
emit bookIdChanged();
}
void Record::setState(int value)
{
if(state_ == value)
return;
state_ = value;
emit stateChanged();
}
readerModel.cpp
#include "readermodel.h"
#include "reader.h"
int ReaderModel::rowCount(const QModelIndex & /*parent*/) const
{
return m_readers.count();
}
QVariant ReaderModel::data(const QModelIndex &index, int role) const
{
if(index.row() < rowCount())
switch(role){
case IdRole: return m_readers.at(index.row())->id();
case PasswordRole: return m_readers.at(index.row())->password();
case RecordRole: return m_readers.at(index.row())->record();
default: return QVariant();
}
return QVariant();
}
QHash ReaderModel::roleNames() const
{
static const QHash roles{
{IdRole, "id"},
{PasswordRole, "password"},
{RecordRole, "record"}
};
return roles;
}
QVariantMap ReaderModel::get(int row) const
{
Reader *reader = m_readers.value(row);
return { {"id", reader->id()},
{"password", reader->password()},
{"record", reader->record()}};
}
void ReaderModel::append(const QString &id, const QString &password)
{
int row = m_readers.count();
beginInsertRows(QModelIndex(), row, row);
Reader *r = new Reader(id, password, name, power, school, credit, money, unback);
m_readers.append(r);
endInsertRows();
}
void ReaderModel::set(int row, const QString &id, const QString &password)
{
if (row < 0 || row >= m_readers.count())
return;
Reader *r = new Reader(id, password == ""? m_readers[row]->password() : password);
m_readers.replace(row, r);
dataChanged(index(row, 0), index(row, 0), { IdRole,PasswordRole});
}
void ReaderModel::remove(int row)
{
if (row < 0 || row >= m_readers.count())
return;
beginRemoveRows(QModelIndex(), row, row);
m_readers.removeAt(row);
endRemoveRows();
}
Reader *ReaderModel::me() const
{
return me_;
}
void ReaderModel::setMe(Reader *r)
{
me_ = r;
emit meChanged();
}
main.cpp
#include
#include
#include
#include
#include "readermodel.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
//向qml注册类型
qmlRegisterType("Backend", 1, 0, "ReaderModel");
ReaderModel *readerModel = new ReaderModel();
...//写入数据
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
//向qml传递变量
engine->rootContext()->setContextProperty("readerModel", readerModel);
engine->load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
mail.qml:
ListView {
visible: true
id: recordView
width: parent.width
height: parent.height
model: readerModel.me.record
delegate:Rectangle{
property var record: readerModel.me.record[index]
RowLayout{
spacing: 10
Label {
text: record.bookId
}
Label {
text: record.state
}
}
Component.onCompleted: {
console.log(readerModel.me.record)
console.log("\n",readerModel.me.record[index])
console.log("\n",readerModel.me.record[index].state)
}
}
}
c++ qml 数组_【QML与C++混合编程】用QVariantList传递数组类型成员相关推荐
- C++与QML混合编程技术(传递自定义数据类型)
目录 一.前言 二.C++与QML集成的基础 2.1 语言特征 2.2 可集成的前提条件 2.3 基础数据类型 2.4 自定义数据类型 三.实例讲解 3.1 QML获取C++类的自定义结构体数据 3. ...
- Java实现有序数组和无序数组_【算法】字典的诞生:有序数组 PK 无序链表
参考资料 <算法(java)> - - Robert Sedgewick, Kevin Wayne <数据结构> ...
- 多个数字数组_七个问题帮助初学者深入理解Java数组
短文涨姿势,看了不白看,不关注等啥? 几乎所有的高级语言当中,都提供了一种叫做"数组"的东西,Java语言当然也不例外.我们通过数组可以很方便的存储和管理一组数据.因为在Java语 ...
- javascript字典中添加数组_如何在 JavaScript 中更好地使用数组
在 freeCodeCamp 社区阅读原文. 本文短小精悍,我保证.在过去的数个月里,我注意到在我审阅的 pull request 中有四个(关于数组使用的)错误经常出现.同时,我自己也会犯这些错误, ...
- java控件数组_在C# WinForm程序中创建控件数组及相应的事件处理
控件数组是VB提供的一个优秀的设计解决方案,它能很方便快捷的处理大批同类控件的响应和时间处理,但不知为什么在C#中这个优秀特性没有传承下来,甚为可惜,本文将要探讨就是如何在C# WinForm程序实现 ...
- java中将txt转换为数组_关于android:在Java中将列表转换为数组
本问题已经有最佳答案,请猛点这里访问. 在Java中,如何将EDCOX1的0度转换为EDCOX1×1? 检查以下代码: ArrayList tiendas; List tiendasList; tie ...
- c++ 二维数组_【技术篇】C指针与二维数组深度辨析
一.源代码 /*第01行*/ CLion 2019.3.4 x64中编写的源代码·截图 二.深度辨析 CLion 2019.3.4 x64中编译的结果·截图 zippo[4][2]是一个四行二列的in ...
- python 整除的数组_计算和可被整除的所有子数组
在我学习面试的时候,我在GeeksForGeeks上找到了这个问题和解决方案,但不明白答案.在 上面说的是Let there be a subarray (i, j) whose sum is div ...
- scala 字符串转换数组_如何在Scala中将十六进制字符串转换为字节数组?
scala 字符串转换数组 Hex String in Scala denotes value in hexadecimal number system i.e. base 16 number sys ...
最新文章
- 玩转正则之highlight高亮
- React Hooks - useEffect通俗易懂
- PYTHON调用JENKINS的API来进行CI
- wamp 安装monggo扩展
- htmlbuilder php phantomjs
- 转发- css(display,float,position)
- 判断手机是否输入表情
- c语言程序设计考试改革,C语言程序设计课程考试改革实施方案.pdf
- Linux SD卡驱动开发(四) —— SD 控制器之真正的硬件操作
- surfaceView和View区别
- 落户北京经开区 小米汽车首车预计2024年下线并量产 网友:开始存钱!
- linux打印全部make编译信息
- 计算机专业指南考试题6,计算机专业指南考试题.doc
- 选择尽可能多的不相交区间
- 函数的参数对象$event的使用和利用他找到事件对象
- Android开发-数据回传
- WinAPI双人贪吃蛇
- WinZip Pro 9 for Mac(专业zip压缩解压工具)
- 持续降库纯碱增仓大涨,沪铝认购小涨,螺纹10-01季节性正套2022.5.19
- 如何把桌面计算机和回收站隐藏,电脑回收站怎么隐藏图标,隐藏我的电脑和回收站...
热门文章
- Linux的目录说明
- kopernio显示无效程序_daz 无法渲染/没有渲染/渲染不显示/渲染无效?
- python管道pipe_Python multiprocessing模块中的Pipe管道
- 2021.01.04 第 1 个工作日反思
- 八数码宽度优先搜索python代码_图之遍历--广度优先遍历
- linux 设置时钟 教程,Linux hwclock命令参数及用法详解--Linux显示/设置硬件时钟命令...
- 【7】测试用例设计-等价类分析法
- python selenium 下拉框 页面变化_python-selenium之select下拉框
- 地磅称重软件源码_地磅称重软件需求梳理的重要性
- 颜色和心理年龄测试软件,超准的色彩心理学:选8个颜色,就可以测出你的心理年龄...