我已经阅读并尝试了各种方法,主要是这里列出的http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html
所以基本上我有一些C ++类,其中包含带有一些属性的事物列表。事物的变化基本上是我无法控制的(硬件/网络节点的出现和离开),并发出变化的信号。
我一直在做的测试是公开带有QStringList
属性的C ++类型。效果很好,但不允许公开多个属性,而且每次更新时都会重置视图。
C ++
Q_PROPERTY(QStringList robots READ robots NOTIFY robotsChanged)
QStringList StatusInfo::robots() {
auto samples = statusReader.read();
QStringList dataList;
for (auto& sample: samples) {
std::string id = sample->data().id();
dataList.append(QString::fromStdString(id));
}
return dataList;
}
void StatusInfo::on_data_available( dds::sub::DataReader<Operator::StatusInformation>& dr) {
emit robotsChanged();
}
QML:
ListView {
id: robotList
model: status.robots
delegate: RobotItem {}
}
另一个选择是子类QAbstractListModel
的子类化,这似乎是制作更复杂模型的“正确”方法。除非不清楚我需要重写哪些方法以及发出哪些信号。
从subclassing的部分开始:
子类化QAbstractListModel时,必须提供rowCount()和data()函数的实现。行为良好的模型还提供了headerData()实现。
好的,很明显。每个模型都需要这个。
对于可编辑列表模型,还必须提供setData()的实现,并实现flags()函数,以便它返回包含Qt :: ItemIsEditable的值。
我的模型不可编辑,所以不能。
为可调整大小的类似列表的数据结构提供接口的模型可以提供insertRows()和removeRows()的实现。在实现这些功能时,重要的是调用适当的功能,以便所有连接的视图都知道任何更改。
这是棘手的地方。我不想为可调整大小的列表式数据结构提供接口。但是我模型的长度 会改变。
进一步使事情复杂化的是,上面的DataReader
仅返回项目列表,而不是一些不错的插入命令,因此,没有简单的方法可以只调用beginInsertRows
和朋友。
正确的方法是什么?