【问题标题】:How to recognize KeyPress events using Qt and X11events?如何使用 Qt 和 X11events 识别 KeyPress 事件?
【发布时间】:2011-08-18 12:04:35
【问题描述】:

我正在从事一个需要识别物理键位置、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

效果很好。

谢谢

【问题讨论】:

  • 有时你说KeyPress(不带X),有时你说XKeyPress——你确定你在正确的地方用了正确的名字吗?
  • 我不明白你的评论。我在需要的地方使用 XKeyPress。 #ifdef KeyPress 常量 int XKeyPress = KeyPress; #undef KeyPress //(在这个undef之后我不能单独使用KeyPress)

标签: qt cross-platform x11 keypress


【解决方案1】:

我不知道为什么它不起作用。在 KeyPress 之后没有调用 x11events,它仅在我移动鼠标时调用,然后所有尚未触发的事件都会被触发。为此,我收到了相同类型的所有事件,我无法比较每个事件的类型,因为它是垃圾。

为了解决这个问题,我在 main.cpp 中实现了 QAbstractEventDispatcher,它是 mainwindow.cpp 的所有者(它是我的 KeyPress 事件的接收器) ma​​in.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 上接收所有系统范围的事件。

再见。

【讨论】:

    猜你喜欢
    • 2021-03-14
    • 2016-10-19
    • 2019-10-21
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    相关资源
    最近更新 更多