C++ 在拖放列表中插入/删除项目(&a);使用cpp模型删除QML listView
我试图在C++ 在拖放列表中插入/删除项目(&a);使用cpp模型删除QML listView,c++,qt,qml,qtquick2,C++,Qt,Qml,Qtquick2,我试图在QML中的ListView中添加N个项目,在给定的索引中添加和删除一个新项目 我做了以下示例,但问题是当我移动一些项目时,当我尝试插入一个新项目时,位置可能不正确,我不知道为什么。当我在我的cpp模型中检查我的数据列表时,位置是正确的,但是,新的或删除的项目将不会插入正确位置的/删除的 当我插入一个新项,然后我移动它,然后我尝试删除该项,或者在该新项旁边插入一个项,似乎会发生错误 下面是一个简单的示例(如果需要,可以运行它)。我调用了我的项数据:块 #include "mainwindo
QML
中的ListView
中添加N个项目
,在给定的索引中添加和删除一个新项目
我做了以下示例,但问题是当我移动一些项目时,当我尝试插入一个新项目时,位置可能不正确,我不知道为什么。当我在我的cpp模型中检查我的数据列表时,位置是正确的,但是,新的或删除的项目将不会插入正确位置的/删除的
当我插入一个新项
,然后我移动它,然后我尝试删除该项
,或者在该新项
旁边插入一个项
,似乎会发生错误
下面是一个简单的示例(如果需要,可以运行它)。我调用了我的项数据
:块
#include "mainwindow.h"
#include <QApplication>
#include <QtQml>
#include <QQuickView>
#include <QQuickWidget>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
main.qml
你知道我做错了什么吗?
非常感谢,祝你度过愉快的一天 移动项目时有两个错误。在DropArea.onenterned
中,如果在visualModel.items.move
之前和之后打印drag.source.visualIndex
和delegateRoot.visualIndex
,您将看到值在移动后被修改。这意味着您在调用myModel.moveBlock
时移动了错误的行。要解决此问题,请在移动项目之前保存值:
DropArea {
anchors { fill: parent; margins: 15 }
onEntered: {
var from = drag.source.visualIndex;
var to = delegateRoot.visualIndex;
myModel.moveBlock(from, to);
}
}
在C++模型中移动项目时,QuestTimeMe::NeXMoVERWOS应该被称为插入/删除项。否则,QMLDelegateModel
无法正确显示您的模型。请记住,在实现BlockModel::moveBlock
时,模型的目标行与源列表m_块的目标行不同。有关详细信息,请参见中的最后一个示例
void BlockModel::moveBlock(int from, int to) {
if (from == to)
return;
auto modelFrom = from;
auto modelTo = to + (from < to ? 1 : 0);
beginMoveRows(QModelIndex(), modelFrom, modelFrom, QModelIndex(), modelTo);
m_blocks.move(from,to);
endMoveRows();
}
void BlockModel::moveBlock(int-from,int-to){
如果(从==到)
返回;
自动建模从=从;
自动建模到=到+(从<到?1:0);
beginMoveRows(QModelIndex(),modelFrom,modelFrom,QModelIndex(),modelTo);
m_块。移动(从、到);
endMoveRows();
}
您好,非常感谢您的回复,效果很好!但是,我意识到您不需要使用visualModel.items.move(from,to)代码>如果您在cpp中使用移动行
。否则,您的解决方案是完美的。非常感谢我根据beginMoveRows()
使用稍微不同的实现移动项目。除了MapItemView
在调用beginMoveRows
/endMoveRows
后无法使用该模型之外,该模型在任何地方都能完美地工作:移动的项目在地图上消失,对项目的其他操作会使应用程序崩溃。你知道怎么做吗?谢谢
#include <QAbstractListModel>
#include <QStringList>
#include <qqmlcontext.h>
#include <QDebug>
#include <QStringList>
//![0]
class Block
{
public:
Block(){
}
Block(const QString &name);
QString nameBlock() const;
void setName(QString n) {
m_name = n;
}
private:
QString m_name;
};
class BlockModel : public QAbstractListModel
{
Q_OBJECT
public:
Block* getBlock(QString name);
Q_INVOKABLE void moveBlock(int from,int to);
Q_INVOKABLE void insertBlock(int index);
Q_INVOKABLE void deleteBlock(int index);
enum BlockRoles {
nameRole = Qt::UserRole + 1,
};
BlockModel(QObject *parent = 0);
void setContext(QQmlContext *ctx) {
m_ctx = ctx;
}
void setName(const QString &name);
void addBlock(const Block &Block);
int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
QHash<int, QByteArray> roleNames() const;
private:
QList<Block> m_blocks;
QQmlContext* m_ctx;
int cpt = 0;
};
#include "model.h"
#include "qDebug"
Block::Block(const QString &name)
: m_name(name)
{
}
QString Block::nameBlock() const
{
return m_name;
}
BlockModel::BlockModel(QObject *parent)
: QAbstractListModel(parent)
{
}
void BlockModel::addBlock(const Block &Block)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_blocks << Block;
endInsertRows();
}
int BlockModel::rowCount(const QModelIndex & parent) const {
Q_UNUSED(parent);
return m_blocks.count();
}
void BlockModel::moveBlock(int from, int to) {
m_blocks.move(from,to);
}
void BlockModel::insertBlock(int index) {
Block b =(Block(QString("New Item ")+QString::number(cpt)));
beginInsertRows(QModelIndex(),index+1,index+1);
m_blocks.insert(index+1,b);
endInsertRows();
cpt++;
}
void BlockModel::deleteBlock(int index) {
beginRemoveRows(QModelIndex(),index,index);
m_blocks.removeAt(index);
endRemoveRows();
}
QVariant BlockModel::data(const QModelIndex & index, int role) const {
if (index.row() < 0 || index.row() >= m_blocks.count())
return QVariant();
const Block &Block = m_blocks[index.row()];
if (role == nameRole)
return Block.nameBlock();
return QVariant();
}
//![0]
QHash<int, QByteArray> BlockModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[nameRole] = "nameBlock";
return roles;
}
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2
import QtQml.Models 2.2
import QtQuick.Controls.Styles 1.4
Rectangle {
id : rootRectangle
visible: true
ScrollView {
anchors.fill:parent
ListView{
id: root
width: parent.width; height: parent.height
property int visualIndex: -1
displaced: Transition {
NumberAnimation { properties: "y"; easing.type: Easing.OutQuad }
}
model: DelegateModel {
id: visualModel
model: myModel
delegate: Component {
MouseArea {
id: delegateRoot
property int visualIndex: DelegateModel.itemsIndex
cursorShape: Qt.PointingHandCursor
width: root.width; height: 100
drag.target: icon
drag.axis: Drag.YAxis
Behavior on height {
PropertyAnimation { duration: 100 }
}
Rectangle {
anchors.top: delegateRoot.top
anchors.left: delegateRoot.left
id: icon
objectName: nameBlock
width: root.width-5; height: 100
color: "skyblue"
radius: 3
Text {
objectName: "rect"
id: title
anchors.fill: parent
anchors.margins: 10
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: nameBlock
}
Drag.active: delegateRoot.drag.active
Drag.source: delegateRoot
Drag.hotSpot.x: 36
Drag.hotSpot.y: 36
Button {
id : buttonAdd
text: "Add Block"
anchors{
right: parent.right
top: parent.top
bottom: parent.bottom
margins: 30
}
onClicked: {
myModel.insertBlock(visualIndex)
}
}
Button {
id : buttonDelete
text: "Delete Block"
anchors{
right: buttonAdd.left
top: parent.top
bottom: parent.bottom
margins: 30
}
onClicked: {
myModel.deleteBlock(visualIndex)
}
}
states: [
State {
when: icon.Drag.active
ParentChange {
target: icon
parent: root
}
AnchorChanges {
target: icon;
anchors.horizontalCenter: undefined;
anchors.verticalCenter: undefined
}
}
]
transitions: Transition {
// Make the state changes smooth
ParallelAnimation {
ColorAnimation { property: "color"; duration: 500 }
NumberAnimation { duration: 300; properties: "detailsOpacity,x,contentY,height,width,font.pixelSize,font.bold,visible" }
}
}
}
DropArea {
anchors { fill: parent; margins: 15 }
onEntered: {
visualModel.items.move(drag.source.visualIndex, delegateRoot.visualIndex)
myModel.moveBlock(drag.source.visualIndex,delegateRoot.visualInde)
}
}
}
}
}
}
}
}
DropArea {
anchors { fill: parent; margins: 15 }
onEntered: {
var from = drag.source.visualIndex;
var to = delegateRoot.visualIndex;
myModel.moveBlock(from, to);
}
}
void BlockModel::moveBlock(int from, int to) {
if (from == to)
return;
auto modelFrom = from;
auto modelTo = to + (from < to ? 1 : 0);
beginMoveRows(QModelIndex(), modelFrom, modelFrom, QModelIndex(), modelTo);
m_blocks.move(from,to);
endMoveRows();
}