在c++中定义了一个简单的QStandardItemModel
,我通过自定义的Delegate
和一个DelegateModel
将其显示在QML
ListView
中。
// The DropArea is part of the delegate `comp_container`
DropArea{
anchors{fill: parent}
keys: ["pageitem"]
onEntered: {
let from = drag.source.DelegateModel.itemsIndex
let to = dragAreaPage.DelegateModel.itemsIndex
if ( pageItemDragOperationStartIndex === -1 ){
pageItemDragOperationStartIndex = from
}
pageItemDragOperationFinalIndex = to
console.log(from + "->" + to)
visualModel.items.move(from,to)
}
}
这里是委托模型,pageproxymodel
是c++模型。
DelegateModel {
id: visualModel
model: pageproxymodel
delegate: comp_container
}
如何更新C++模型?委托的顶层项是MouseArea
,我在release handler中处理重新排序:
onReleased: {
if ( pageItemDragOperationStartIndex !== -1 && pageItemDragOperationFinalIndex !== -1 ){
console.log("Page item final drag operation: " + pageItemDragOperationStartIndex + "->" + pageItemDragOperationFinalIndex)
pageproxymodel.move(pageItemDragOperationStartIndex, pageItemDragOperationFinalIndex)
pageItemDragOperationStartIndex = -1
pageItemDragOperationFinalIndex = -1
}
}
C++模型的move
函数将调用转发给以下处理程序:
bool PageModel::moveRow(const QModelIndex &sourceParent,
int sourceRow,
const QModelIndex &destinationParent,
int destinationChild)
{
if ( sourceRow < 0 || sourceRow > rowCount()-1 ||
destinationChild < 0 || destinationChild > rowCount() )
{
return false;
}
beginMoveRows(sourceParent, sourceRow, sourceRow, destinationParent, destinationChild);
QList<QStandardItem*> rowItems = takeRow(sourceRow);
insertRow(destinationChild, rowItems);
endMoveRows();
return true;
}
对于上面的C++模型代码,它在QML中的释放处理程序处崩溃:
我尝试了其他方法来观察效果,没有崩溃,但也没有预期的行为。
- 删除单个行(这将删除QML ListView中的2(!)行)
- 删除没有开始/结束调用的单行(删除QML ListView中的1行,但不能是正确的)
- 无需开始/结束调用即可删除和插入单行(QML ListView在一段时间内看起来很好,但移动几次后就会失去同步)
基本上,我想做的就是通过c++模型保存ListView状态,毕竟这是一个标准的用例,我这边肯定有什么简单的错误,但我看不到它。
2条答案
按热度按时间f2uvfpb91#
我喜欢对
DelegateModel
做的一件事就是利用DelegateModelGroup
。通过声明一个名为“all”的组,它引入了一个附加属性allIndex
,这对于在项目被重新排序后跟踪它很有用。下面的示例实现了一个同时具有MouseArea
和DropArea
的DelegateModel
。在拖动模式下,我禁用了所有的MouseArea
,这样DropArea
就有机会做出响应。您可以Try it Online!
l3zydbqr2#
发现了错误:
pageItemDragOperationStartIndex
和pageItemDragOperationFinalIndex
变量是每个委托的一部分,但不是页面的一部分。另外,正如在注解中指出的,使用QStandardItemModel
不必调用begin/end
函数。现在它的工作方式就像一个护身符。