Qt QKeyEvent nativeVirtualKey未定义
我需要QML应用程序中密钥的本机密钥代码。我在QML项中有以下密钥处理程序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
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))
}
}