Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在拖放列表中插入/删除项目(&a);使用cpp模型删除QML listView_C++_Qt_Qml_Qtquick2 - Fatal编程技术网

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应该被称为插入/删除项。否则,QML

DelegateModel
无法正确显示您的模型。请记住,在实现
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();
}