无法在 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 中的应用程序创建的文件
Qt Designer 4.8 在 Mac OS X 10.7 上启动时崩溃