嵌入式Linux很多场景下需要自行制定Keyboard的keycode. 对于某个按键F8, Qt::Key_F8是Qt api, 是个固定值, 用于Qt application统一读取使用, 而缺省Linux把keycode映射为:
//src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h
const QBsdKeyboardMap::Mapping keymapDefault[] = {
{ 66, 0xffff, Qt::Key_F8, ModPlain, NoFlags, 0x0000 },
}
//qnamespace.h
Key_F8 = 0x01000037,
而嵌入式平台按键有限且要自行指定keycode, 这时不再使用上述keymapDefault的缺省实现. 比如将输入设备gpio keys实现为驱动 /dev/input/event1 (假如他的F8 keycode是82, 非66), 那么如何让Qt使用 /dev/input/event1 并使用新的 keycode--Key_F8 映射关系呢?
有以下几个步骤:
1. 使用qtapp/utilities/kmap2qmap工具将xxx.kmap(可编辑)生成xxx.qmap(二进制文件), xxx.kmap 内容可以是:
keymaps 0-127
...
#headset
keycode 82 = F8
...
2. 在启动Qt application前, 指定环境变量 QT_QPA_EVDEV_KEYBOARD_PARAMETERS, 其中包含了所使用的设备驱动/dev/input/event1 以及所定制的按键映射 xxx.qmap. 此外, 指定环境变量QT_QPA_EGLFS_NO_LIBINPUT 表示禁用 libinput 而使用 Qt 自带的 evdev handler用于接收并处理输入事件:
export QT_QPA_EVDEV_KEYBOARD_PARAMETERS=/dev/input/event0:/dev/input/event1:/dev/input/event2:/dev/input/event3:keymap=/usr/mbin/xxx.qmap
export QT_QPA_EGLFS_NO_LIBINPUT=1
3. 在Qt application的code中(比如qml)就可以使用通用的Qt::Key_F8了:
Item {
anchors.fill: parent
focus: true
Keys.onPressed: {
if (event.key >= Qt.Key_0 && event.key <= Qt.Key_9) {
console.log("digit key");
event.accepted = true;
}
}
Keys.onReleased: {
if (event.key == Qt.Key_F8) {
console.log("headset key");
event.accepted = true;
} else {
console.log("key=" + event.key);
}
}
}