在c++中定义了一个简单的c++,通过自定义Delegate
和DelegateModel
在QML
ListView
中显示。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
,我处理发布处理程序中的重新排序:
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中的发布处理程序上崩溃:
我尝试过其他的方法来观察它的效果,没有撞车,但也没有预期的行为。
基本上,我想要做的就是通过ListView模型保存c++状态,毕竟这是一个标准用例,简单的东西在我这一边一定是错误的,但是我看不见它。
发布于 2022-11-30 02:43:15
我喜欢用DelegateModel
做的一件事就是使用DelegateModelGroup
。通过声明一个名为"all“的组,它引入了一个附加属性allIndex
,该属性对于重新排序后跟踪项目非常有用。下面的示例使用DelegateModel
和MouseArea
实现了一个DropArea
。在拖动模式下,我禁用了所有的MouseArea
,这样DropArea
就有机会做出响应。
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
property int activeMouseArea: -1
ListView {
id: listView
width: 420
height: parent.height
model: SampleDelegateModel { }
ScrollBar.vertical: ScrollBar {
width: 20
policy: ScrollBar.AlwaysOn
}
}
footer: Text { id: dbg }
}
// SampleData.qml
import QtQuick
import QtQuick.Controls
ListModel {
ListElement { name: "Steve Jobs" }
ListElement { name: "Jeff Bezos" }
ListElement { name: "Bill Gates" }
ListElement { name: "Elon Musk" }
}
// SampleDelegateModel.qml
import QtQuick
import QtQuick.Controls
import QtQml.Models
DelegateModel {
id: delegateModel
model: SampleData { }
delegate: SampleDelegate { }
groups: [
DelegateModelGroup {
id: allItems
name: "all"
includeByDefault: true
}
]
filterOnGroup: "all"
function moveItem(from, to) {
dbg.text = `Debugging: moveItem(${from},${to})`;
allItems.move(from, to);
}
}
// SampleDelegate.qml
import QtQuick
import QtQuick.Controls
import QtQml.Models
Rectangle {
property int allIndex: DelegateModel.allIndex
width: 400
height: labelText.height + 20
border.color: "grey"
z: mouseArea.drag.active || mouseArea.pressed ? 2 : 1
property int dragTo: -1
Drag.active: mouseArea.drag.active
Text {
id: labelText
anchors.centerIn: parent
text: allIndex + ": [" + index + "] " + name
}
DropArea {
anchors.fill: parent
onEntered: drag.source.dragTo = allIndex
}
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: parent
property point startPoint
enabled: activeMouseArea === -1
onPressed: {
activeMouseArea = allIndex;
dragTo = -1;
startPoint = Qt.point(parent.x, parent.y);
}
onReleased: {
activeMouseArea = -1;
[parent.x,parent.y] = [startPoint.x, startPoint.y];
Qt.callLater(delegateModel.moveItem, allIndex, dragTo);
}
}
}
你可以在网上试试!
发布于 2022-11-29 18:34:29
发现错误:pageItemDragOperationStartIndex
和pageItemDragOperationFinalIndex
变量,每个委托的一部分,但不是页面的一部分。另外,正如注释中指出的那样,使用QStandardItemModel
不需要调用begin/end
函数。现在它就像一种魅力。
https://stackoverflow.com/questions/74607500
复制相似问题