开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜