Qt QKeyEvent nativeVirtualKey未定义

Qt QKeyEvent nativeVirtualKey未定义,qt,qml,qt5,Qt,Qml,Qt5,我需要QML应用程序中密钥的本机密钥代码。我在QML项中有以下密钥处理程序 Keys.onPressed: { console.log("Key: ", event.key) console.log("Native: ", event.nativeVirtualKey); event.accepted = true

我需要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,即使密钥事件包含扩展信息。不幸的是,没有提到何时或哪些条件导致虚拟本机密钥消失。

正如我在中指出的:不是一个而是一个QObject,它公开了一些属性,但不是全部属性。解决方法是创建一个QObject,该QObject将事件筛选器安装到该项并公开该属性:

包括 包括 包括 类KeyHelper:公共QObject{ Q_对象 Q_属性QQuickItem*目标读取目标写入设置目标通知目标更改 公众: 使用QObject::QObject; QQuickItem*目标常量{ 返回m_目标; } 无效setTargetQQuickItem*项{ ifm_目标 m_target->removeEventFilterthis; m_目标=项目; ifm_目标 m_target->installEventFilterthis; Q_发射目标改变DM_目标; } bool eventFilterQObject*已监视,QEvent*事件{ ifwasted==m_目标和事件->类型==QEvent::KeyPress{ ifQKeyEvent*ke=静态事件 Q_EMIT nativeVirtualKeyChangedke->nativeVirtualKey; } 返回QObject::eventFilterwatched,事件; } 信号: void nativeVirtualKey变更了第32个nativeVirtualKey; 作废targetChangedQQuickItem*项; 私人: QPointer m_目标; }; int main argc,char*argv[] { QCoreApplication::setAttributeQt::AA_启用HighdDiscaling; QGUIGC,argv; qmlRegisterTypeqt.keyhelper,1,0,keyhelper; qqmlaplicationengine; const QUrl urlQStringLiteralqrc:/main.qml; QObject::connect&engine,&QQmlApplicationEngine::objectCreated, &应用程序,[url]QObject*obj,常量QUrl和objUrl{ 如果!obj&&url==objUrl QCoreApplication::exit-1; },Qt::QueuedConnection; engine.loadurl; 返回app.exec; } 包括main.moc
正如我在中已经指出的:不是一个而是一个QObject,它公开了一些属性,但不是全部。解决方法是创建一个QObject,该QObject将事件筛选器安装到该项并公开该属性:

包括 包括 包括 类KeyHelper:公共QObject{ Q_对象 Q_属性QQuickItem*目标读取目标写入设置目标通知目标更改 公众: 使用QObject::QObject; QQuickItem*目标常量{ 返回m_目标; } 无效setTargetQQuickItem*项{ ifm_目标 m_target->removeEventFilterthis; m_目标=项目; ifm_目标 m_target->installEventFilterthis; Q_发射目标改变DM_目标; } bool eventFilterQObject*已监视,QEvent*事件{ ifwasted==m_目标和事件->类型==QEvent::KeyPress{ ifQKeyEvent*ke=静态事件 Q_EMIT nativeVirtualKeyChangedke->nativeVirtualKey; } 返回QObject::eventFilterwatched,事件; } 信号: void nativeVirtualKey变更了第32个nativeVirtualKey; 作废targetChangedQQuickItem*项; 私人: QPointer m_目标; }; int main argc,char*argv[] { QCoreApplication::setAttributeQt::AA_启用HighdDiscaling; QGUIGC,argv; qmlRegisterTypeqt.keyhelper,1,0,keyhelper; qqmlaplicationengine; const QUrl urlQStringLiteralqrc:/main.qml; QObject::connect&engine,&QQmlApplicationEngine::objectCreated, &应用程序,[url]QObject*obj,常量QUrl和objUrl{ 如果!obj&&url==objUrl QCoreApplication::exit-1; },Qt::QueuedConnection; engine.loadurl; 返回app.exec; } 包括main.moc
这里是对@eyllanesc的答案的一个轻微调整,它取代了eventFilter,将QEvent重新打包为QVariantMap,这样就可以使用期望KeyEvent API的函数直接调用它


这里是对@eyllanesc的答案的一个轻微调整,它取代了eventFilter,将QEvent重新打包为QVariantMap,这样就可以使用期望KeyEvent API的函数直接调用它


出于某种原因,QML KeyEvent对象仅公开,而不公开nativeVIrtualKey。这对你有帮助吗?谢谢@JarMan,这是个bug吗?这可以解释我看到的行为。有没有文件解释什么是扫描码?我不熟悉这个概念。我不确定它的用途。我也不确定nativeVirtualKey的用途。但是,作为一个黑客式的解决方法,您可以做的一件事是创建一个事件过滤器,它接受所有关键事件,并将nativeVirtualKey复制到nativeScanCode属性中,然后使用这些值生成新的QKeyEvents
由于某些原因,QML KeyEvent对象仅公开,而不公开nativeVIrtualKey。这对你有帮助吗?谢谢@JarMan,这是个bug吗?这可以解释我看到的行为。有没有文件解释什么是扫描码?我不熟悉这个概念。我不确定它的用途。我也不确定nativeVirtualKey的用途。但是,作为一个黑客式的解决方法,您可以做的一件事是创建一个事件过滤器,它接受所有关键事件,并将nativeVirtualKey复制到nativeScanCode属性中,然后使用这些值生成新的QKeyEvents。我发布了这个相关问题。我甚至可以在事件筛选器中设置一个信号,该信号将重新发布附加了本机虚拟密钥的重复事件。我试图通过在筛选器中直接重新发出QEvent对象来简化代码,但在尝试从QML捕获信号时,该对象变得未定义。我明白了。我甚至可以在事件筛选器中设置一个信号,该信号将重新发布附加了本机虚拟密钥的重复事件。我试图通过在筛选器中直接重新发出QEvent对象来简化代码,但在尝试从QML捕获信号时,该对象变得未定义。
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)
    }
}
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
};
        KeyHelper{
            target: ...
            onNativeKeyPress: {
                console.log("native key press ", JSON.stringify(event))
            }
         }