0

私は QTreeWidget を使用して、親ノードのツリーとそのリーフ ノードを表示しています。各親はさまざまなリーフ ノードを持つことができますが、リーフ ノードは子を持つべきではありません。ユーザーは、葉を新しい位置にドラッグすることで、親の間で葉を移動できる必要があります。葉が他の葉に落とされないようにするために、親ノードItemIsDragEnabledを持っている間は葉だけを設定しました。ItemIsDropEnabledQTreeWidget が「SingleSelection」に設定されている場合、これは正常に機能します。ただし、SelectionMode が に設定されてExtendedSelectionいる場合は、リーフと親ノードを一緒に選択して、両方をリーフにドロップできます: http://i.stack.imgur.com/Kil3y.jpg (スクリーンショット)

サンプルコードは次のとおりです。

QTreeWidget *tree = this->ui->treeWidget;
QTreeWidgetItem *item;
QTreeWidgetItem *child;
tree->setSelectionMode(QAbstractItemView::ExtendedSelection);
tree->setDefaultDropAction(Qt::MoveAction);
tree->setDragEnabled(true);
tree->setAcceptDrops(true);
tree->setDropIndicatorShown(true);

// disable dropping of leaves as top level items
tree->invisibleRootItem()->setFlags( Qt::ItemIsSelectable |
                Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );

for (int i = 0; i < 2; i++) {
    // create top level item
    item = new QTreeWidgetItem();
    item->setText(0, "parent");
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
                  | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled );

    // add 3 child items
    for (int j = 0; j < 3; j++) {
        child = new QTreeWidgetItem();
        child->setText(0, "child");
        child->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
                      | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled );
        item->addChild(child);
    }

    // add item to tree
    tree->addTopLevelItem(item);
}

私はかなりグーグルで検索しましたが、解決策を思いつくことができませんでした。を使用している間、子ノードと親ノードをそれぞれのレベルに保つにはどうすればよいExtendedSelectionですか?

QTreeWidget をサブクラス化し、insertRows() をオーバーライドする必要がありますか? アクションが問題ないかどうかを確認できるように、QTreeWidget のドラッグ アンド ドロップ アクションをインターセプトする方法はありますか? (これを QStandardItemModel/QTreeView で動作させる方法があれば、私も嬉しいです)

4

1 に答える 1

0

itemSelectionChanged簡単な回避策の 1 つは、最後に選択したアイテムと同じタイプではないすべてのアイテムを選択から削除するシグナルに小さな関数を接続することです。私にとっては完璧に機能します(およびWarcraft 3トリガーエディターなどの他のプログラムでも)

于 2012-03-08T16:23:22.277 に答える