【发布时间】: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
关于如何解决这个问题的任何想法?
【问题讨论】: