2012-01-27 151 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