QKeyEvent nativeVirtualKey अपरिभाषित है
मुझे अपने 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 दुर्भाग्य से आभासी देशी कुंजी गायब होने का कारण कब या किन स्थितियों में है, इसका कोई उल्लेख नहीं है।
जवाब
जैसा कि मैंने पहले से ही में बताया इस उत्तर : 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)
}
}
यहाँ @ 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))
}
}