QKeyEvent nativeVirtualKey अपरिभाषित है

Nov 17 2020

मुझे अपने QML एप्लिकेशन में एक कुंजी का मूल कुंजी कोड चाहिए। मेरे पास QML आइटम में निम्न प्रमुख हैंडलर हैं।

            Keys.onPressed: {
                console.log("Key: ", event.key)
                console.log("Native: ", event.nativeVirtualKey);
                event.accepted = true
            }

event.keyजब कुंजी का उपयोग, लेकिन ठीक काम करता है event.nativeVirtualKeyअपरिभाषित था। उदा।

qml: Key:  70
qml: Native:  undefined

क्या मेरे कोड में कुछ गड़बड़ है? मैं nativeVirtualKey कैसे प्राप्त कर सकता हूं?

मैं अब प्रलेखन में देख रहा हूं कि "नोट: मूल आभासी कुंजी 0 हो सकती है, भले ही कुंजी घटना में विस्तारित जानकारी हो।" https://doc.qt.io/qt-5/qkeyevent.html#nativeVirtualKey दुर्भाग्य से आभासी देशी कुंजी गायब होने का कारण कब या किन स्थितियों में है, इसका कोई उल्लेख नहीं है।

जवाब

3 eyllanesc Nov 17 2020 at 02:14

जैसा कि मैंने पहले से ही में बताया इस उत्तर : KeyEventनहीं एक QKeyEventलेकिन एक QObject कि कुछ गुण लेकिन सभी नहीं उजागर करता है। वर्कअराउंड एक QObject बनाना है जो आइटम के लिए एक इवेंट फ़िल्टर स्थापित करता है और उस संपत्ति को उजागर करता है:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem>

class KeyHelper: public QObject{
    Q_OBJECT
    Q_PROPERTY(QQuickItem* target READ target WRITE setTarget NOTIFY targetChanged)
public:
    using QObject::QObject;
    QQuickItem* target() const {
        return m_target;
    }
    void setTarget(QQuickItem* item){
        if(m_target)
            m_target->removeEventFilter(this);
        m_target = item;
        if(m_target)
            m_target->installEventFilter(this);
        Q_EMIT targetChanged(m_target);
    }
    bool eventFilter(QObject *watched, QEvent *event){
        if(watched == m_target && event->type() == QEvent::KeyPress){
            if(QKeyEvent *ke = static_cast<QKeyEvent *>(event))
                Q_EMIT nativeVirtualKeyChanged(ke->nativeVirtualKey());
        }
        return QObject::eventFilter(watched, event);
    }
signals:
    void nativeVirtualKeyChanged(quint32 nativeVirtualKey);
    void targetChanged(QQuickItem* item);
private:
    QPointer<QQuickItem> m_target;

};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    qmlRegisterType<KeyHelper>("qt.keyhelper", 1, 0, "KeyHelper");

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

#include "main.moc"
import QtQuick 2.12
import QtQuick.Window 2.12
import qt.keyhelper 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    Item {
        id: item
        focus: true
        anchors.fill: parent
    }
   KeyHelper{
       target: item
       onNativeVirtualKeyChanged: console.log(nativeVirtualKey)
    }
}
Mark Nov 17 2020 at 05:35

यहाँ @ eyllanesc के उत्तर का एक मामूली समायोजन है eventFilterजो QEvent को QVariantMap के रूप में पुन: व्यवस्थित करने के लिए बदलता है ताकि इसे सीधे उन कार्यों के साथ कहा जा सके जो KeyEventAPI की अपेक्षा करते हैं।

class KeyHelper: public QObject{
     ... // same as @ellyanesc's answer

     bool eventFilter(QObject *watched, QEvent *event){
         if(watched == m_target && event->type() == QEvent::KeyPress){
             if(QKeyEvent *ke = static_cast<QKeyEvent *>(event)) {
                 // it seems we cannot send the event in a signal since it doesnt inherit from QObject.
                 // copy the relevant values to an event object
                 QVariantMap eventObject;
                 eventObject["key"] = ke->key();
                 eventObject["modifiers"] = int(ke->modifiers());
                 eventObject["nativeVirtualKey"] = ke->nativeVirtualKey();
                 eventObject["nativeModifiers"] = ke->nativeModifiers();
                 Q_EMIT nativeKeyPress(eventObject);
             }
         }
         return QObject::eventFilter(watched, event);
     }

signals:
     void nativeKeyPress(QVariantMap event); 

     ... // same as @ellyanesc's answer
};

और फिर qml फ़ाइल में

        KeyHelper{
            target: ...
            onNativeKeyPress: {
                console.log("native key press ", JSON.stringify(event))
            }
         }