Как имитировать событие нажатия клавиши в Qml? - PullRequest
0 голосов
/ 27 мая 2020

Я использую настраиваемую виртуальную клавиатуру с помощью Qml. Моя цель - имитировать физический сигнал нажатия клавиши реальной клавиатуры, когда я нажимаю кнопку на виртуальной клавиатуре. Я следил за учебником в Qt Virtual Keyboard и успешно создал и запустил пример кода.

Проблема в том, что в примере кода используется QCoreApplication :: sendEvent () функция в классе C ++ для отправки события нажатия клавиши в сфокусированный объект QObject. Он хорошо работает, когда я импортирую QtQuick.Controls 1.3 в main.qml в качестве руководства, но не действует, когда я меняю на QtQuick.Controls 2.2 , что имеет важное значение в моем приложении. Вот основная часть кода примера:

void KeyEmitter::emitKey(Qt::Key key)
{
    QQuickItem* receiver = qobject_cast<QQuickItem*>(QGuiApplication::focusObject());
    if(!receiver) {
        return;
    }
    QKeyEvent pressEvent = QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, QKeySequence(key).toString());
    QKeyEvent releaseEvent = QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier);
    QCoreApplication::sendEvent(receiver, &pressEvent);
    QCoreApplication::sendEvent(receiver, &releaseEvent);
}

Итак, как я могу отправить событие нажатия клавиши в свое приложение? Любая помощь будет принята с благодарностью.

Спасибо,

Ответы [ 2 ]

1 голос
/ 28 мая 2020
• 1000 *

Попробуйте следующее:

файл keyemitter.h (только заголовок, вам не нужен cpp файл):

#ifndef KEYEMITTER_H
#define KEYEMITTER_H
#include <QObject>
#include <QCoreApplication>
#include <QKeyEvent>
class KeyEmitter : public QObject
{
    Q_OBJECT
public:
    KeyEmitter(QObject* parent=nullptr) : QObject(parent) {}
    Q_INVOKABLE void keyPressed(QObject* tf, Qt::Key k) {
        QKeyEvent keyPressEvent = QKeyEvent(QEvent::Type::KeyPress, k, Qt::NoModifier, QKeySequence(k).toString());
        QCoreApplication::sendEvent(tf, &keyPressEvent);
    }
};
#endif // KEYEMITTER_H

main. cpp file:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext>
#include "keyemitter.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQuickView view;
    KeyEmitter keyEmitter;
    view.rootContext()->setContextProperty("keyEmitter", &keyEmitter);
    view.setSource(QStringLiteral("qrc:/main.qml"));
    view.show();
    return app.exec();
}

файл main.qml:

import QtQuick 2.12
import QtQuick.Controls 2.12
Rectangle {
    anchors.fill: parent
    color: "red"
    Column{
        Row {
            TextField {
                id: tf
                Component.onCompleted: { console.log(tf); }
                text: "123"
            }
        }
        Row {
            Button {
                text: "1"
                onClicked: keyEmitter.keyPressed(tf, Qt.Key_1)
            }
            Button {
                text: "2"
                onClicked: keyEmitter.keyPressed(tf, Qt.Key_2)
            }
            Button {
                text: "3"
                onClicked: keyEmitter.keyPressed(tf, Qt.Key_3)
            }
        }
        Row {
            Button {
                text: "DEL"
                onClicked: keyEmitter.keyPressed(tf, Qt.Key_Backspace)
            }
            Button {
                text: "OK"
                onClicked: keyEmitter.keyPressed(tf, Qt.Key_Enter)
            }
            Button {
                text: "ESC"
                onClicked: keyEmitter.keyPressed(tf, Qt.Key_Escape)
            }
        }
    }
}

0 голосов
/ 05 сентября 2020

Спасибо @ Ponzifex,

Вы правы. Когда я нажимаю кнопку на настраиваемой клавиатуре, объект фокуса немедленно изменяется на нажатую кнопку вместо текстового поля, как я хочу.

Просто изменение focusPolicy кнопки на NoFocus решает мою проблему.

Button {
    id: btnOne                
    focusPolicy: Qt.NoFocus
    text: qsTr("1")
    onClicked: {
        keyEmitter.emitKey( Qt.Key_1 )
    }
}
...