2012-01-27 148 views
3

目前,我正在尝试将系统X11事件(在Linux上)传递给我创建的对象。为此,我从我的QApplication中将一个eventFilter安装到了我的对象上。这可以工作,因为它可以获取应用程序的所有事件。不过,我也需要传递对象X11事件。如何将X11事件传递给QDialog

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

无论如何要将X11事件直接传递给我的对象,在我的应用程序内?

+1

你介意解释你试图用更广泛的术语来做什么吗?您的应用程序需要接收X11事件的目的是什么? – thkala 2012-01-28 00:00:49

+0

你的“对象”是“QDialog”吗?你重新实现'QApplication :: x11EventFilter'是否返回'false'以允许重新实现'QDialog :: x11Event'函数接收事件? – alexisdm 2012-01-28 03:26:21

+0

@alexisdm我的印象是,如果XEvent没有被QApplication或父窗口部件传递,x11Event就无法接收XEvent?它是否正确? – Julio 2012-01-30 15:07:50

回答

3

您可以通过以下方式收到XEvent S:

  • 过滤功能与QAbstractEventDispatcher::instance()->setEventFilter()将接收所有XEvent S设定。
  • 设置为qApp->setEventFilter()的过滤器函数将只接收针对应用程序的事件。
  • 虚函数QApplication::x11EventFilter
  • 虚函数QWidget::x11Event为您的顶层窗口(S)重新实现的重新实现(子控件没有收到XEvent S)。

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

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

有关详细信息,你应该看看Qt的来源:QEventDispatcher_x11.cpp和功能QApplication::x11ProcessEvent in QApplication_x11.cpp

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

+0

我结束了重新实现QApplication :: x11EventFilter。混淆了我的返回错误并返回true,但它捕获了所有X11事件并打破了一些东西。但是弄清楚了,现在好像工作得很好:) – Julio 2012-01-30 20:23:36

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

    如果(对myApp!= 0){

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

    }

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

bool QWidget::x11Event (XEvent * event) 

各个部件

+0

我不确定这是个好主意。 Qt已经处理X11事件... – 2012-01-28 08:35:19

+0

我意识到这是过度杀毒,但仍然是一个可能的解决方案。除此之外,您不必在多个小部件上安装事件过滤器。 – Neox 2012-01-28 08:38:56