Details
-
Bug
-
Resolution: Out of scope
-
P3: Somewhat important
-
4.6.2
-
None
-
Windows XP Professional SP3
Description
I have implemented Drag and Drop in my QTreeWidget subclass (class MyTreeWidget : public QTreeWidget) and it works almost fine. The only problem I experience is: the first click after drag and drop action doesn't select the tree item.
I have written a complete minimalist example to demonstrate the problem (see attached main.cpp, MyTreeWidget.h, MyTreeWidget.cpp files). Steps to reproduce the problem:
1. Drag any item.
2. Click any item to select it - item is not getting selected.
I also looked at what is happening with a debugger. Method MyTreeWidget::mousePressEvent() is called when I click the item after Drag and Drop:
QtGuid4.dll!QTreeViewPrivate::expandOrCollapseItemAtPos(pos=
{...})QtGuid4.dll!QTreeView::mousePressEvent(event=0x0012d734)
drag_and_drop_example.exe!MyTreeWidget::mousePressEvent(e=0x0012d734)
QtGuid4.dll!QWidget::event(event=0x0012d734)
QtGuid4.dll!QFrame::event(e=0x0012d734)
QtGuid4.dll!QAbstractScrollArea::viewportEvent(e=0x0012d734)
QtGuid4.dll!QAbstractItemView::viewportEvent(event=0x0012d734)
QtGuid4.dll!QTreeView::viewportEvent(event=0x0012d734)
QtGuid4.dll!QAbstractScrollAreaPrivate::viewportEvent(event=0x0012d734)
QtGuid4.dll!QAbstractScrollAreaFilter::eventFilter(o=0x00a00bf8, e=0x0012d734)
QtCored4.dll!QCoreApplicationPrivate::sendThroughObjectEventFilters(receiver=0x00a00bf8, event=0x0012d734)
QtGuid4.dll!QApplicationPrivate::notify_helper(receiver=0x00a00bf8, e=0x0012d734)
QtGuid4.dll!QApplication::notify(receiver=0x00a00bf8, e=0x0012d734)
QtCored4.dll!QCoreApplication::notifyInternal(receiver=0x00a00bf8, event=0x0012d734)
QtCored4.dll!QCoreApplication::sendSpontaneousEvent(receiver=0x00a00bf8, event=0x0012d734)
QtGuid4.dll!QApplicationPrivate::sendMouseEvent(receiver=0x00a00bf8, event=0x0012d734, alienWidget=0x00a00bf8, nativeWidget=0x0012febc, buttonDown=0x65cc7fbc, lastMouseReceiver={...}
, spontaneous=true)
QtGuid4.dll!QETWidget::translateMouseEvent(msg=
)
QtGuid4.dll!QtWndProc(hwnd=0x0002067a, message=513, wParam=1, lParam=5439533)
In method
bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos) { Q_Q(QTreeView); // we want to handle mousePress in EditingState (persistent editors) if ((state != QAbstractItemView::NoState && state != QAbstractItemView::EditingState) || !viewport->rect().contains(pos)) return true; // MY COMMENT: here execution flow goes out of the method because of 'state' ... }
the value of a data-member 'state' is equal to QAbstractItemView :: DragSelectingState. So control flow goes out of this method with the return value equal to 'true'. It seems that QTreeWidget::mousePressEvent() or QTreeViewPrivate::expandOrCollapseItemAtPos calls don't perform all the necessary operations because of a premature return.
I have written a simple dirty-fix that prevents QTreeViewPrivate::expandOrCollapseItemAtPos() from returning in the 'if' statement (see code fragment above):
void MyTreeWidget::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) startPos = e->pos(); if (DragSelectingState == state()) // these two lines setState(NoState); // eliminate the problem QTreeWidget::mousePressEvent(e); }
With these two lines the items are getting selected on the first click (after Drag and Drop action) and everything seem to be working correctly.
Note 1: I can not reproduce this problem with QListWidget - if I replace QTreeWidget with QListWidget in this example, then the first click after Drag and Drop action does select items in the tree.
Note 2: Moving selected item using keyboard arrow keys is OK.