首页 > 解决方案 > 如何防止特定的 QTreeView 分支被拖动?

问题描述

我有一个QTreeView将一对列表表示为具有两个分支的树数据结构,并且我想启用在分支之间拖动元素。但是,我也想禁止拖动整个分支。有谁知道 Qt 是否支持指定QTreeView可以拖动的单个分支和节点?

标签: c++qtdrag-and-dropqtreeview

解决方案


解决方案

使用QStandardItem::setFlags仅在那些项目上设置Qt::ItemIsDragEnabled,您希望使其可拖动,例如:

item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);

有关更多信息,请参阅Qt::ItemFlags

例子

下面的示例创建两个项目列表,并允许项目从一个列表拖放到另一个列表,但列表本身保持固定,即不可拖动:

#include "MainWindow.h"
#include <QStandardItemModel>
#include <QTreeView>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    auto *view = new QTreeView(this);
    auto *model = new QStandardItemModel(this);
    auto *list1 = createItem(tr("List 1"), true);
    auto *list2 = createItem(tr("List 2"), true);
    auto *rootItem = model->invisibleRootItem();

    rootItem->setFlags(rootItem->flags() ^ Qt::ItemIsDropEnabled);

    list1->appendRow(createItem(tr("Item 1"), false));
    list1->appendRow(createItem(tr("Item 2"), false));
    list1->appendRow(createItem(tr("Item 3"), false));

    list2->appendRow(createItem(tr("Item 4"), false));
    list2->appendRow(createItem(tr("Item 5"), false));

    model->appendRow(list1);
    model->appendRow(list2);

    view->setModel(model);
    view->setDragEnabled(true);
    view->setAcceptDrops(true);
    view->setDefaultDropAction(Qt::MoveAction);
    view->expandAll();
    view->setRootIsDecorated(true);

    setCentralWidget(view);
    resize(300, 400);
}

QStandardItem *MainWindow::createItem(const QString &name, bool topLevel)
{
    auto *item = new QStandardItem(name);
    Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;

    if (topLevel)
        flags |= Qt::ItemIsDropEnabled;
    else
        flags |= Qt::ItemIsDragEnabled;

    item->setFlags(flags);

    return item;
}

推荐阅读