我在自定义 QAbstractListItem
子类(实现here)的 GridView
中显示数据 . 添加和删除项目工作正常,QML会收到更改通知,并且转换工作正常 .
现在我正在尝试在模型中设置Item的属性并让QML对其做出反应 . 问题是,QML中的 onPropertyChanged
未被调用 .
这是C的 property :
// item.h
Q_PROPERTY(bool pToBeDeleted READ toBeDeleted NOTIFY toBeDeletedChanged)
// item.cpp
void Item::requestDelete()
{
toBeDeleted_m = true;
qDebug() << "emitting";
emit toBeDeletedChanged();
}
这就是GridView的样子:
// main.qml
GridView {
id: grid
// ...
model: empty
delegate: customComponent {
toBeDeleted: pToBeDeleted
}
ListModel {
id: empty
}
}
程序启动时, grid
的 model
设置为我的itemmodel .
这是QML类型,看不到变化:
// customComponentForm.ui.qml
Item {
property bool toBeDeleted: false
}
// customComponent.qml
CustomComponentForm {
onToBeDeletedChanged: {
console.debug("change")
}
}
现在,当我从模型内部调用方法时,如下所示:
this->items.at(i++)->requestDelete();
输出显示 emitting
但不是 change
.
我试图包括
emit dataChanged(createIndex(i, 0), createIndex(i, 0));
这确实导致 onToBeDeletedChanged
有时被调用,但这也导致了一些错误的行为
DelegateModel::item: index out range 3 3
1 回答
这里出了两件事 . 首先,因为在
dataChanged
emit具有错误的索引,导致错误的项目被更新 . 第二,错过了第三个参数,因为在另一次尝试中我尝试用错误的方式内联定义Vector,我没有立刻发现这是问题 . 这里的正确电话会是
我的错 .
但另一方面,由于角色名称索引似乎与平台有关,并且表明模型的变化在某种程度上是一种肮脏的方法,因此更好的解决方案(如Kevin Krammer所示)将重写itemmodel以仅包含单个属性,这是
QObject
项目 . 这样,QML就会通知更改项目的属性 .