如何将X11事件传递给QDialog

目前,我正在尝试将系统X11事件(在Linux上)传递给我创build的对象。 要做到这一点,我已经从我的QApplication安装了一个eventFilter到我的对象。 这是有效的,因为它获得了应用程序的所有事件。 不过,我也需要传递对象X11事件。

我继续前进,在我的对象中创build了一个x11Event,希望它能够接收来自X11的事件,但事实并非如此。

反正有X11事件直接传递给我的对象,在我的应用程序?

Solutions Collecting From Web of "如何将X11事件传递给QDialog"

您可以通过以下方式接收XEvent

  • 一个用QAbstractEventDispatcher::instance()->setEventFilter()设置的过滤函数,它将接收所有的XEvent
  • 一个使用qApp->setEventFilter()设置的过滤函数,它只接收针对应用程序的事件。
  • 重新实现虚函数QApplication::x11EventFilter
  • 为顶级窗口重新实现虚函数QWidget::x11Event (子窗口小部件不接收XEvent )。

以该顺序。 如果任何这些函数对任何事件都返回true ,则下一个函数将不会收到该事件。

有些事件也可以通过这些函数之间的Qt进行过滤,例如QWidget::x11Event没有接收到XKeyEvent (它被具有键盘焦点的小部件的QInputContext::x11FilterEvent函数过滤)。

有关更多详细信息,您应该查看Qt源代码: QEventDispatcher_x11.cpp和QApplication::x11ProcessEvent的函数QApplication::x11ProcessEvent

所以大部分情况下,如果只在QDialog派生类中重新实现x11Event函数,则应该已经获得大部分XEvent 。 如果你想要你的子部件也可以接收它们,你可以通过重新实现QDialog::x11Event手动调用他们的x11Event函数。

我现在没有我的开发机器,所以原谅我的语法。 我会做以下几点:

  1. 声明XEvent *为一个元类型:

    int main() { qRegisterMetatype<XEvent*>(); }

  2. 重新实现QApplication::x11EventFilter作为alexisdm建议

  3. 在QApplication重新实现中创建一个信号,例如:

    void dialogEvent(XEvent*);

  4. 比在你的应用程序的任何地方,你可以做到以下几点:

    QApplication *inst = QApllication::instance();

    MyApplication *myApp = qobject_cast<MyApplication*>(inst);

    if(myApp!= 0){

     connect(myApp, SIGNAL(dialogEvent(XEvent*), myDialog, SLOT(onXEvent(XEvent*)); 

    }

这样你可以在全球范围内访问x11事件。 作为替代,你可以随时重新实现:

 bool QWidget::x11Event ( XEvent * event ) 

为个别小部件