我已经在Qt论坛(这里:https://forum.qt.io/topic/101608/how-to-port-qapplication-x11eventfilter-to-xcb-qabstractnativeeventfilter)上发布了一个问题,但尚未成功,如果有人有解决方案,我也将其发布在这里。
现在这是上面链接中的第一篇文章:
我们目前正在将应用程序从Qt4移植到Qt5,关于如何将 MyApplication :: x11EventFilter 实现替换为随安装的 QAbstractNativeEventFilter 的文档很少。 QCoreApplication :: installNativeEventFilter (如https://doc.qt.io/qt-5/sourcebreaks.html#changes-to-qcoreapplication中所述)。 我们刚刚开始实施
MyXcbEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *)
,如“ Linux示例”部分的https://doc.qt.io/qt-5/qabstractnativeeventfilter.html#nativeEventFilter中所述。 并且,使用我们在网络上找到的内容,例如替换为 MyApplication 中的内容:
bool MyApplication::x11EventFilter(XEvent* p_event)
{
int eventType = p_event->type;
QSharedPointer<QEvent> eventToSend;
if (eventType == ButtonPress)
{
XButtonPressedEvent& bpe = p_event->xbutton;
const QPoint pos(bpe.x_root,bpe.y_root);
QWidget* widget = qApp->widgetAt(pos);
if (widget && widget->window() != qApp->activeWindow())
{
QPoint local_pos = widget->mapFromGlobal(pos);
eventToSend = QSharedPointer<QEvent>((QEvent*)new QMouseEvent(QEvent::MouseButtonPress, local_pos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
}
}
return false;
}
对于这样的事情(在 MyApplication 构造函数中调用 installNativeEventFilter(m_myXcbEventFilter)):
bool MyXcbEventFilter::nativeEventFilter(const QByteArray& p_eventType, void* p_message, long*)
{
if (p_eventType == "xcb_generic_event_t")
{
xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(p_message);
uint16_t xcbEventType = ev->response_type & ~0x80;
if (xcbEventType == XCB_BUTTON_PRESS)
{
xcb_button_press_event_t* buttonPressEvent = static_cast<xcb_button_press_event_t*>(p_message);
// Do stuff
}
}
}
但是我们从来没有落入 xcbEventType == XCB_BUTTON_PRESS ,相反,似乎(至少对于按钮按下/释放而言)存在我们可以转换为的 XCB_GE_GENERIC > xcb_ge_generic_event_t 具有 event_type 成员,该成员包含例如 XCB_BUTTON_PRESS ,然后代码更改为:
bool MyXcbEventFilter::nativeEventFilter(const QByteArray& p_eventType, void* p_message, long*)
{
if (p_eventType == "xcb_generic_event_t")
{
xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(p_message);
uint16_t xcbEventType = ev->response_type & ~0x80;
if (xcb_eventType == XCB_GE_GENERIC)
{
xcb_ge_generic_event_t* genericEvent = static_cast<xcb_ge_generic_event_t*>(p_message);
xcbEventType = genericEvent->event_type;
}
if (xcbEventType == XCB_BUTTON_PRESS)
{
xcb_button_press_event_t* buttonPressEvent = static_cast<xcb_button_press_event_t*>(p_message);
// Do stuff
}
}
}
现在,我们在按按钮时就陷入了 xcbEventType == XCB_BUTTON_PRESS ,但是强制转换为 xcb_button_press_event_t 似乎没有任何意义,因为 root_x , root_y , event_y 和 event_y 成员在我们单击的任何位置始终具有相同的值。
任何人都知道如何正确实现吗?
谢谢