将关键事件发送到 Qt QML WebEngineView

Sending Key Events to a Qt QML WebEngineView

本文关键字:Qt QML WebEngineView 事件      更新时间:2023-10-16

我有一个Qt QML WebEngineView,我想从自定义键盘发送按键事件。有没有办法以编程方式将按键事件发送到视图?需要明确的是,我只遇到了WebEngineViews的问题,而不是其他QML元素。

网上有一些关于如何使用QWidgets进行此操作的讨论,但我正在尝试使用Qt Quick/QML进行工作。

[1] https://forum.qt.io/topic/69439/how-do-you-send-key-events-to-qwebengineview-if-sendkey-doesn-t-work

你不能纯粹在QML端做到这一点,但你可以编写自己的QObject并将其注册为上下文属性。

类 KeyEventSender

#include <QObject>
#include <QGuiApplication>
#include <QQuickItem>
#include <QQuickWindow>
class KeyEventSender : public QObject
{
    Q_OBJECT
public:
    explicit KeyEventSender(QObject *parent = nullptr) : QObject(parent) {}
    Q_INVOKABLE void simulateKey(int key, Qt::KeyboardModifiers modifiers, const QString &text) {
        QQuickItem *r = qobject_cast<QQuickItem *>(QGuiApplication::focusObject());
        if (r) {
            bool autorep = false;
            QKeyEvent press = QKeyEvent(QKeyEvent::KeyPress, key, modifiers, text, autorep);
            r->window()->sendEvent(r, &press);
            QKeyEvent release = QKeyEvent(QKeyEvent::KeyRelease, key, modifiers, text, autorep);
            r->window()->sendEvent(r, &release);
        }
    }
};

在 main(( 中注册它

#include "keyeventsender.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    KeyEventSender k;
    engine.rootContext()->setContextProperty("keyEventSender",&k);

在 QML 中使用它:

    TextField {
        id: text
        anchors.centerIn: parent
        focus: true
    }
    Timer {
        interval: 2000; running: true; repeat: true
        property bool capital: false
        onTriggered: {
            if (!capital)
                keyEventSender.simulateKey(Qt.Key_K, Qt.NoModifier,"k")
            else
                keyEventSender.simulateKey(Qt.Key_K, Qt.ShiftModifier,"K")
            capital = !capital
        }
    }

请注意,焦点项获取关键事件。当计时器触发时,文本字段将像"kKkKkK"一样更新。

观察 QTBUG-46251 和 QTBUG-43602,WebEngineView 对滚动内容进行自己的键处理。

他们建议使用Action变通办法

ApplicationWindow {
    width: 1280
    height: 720
    visible: true
    WebEngineView {
        id: webview
        url: "http://www.qt-project.org"
        anchors.fill: parent
        focus: true;
    }
    Action {
        shortcut: "Escape"
        onTriggered: {
            console.log("Escape pressed.");
            Qt.quit();
        }
    }
}