我正在一个需要识别物理键位置,Control,Shift和Winkey的项目中工作。我需要知道键盘中每个左侧或右侧的位置。
为此,我需要使用Qt处理X11events和WinEvents。我在Windows中做得很好,忘记了Alt Gr的可怕部分,我无法处理。在Linux中,我试图做同样的事情:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#if WIN32
#include <windows.h>
#else
#include <X11/XKBlib.h>
#ifdef KeyPress
const int XKeyPress = KeyPress;
#undef KeyPress
#endif
#endif
#include "main.h"
#include <QFile>
#include <QDebug>
#include <QX11Info>
#if WIN32
bool MainWindow::winEvent( MSG* msg, long* result )
{
if(msg->message == WM_KEYDOWN || msg->message == WM_HOTKEY)
{
SHORT state;
switch(msg->wParam)
{
case VK_CONTROL:
// the Alt Gr is handled using Ctrl+Alt+Shift (I Guess)
state = GetKeyState(VK_SHIFT);
if(state == TRUE)
keyPressEvent(msg->wParam, "Key_AltGr");
else{
state = GetKeyState(VK_LCONTROL);
if(state & VK_LCONTROL)
keyPressEvent(msg->wParam, "Key_ControlL");
else
keyPressEvent(msg->wParam, "Key_ControlR");
}
break;
case VK_SHIFT:
state = GetKeyState(VK_LSHIFT);
if(state & VK_LSHIFT)
keyPressEvent(msg->wParam, "Key_ShiftL");
else
keyPressEvent(msg->wParam, "Key_ShiftR");
break;
case VK_MENU:// alt
state = GetKeyState(VK_SHIFT);
if(state == TRUE)
keyPressEvent(msg->wParam, "Key_AltGr");
break;
case VK_SNAPSHOT:
keyPressEvent(msg->wParam, "Key_Print");
break;
default:
return false;
}
return true;
}
return false;
}
#else
bool MainWindow::x11Event(XEvent *xe)
{
switch(xe->type)
{
case XKeyPress:
switch (xe->xkey.keycode)
{
case 37://Control_L
keyPressEvent(xe->xkey.keycode, "Key_ControlL");
break;
case 105://Control_R
keyPressEvent(xe->xkey.keycode, "Key_ControlR");
break;
case 50://Shift_L
keyPressEvent(xe->xkey.keycode, "Key_ShiftL");
break;
case 62://Shift_R
keyPressEvent(xe->xkey.keycode, "Key_ShiftR");
break;
case 133://Super_L
keyPressEvent(xe->xkey.keycode, "Key_SuperL");
break;
case 134://Super_R
keyPressEvent(xe->xkey.keycode, "Key_SuperR");
break;
default:
return false;
}
return true;
break;
}
return false;
}
#endif
方法x11Event案例XKeyPress(在调试模式下,它是2)永远不会满足,但是如果你看:
grep KeyPress /usr/include/X11/X.h
#define KeyPressMask (1L<<0)
#define KeyPress 2
常量是正确的,但类型永远不会相等2.如果我将常量XKeyPress更改为28,看起来像
maiko@cits-d530:release$ grep 28 /usr/include/X11/X.h
#define PropertyNotify 28
#define FirstExtensionError 128
效果很好。
THX
答案 0 :(得分:1)
我不知道为什么它不起作用。在KeyPress之后没有调用x11events,只有当我移动鼠标时才调用它,然后触发所有尚未触发的事件。为此,我收到了相同类型的所有事件,我无法比较每个事件的类型,因为它是垃圾。
要解决这个问题,我在main.cow中实现了QAbstractEventDispatcher,它是mainwindow.cpp的所有者(来自我的KeyPress事件的接收者) 的的main.cpp 强>
QAbstractEventDispatcher *evInstance = QAbstractEventDispatcher::instance(0);
evInstance->setEventFilter((QAbstractEventDispatcher::EventFilter) MainWindow::customEventFilter);
MainWindow *w = new MainWindow(program.getLayoutFile(), program.getUnicode());
w->show();
a.exec();
但是方法customEventFilter需要是静态的。我更改了所有代码,但是工作正常,customEventFilter可以在linux或windows上接收所有系统范围的事件。
再见。