QTableView mouseRelease событие не вызывается, когда перетаскивание заканчивается, ошибка? - PullRequest
1 голос
/ 31 января 2012

Я просто хотел бы перехватить событие mouseRelease, когда пользователь перетаскивает элемент из QTableView и отпускает левую кнопку.

Я хочу выделить возможные зоны удаления в моем приложении, например, изменить фон виджета. Я начинаю с определения перетаскивания путем повторной реализации:

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

и испускаю собственный сигнал.

Теперь, когда дропзона изменилась, мне нужно отловить событие освобождения, чтобы перерисовать дропзону, как и раньше независимо от того, было ли перетаскивание выполнено успешно или нет!

Я пробовал разные модели, переопределяя 4 события мыши и eventFilter, но событие освобождения мыши никогда не перехватывалось.

Вот мой код:

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);
}

Итак, это ошибка? Если вы знаете трюк, это мне очень поможет.

Спасибо!

Edit: я не могу переопределить dropEvent для каждого виджета в моем приложении, если пользователь перетаскивает элемент в другое приложение, я все еще хочу перехватить событие release ...

Ответы [ 4 ]

1 голос
/ 20 августа 2015

Как уже говорилось выше, прошло 3 года, но благодаря последнему ответу я нашел еще более простое решение этой проблемы.

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();
}
1 голос
/ 12 марта 2015

Три года с тех пор, как этот вопрос был задан, и эта проблема Qt все еще существует в Qt 5.4.В последнее время у меня возникла та же проблема: уходит за пределы приложения и нет MouseReleaseEvent.Решение простое и не совсем хитрость:

MousePressEvent, который запускает перетаскивание, выглядит следующим образом (упрощенно):

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.
        }
    }
}

Трюк прост: drag-> exec ()запускает собственный цикл обработки событий, который завершается при отпускании кнопки мыши.Положение мыши после drag-> exec (); можно определить с помощью QCursor.

0 голосов
/ 21 мая 2013

Я столкнулся с подобной проблемой и не был рад узнать, что MouseReleaseEvent не запускается в конце перетаскивания.

Я просто использовал DragLeaveEvent и отключил свои переменные, как я сделал бы в MouseReleaseEvent.Если пользователь перетянет приложение и снова включит его, те ранее отключенные переменные будут повторно включены в DragMoveEvent (при условии, что оно принято).

По крайней мере, это был мой трюк.Надеюсь, это поможет.

0 голосов
/ 31 января 2012

Для QTableView вам необходимо переопределить три функции для поддержки dnd:

  • void dragEnterEvent ( QDragEnterEvent * event ) - в этой функции мышь входит в виджет
  • void QAbstractItemView::dragMoveEvent ( QDragMoveEvent * event ) - в этомФункция позволяет обновить выделенную зону выделения
  • void QAbstractItemView::dropEvent ( QDropEvent * event ) - в этой функции вы решаете, принимать ли событие
...