How to recognize KeyPress events using Qt and X11events?
I'm working in a project that need to recognize the physical keys' positions, Control, Shift and Winkey. I need to know where is each of then Left or Right in the Keyboard.
For that I need to handle X11events and WinEvents using Qt. I did it pretty well in Windows, forgetting the terrible part about Alt Gr, I can't handle yet. In Linux I tried to do the same:
#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");
}
bre开发者_运维问答ak;
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
in method x11Event the case XKeyPress (in debug mode, it's 2) is never satisfied but if you look to:
grep KeyPress /usr/include/X11/X.h
#define KeyPressMask (1L<<0)
#define KeyPress 2
The constant is correct but the type is never equal 2. If I change the constant XKeyPress to 28, looks like
maiko@cits-d530:release$ grep 28 /usr/include/X11/X.h
#define PropertyNotify 28
#define FirstExtensionError 128
works well.
Thx
I couldn't knew why it wasn't working. None x11events are called after a KeyPress, it is only called when I move the mouse then all events that didn't fire yet are fired. For that I was receiving all of events at the same type and I couldn't compare the type of each one because it was garbage.
To resolve this I implemented the QAbstractEventDispatcher in the main.cpp that's the owner of mainwindow.cpp (which is the receiver from my KeyPress events) 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();
but the method customEventFilter needs to be static. I changed all my code for that but works, customEventFilter can receive all system wide events, on linux or windows.
Bye.
精彩评论