我在使用可以通过拖放重新排序的自定义项实现QListWidget时遇到了麻烦。问题是当我对项目进行快速双击(非常短的拖放)时,该项有时会从QListWidget中消失。
这是我的Widget的构造函数:
ListPopisiDragDrop::ListPopisiDragDrop(QWidget *parent) :
QListWidget(parent)
{
setSelectionMode(QAbstractItemView::SingleSelection);
setDragEnabled(true);
viewport()->setAcceptDrops(true);
setDefaultDropAction(Qt::MoveAction);
setDropIndicatorShown(true);
setDragDropMode(QAbstractItemView::InternalMove);
}
也是掉落事件:
void ListPopisiDragDrop::dropEvent(QDropEvent *event){
int startRow=currentIndex().row();
QListWidget::dropEvent(event);
int endRow=currentIndex().row();
//more code...
}
自定义项是通过从QAbstractItemDelegate实现paint()和sizeHint()函数来实现的。
当消失的项目出现问题时,甚至不会调用dropEvent。
我真的不知道发生了什么,如果我做错了什么。任何帮助表示赞赏。
谢谢!
编辑: 我在Symbian S60第5版手机上运行该应用程序。
EDIT2: 如果我将这一行添加到构造函数:
setDragDropOverwriteMode(true);
列表中的项目仍然会消失,但空行仍然存在。
EDIT3: 我已添加此代码以查看发生的情况:
bool ListPopisiDragDrop::event(QEvent *e){
qDebug()<<"new event, type: "<<e->type()<<", listCount: "<<this->count();
QListWidget::event(e);
}
当调用drop事件时,我还打印了“drop event”。这给了我以下输出:
...
[Qt Message] new event, type: 12 , listCount: 2
[Qt Message] new event, type: 12 , listCount: 2
[Qt Message] new event, type: 68 , listCount: 2
[Qt Message] DROPEVENT
[Qt Message] new event, type: 71 , listCount: 2
[Qt Message] new event, type: 12 , listCount: 2
[Qt Message] new event, type: 12 , listCount: 2
[Qt Message] new event, type: 68 , listCount: 2
[Qt Message] DROPEVENT
[Qt Message] new event, type: 71 , listCount: 2
[Qt Message] new event, type: 12 , listCount: 2
[Qt Message] new event, type: 12 , listCount: 2
[Qt Message] new event, type: 12 , listCount: 2
[Qt Message] new event, type: 68 , listCount: 2
[Qt Message] new event, type: 12 , listCount: 1
[Qt Message] new event, type: 12 , listCount: 1
[Qt Message] new event, type: 1 , listCount: 1
...
如您所见,在事件类型68之后,listCount从2更改为1(一个项目消失)。我还没有得到问题所在......
Edit4: 即使我不使用自定义项目,我也有同样的行为。仍然无法弄清楚出了什么问题。
Edit5: 即使是[1]中的示例在移动设备上进行测试时也具有相同的行为。 Qt版本可能有问题吗?我正在使用Qt for Symbian Devices 4.6.3 ...
[1] http://www.java2s.com/Code/Cpp/Qt/QListWidgetdraganddrop.htm
答案 0 :(得分:2)
我可以想到这种行为的两个原因:信号itemDoubleClicked在QListWidget中的某处处理并执行某些操作,或者当源和目标相同时,dropEvent中的“更多代码”会出现问题(您可以检查是否startRow等于endRow,在这种情况下什么都不做。)
编辑:
此计划是否适合您:
#include <QApplication>
#include <QListWidget>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QListWidget lw;
for(int i = 1; i < 10; ++i)
lw.addItem(new QListWidgetItem(QString("Item %1").arg(i)));
lw.setDragEnabled(true); // ***
lw.viewport()->setAcceptDrops(true); // ***
lw.setDefaultDropAction(Qt::MoveAction); // ***
lw.setDropIndicatorShown(true); // ***
lw.setDragDropMode(QAbstractItemView::InternalMove);
lw.show();
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
a.exec();
}
可删除包含三颗星的行。这个程序适用于使用Qt 4.7.1的Windows XP,使用VS2010编译。
答案 1 :(得分:1)
在桌面上遇到同样的问题,其中SelectionMode,InternalMove等完全如图所示。还有我自己的视图模型,所以我只是以这种方式返回:
Qt::ItemFlags MyModel::flags(const QModelIndex& index) const
{
if (index.isValid())
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled;
}
和我一起工作。