Qt:在拖放过程中拦截键盘事件

问题描述 投票:0回答:1

在执行拖放操作时,我想在状态栏中显示一些关于特定放置操作的预期效果的额外提示。 为此,我重写了 DragMoveEvent(),它非常适合鼠标移动事件。

但是,键盘信号仅在 Qt 内部的某处进行评估(以切换建议的放置操作),但在运行拖放操作期间不会暴露。

我尝试重写 mousePress/ReleaseEvent()、event() 并安装 eventFilter()。

c++ linux qt drag-and-drop keyboard
1个回答
0
投票

以下实验似乎有效。至少对于哑剧数据来说, 由一个 url 列表组成。使用 Qt 5.15.8 在 Debian 12 上进行测试。

// A class, that accepts drops of dragged data.
class IListView ...
{
    ...
protected:
    // Redefined virtual method to receive the drop event from Qt.
    void dropEvent(QDropEvent *event) override;
    ...
signals:
    // A signal sending the event data from the drop event.
    void dir_dropped(QDropEvent *event);
    ...
private slots:
    // A slot, that receives the event data from the signal.
    void dir_drop(QDropEvent *event);
    ...
}

// The constructor.
IListView::IListView(...)
{
    ...
    // Connect signal and slot and request it to be queued.
    // The queued signal will be picked up when control returns to the
    // event loop. Normally this is used to transfer signals between threads.
    // Here we use it to complete the drop event before actually
    // processing it.
    connect(this, &IListView::dir_dropped, this, &IListView::dir_drop,
            Qt::QueuedConnection);
    ...
}

// The overridden method to receive the drop event from Qt.
void IListView::dropEvent(QDropEvent *event)
{
    // Apparently, keyboard events can't be received here.
    // Do a deep copy of the event and send that over a queued connection.
    QDropEvent *copied_event = new QDropEvent(*event);
    emit dir_dropped(copied_event);
    // On return from this method, the received event appears to be deleted.
    // Hence the deep copy.
    // Also it seems, that the block on keyboard events is removed.
}

// The slot, that receives the event data from the signal.
void IListView::dir_drop(QDropEvent *event)
{
    // Process the event, ask back to the user when needed.
    // (For example: Overwrite existing file? yes/no/yestoall/notoall).
    // Keyboard events can be received here as usual.
    ...
    // Finally delete the copied event.
    delete event;
}
© www.soinside.com 2019 - 2024. All rights reserved.