如何将X11事件传递给QDialog

时间:2012-01-27 23:30:24

标签: c++ linux qt qt4

目前,我正在尝试将系统X11事件(在Linux上)传递给我创建的对象。为此,我从QApplication向我的对象安装了一个eventFilter。这是有效的,因为它获取应用程序的所有事件。但是我也需要传递对象X11事件。

我继续在我的对象中创建了一个x11Event,希望它能从X11接收事件,但事实并非如此。

是否有将X11事件直接传递给我的应用程序内的对象?

2 个答案:

答案 0 :(得分:3)

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

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

按此顺序。如果这些函数中的任何一个为任何事件返回true,则下一个函数将不会收到该事件。

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

有关详情,请查看Qt来源:QEventDispatcher_x11.cpp和函数QApplication::x11ProcessEvent in QApplication_x11.cpp

因此,在大多数情况下,如果您仅重新实现x11Event派生类中的QDialog函数,则您应该已经收到大多数XEvent。如果您希望您的子窗口小部件也能接收它们,您可以在重新实现x11Event时手动调用QDialog::x11Event函数。

答案 1 :(得分:1)

我现在没有我的开发机器,请原谅我的语法。我会做以下事情:

  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*));
    

    }

  5. 这样您就可以全局访问x11事件。作为替代方案,您可以随时重新实现:

    bool QWidget::x11Event ( XEvent * event )
    
    个人小部件的