无法在 Linux 上使用 Qt 4.8 从 3Dconnexion SpaceNavigator 获取事件

Posted

技术标签:

【中文标题】无法在 Linux 上使用 Qt 4.8 从 3Dconnexion SpaceNavigator 获取事件【英文标题】:Can't get Events from 3Dconnexion SpaceNavigator using Qt 4.8 with Linux 【发布时间】:2017-10-06 05:43:26 【问题描述】:

我正在 Linux 下使用 Qt 4.8 开发 3D 应用程序。现在我需要支持一个 3d 鼠标(3Dconnexion SpaceNavigator)。附带的 SDK 比较老派,使用 X11 检索事件。

我正在使用 SDK 提供的示例代码,并尝试将其与 Qt 4.8 合并。看起来设置鼠标正在工作(据我从调试输出中可以看出),但我没有得到任何带有 QWidget::x11Event(XEvent*) 的 XEvents。

我已经找到了使用 libudev 或 libusb 绕过 SDK 的解决方案,这两种方法目前都不适用于我:/

也许有人已经有了解决这个特定问题的方法?我无法想象现在每个人都在使用 X11 :)

这是我正在使用的 Qt 设置代码,调试输出看起来可以正常工作:

Display* pDisplay = QX11Info::display();

Atom event_motion  = XInternAtom( pDisplay, "MotionEvent", TRUE );
Atom event_press   = XInternAtom( pDisplay, "ButtonPressEvent", TRUE );
Atom event_release = XInternAtom( pDisplay, "ButtonReleaseEvent", TRUE );
Atom event_command = XInternAtom( pDisplay, "CommandEvent", TRUE );


std::cout << "MotionEvent: " << event_motion << std::endl;
std::cout << "ButtonPressEvent: " << event_press << std::endl;
std::cout << "ButtonReleaseEvent: " << event_release << std::endl;
std::cout << "CommandEvent: " << event_command << std::endl;

Atom ActualType;
int ActualFormat;
unsigned long NItems, BytesReturn;

Window root = RootWindow( pDisplay, DefaultScreen(pDisplay) );
std::cout << "root: " << std::hex << "0x" << root << std::dec << std::endl;
unsigned char* p_property;

Window app_window = (Window) this->window()->winId();

XGetWindowProperty( pDisplay, root, event_command, 0, 1, FALSE, 
    AnyPropertyType, &ActualType, &ActualFormat, &NItems, &BytesReturn, &p_property );

if (0!=p_property)

    Window wnd = *(Window*) p_property;
    XFree( p_property );

    std::cout << "magellan window number: " << std::hex << wnd << std::dec << std::endl;

    XTextProperty wnd_name;
    XGetWMName( pDisplay, wnd, &wnd_name );
    std::cout << "magellan window name: " << wnd_name.value << std::endl; 

    XGetWMName( pDisplay, app_window, &wnd_name );
    std::cout << "Found window property: " << wnd_name.value << " (" << std::hex << app_window << std::dec << ")" << std::endl;

    XEvent CommandMessage;
    CommandMessage.type = ClientMessage;
    CommandMessage.xclient.format = 16;
    CommandMessage.xclient.send_event = FALSE;
    CommandMessage.xclient.display = pDisplay;
    CommandMessage.xclient.window = wnd;
    CommandMessage.xclient.message_type = event_command;

    CommandMessage.xclient.data.s[0] = (short) XHigh32( app_window );
    CommandMessage.xclient.data.s[1] = (short) XLow32( app_window );
    CommandMessage.xclient.data.s[2] = 27695;

    if (0!=XSendEvent( pDisplay, wnd, FALSE, 0x0000, &CommandMessage ))
    
        std::cout << "Sent event to SpaceMouse" << std::endl;
    

    XSelectInput( pDisplay, app_window, NoEventMask );

感谢任何提示:)

【问题讨论】:

附带说明:SpaceNavigator 3D 鼠标本身可以工作,因此驱动程序等已启动并运行。 This 可能会有一些用处。我过去使用过非常相似的代码。 【参考方案1】:

在对 3d 鼠标进行了更多的修补之后,我得出的结论是,“官方”的方式会导致死胡同。驱动程序似乎不再正确支持 Linux。

所以我咬紧牙关,现在我正在使用 Linux 下的 /dev/input/event 从 3d 鼠标收集数据,这至少与 UI 无关。我打开设备并在单独的线程中读取数据(定期轮询设备)。

到目前为止效果很好。

【讨论】:

以上是关于无法在 Linux 上使用 Qt 4.8 从 3Dconnexion SpaceNavigator 获取事件的主要内容,如果未能解决你的问题,请参考以下文章

无法删除以前由 Win 7 上的 Qt 4.8 中的应用程序创建的文件

使用 QtDBus 支持构建 Qt 4.8

Qt5 和 Qt 4.8 中的模型和角色

Qt Designer 4.8 在 Mac OS X 10.7 上启动时崩溃

QVFB 无法显示 -- QT for Embedded linux 演示示例

Qt4.4如何获取用户设置路径