【问题标题】:Getting old and new QStandardItem after drag-and-drop move拖放移动后获取新旧 QStandardItem
【发布时间】:2015-05-19 19:06:09
【问题描述】:

我正在尝试创建一个 QTreeView,它支持项目的内部移动以及一种让我检测移动的源和目标的方法。使用 QTreeWidget 时,我可以覆盖 dropEvent 并执行以下操作:

void MyTreeWidget::dropEvent(QDropEvent* event)
{
    QList<QStandardItem*> dragItems = selectedItems();
    QTreeView::dropEvent(event);
    // here dragItems have been moved to the new places so I can do whatever I want
}

我需要知道源位置和目标位置的原因是能够将命令推送到撤消堆栈上,从而在底层数据结构中执行相同的移动。

我现在已经切换到带有 QStandardItemModel 的 QTreeView(创建一个描述底层数据结构的自定义模型将需要太多工作),但它的工作方式似乎有点不同。在调用 QTreeView::dropEvent(...) 之后,它创建并添加了新项目,但没有删除旧项目,所以我无法确定新索引,因为一旦删除旧项目,它就会改变。我正在使用这个例子来调试它:

#include <QtDebug>
#include <QApplication>
#include <QTreeView>
#include <QtGui/QStandardItemModel>

class MyTreeView : public QTreeView
{
    public:
        MyTreeView(QWidget* parent=0)
            : QTreeView(parent)
        {}

        void dropEvent(QDropEvent* event) {
            qDebug() << "rows before:" << model()->rowCount();
            QTreeView::dropEvent(event);
            qDebug() << "rows after:" << model()->rowCount();
        }

};

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    MyTreeView* tree = new MyTreeView();
    QStandardItemModel model(3, 1);
    for(int r = 0; r < model.rowCount(); r++)
        model.setItem(r, 0, new QStandardItem(QString("%0").arg(r)));

    tree->setDragEnabled(true);
    tree->viewport()->setAcceptDrops(true);
    tree->setDefaultDropAction(Qt::MoveAction);
    tree->setDropIndicatorShown(true);
    tree->setDragDropMode(QAbstractItemView::InternalMove);

    tree->setModel(&model);
    tree->show();

    return app.exec();
}

当我在 Qt 5.4 (Windows 7) 上运行它并拖放一个项目时,我得到以下输出:

rows before: 3
rows after: 4

当使用 QTreeWidget 时,它会说:

rows before: 3
rows after: 3

关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    有一个更好的方法可以使用QAbstractItemModel::rowsMoved 来移动项目 来自文档:

    在模型中的行移动后发出此信号。 sourceStartsourceEnd 之间的项目,在给定下 sourceParent 项目已从 行 destinationRow.

    另外,我记得在 QQ 中阅读Using Undo/Redo with Item Views,我能找到的最佳链接是cached pageFrench version

    【讨论】:

    • "rowsMo​​ved" 没有发出。我想这是因为它实际上并没有移动它,而是创建新项目然后删除旧项目。要像 QQ 链接描述的那样做,我需要重新实现标准模型的拖放逻辑(这似乎很麻烦)或从头开始创建我自己的模型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2022-10-02
    • 1970-01-01
    相关资源
    最近更新 更多