No se llama al evento QTableView mouseRelease cuando finaliza el arrastre, ¿error?

I would simply like to catch the mouseRelease event when a user drags an item from a QTableView and releases the left button.

I want to highlight possible dropping zones in my app, like changing the background of a widget. I start by detecting the drag-start by re-implementing:

void LibraryTableView::startDrag( Qt::DropActions supportedActions )
{
    m_dragReleased = false;
    emit dragStart();
    QTableView::startDrag(supportedActions);
}

and emitting my own signal.

Now that the dropzone has changed, I need to catch the release event to redraw the dropzone as before whether the drag and drop succeded or not !

I tried different models, reimplementing the 4 mouse events and eventFilter, but the Mouse Release Event is never catched.

Aquí está mi código:

void LibraryTableView::mouseDoubleClickEvent( QMouseEvent* event )
{
    QTableView::mouseDoubleClickEvent(event);
}

void LibraryTableView::mouseMoveEvent( QMouseEvent* event )
{
    qDebug() << "move";
    QTableView::mouseMoveEvent(event);
}

void LibraryTableView::mousePressEvent( QMouseEvent* event )
{
    qDebug() << "press";
    QTableView::mousePressEvent(event);
}

void LibraryTableView::mouseReleaseEvent( QMouseEvent* event )
{
    qDebug() << "real"; // Never called when drag ends ...
    QTableView::mouseReleaseEvent(event);
}

So, it is a bug ? If you know a trick, it would help me a lot.

Gracias !

Edit: I cannot reimplement dropEvent for every widget in my application, if the user drags and drop an element in another application, I still want to catch the release event ...

preguntado el 31 de enero de 12 a las 16:01

Drop event happens outside the table view? -

Then mouse release is "catched" on that widget. -

4 Respuestas

As said above it's been 3 years but thank to the last answer I found an even easier solution for this problem.

void LibraryTableView::startDrag( Qt::DropActions supportedActions )
{
    m_dragReleased = false;
    emit dragStart();
    QTableView::startDrag(supportedActions);

    //CODE HERE WILL BE EXECUTED ONLY WHEN THE MOUSE BUTTON HAS
    //BEEN RELEASED SO YOU CAN DO THE FOLLOWING
    emit dragStop();
}

Respondido 20 ago 15, 16:08

Three years since this question was asked and this Qt problem still exists in Qt 5.4. Lately I had the same problem: Drops outside the application and no MouseReleaseEvent. The solution is simple and not really a trick:

The mousePressEvent, which starts the drag&drop looks like this (simplified):

void DragNDropListView::mousePressEvent(QMouseEvent *event){
        ....
        QDrag *drag = new QDrag(this);
        QMimeData *mimeData = new QMimeData;
        mimeData->setData("application/x-xxxxxx", QByteArray());
        drag->setMimeData(mimeData);
        drag->exec();
            // The d&d ended here. Inside the widget where the drag
            // started, a mouseReleaseEvent would have been fired.
            // Outside this widget not.
            // drag->mimeData() is here still available.
        }
    }
}

The trick is simple: drag->exec() starts its own event loop, which is exited when the mouse button is released. The mouse position after drag->exec(); can be determined with QCursor.

respondido 12 mar '15, 23:03

Para QTableView you have to reimplement three function for dnd support:

  • void dragEnterEvent ( QDragEnterEvent * event ) - in this function the mouse enters the widget
  • void QAbstractItemView::dragMoveEvent ( QDragMoveEvent * event ) - in this function you can update your drop zone highlighting
  • void QAbstractItemView::dropEvent ( QDropEvent * event ) - in this function you decide whether to accept the event

Respondido el 31 de enero de 12 a las 21:01

The drop occurs in a different widget, the QTableView is dragOnly - Kirell

En ese caso el dropEvent should be reimplemented in the widget where the drop occurs. - Neox

If the user drops an element out of my application, I still want to catch the mouse Release ... Whether the widget accepts drop or not. - Kirell

I encountered a similar issue and was not happy to find out that the MouseReleaseEvent was not getting fired at the end of a drag.

I just used the DragLeaveEvent and toggled my variables off, as I would have done in the MouseReleaseEvent. If user dragged off the app, and then back on, those previously toggled off variables would get re-enabled in the DragMoveEvent (assuming it is accepted).

That was my trick, at least. Hope it helps.

contestado el 21 de mayo de 13 a las 14:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.