2013-04-17 252 views
1

在我正在構建的應用程序中,我實現了一個全局撤銷/重做系統,可通過常規快捷鍵Ctrl-Z和Ctrl-Shift-Z訪問該系統。QLineEdit撤銷/重做功能干擾全局撤銷/重做

我也使用QLineEdit字段,它們有自己的撤消/重做功能。無論何時觸發editFinished事件(按下輸入或焦點丟失),都會創建全局撤消事件。但是,如果您只需鍵入幾個字母,然後按Ctrl-Z,該字段將捕獲按鍵,使用其自己的撤消系統撤銷上次編輯,然後不會按下按鍵。

我想實現什麼是這樣的:

  1. 當QLineEdit的具有焦點和Ctrl-Z被按下,但也有在QLineEdit的無編輯撤消(當undoAvailable()爲假)我希望小部件忽略按鍵並將其傳遞給其父母。

  2. 當撤銷可用並且用戶在窗口小部件有焦點時(IE按下工具欄上的按鈕)調用撤銷/重做動作時,我希望它們被傳遞到此窗口小部件。

任何想法?

回答

1

從您的標籤,我猜你使用Python包裝到Qt。我的例子有C++代碼,但仍然適用於Python版本的Qt,如果這是你使用的。

它看起來像QObject :: eventFilter可能會做你正在尋找。您需要創建一個帶有eventFilter(QObject * sender,QEvent * event)的類作爲成員。對於你想跟蹤的每個QLineEdit,執行一些操作,比如'myLineEdit-> setEventFilter(eventFilterClassInstance);'

這使您可以攔截您安裝了事件過濾器的每個對象的所有QEvent。您可以在多個對象上安裝事件過濾器,然後通過設置它們的QObject開始過濾。最重要的是,如果您希望將事件作爲正常處理,則可以從eventFilter返回true;如果不應該看到該事件,則可以返回false。

既然你有興趣做撤銷/重做,你可以做isUndoAvailable()來檢查它是否是。

代碼可能是這樣的:

MyEventFilterClass::eventFilter(QObject *object, QEvent *event) 
{ 
    if (object == someLineEdit) { 
     if (event->type() == QEvent::KeyPress) { 
      QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); 

      int key = keyEvent->key(); 
      int mods = keyEvent->modifiers(); 
      if (mods == Qt::ShiftModifier && key == Qt::Key_Z) { 
       if (someLineEdit->undoAvailable()) { 
        someLineEdit->undo(); 
        return true; 
       } 
       else { 
        /* There are a few options here: */ 
        /* If you have a list of known parents, you could iter over them, and pick the right one. */ 
        /* Or maybe you want the event filter to emit a signal for the parents to see. */ 
        return true; 
       } 
      } 
     } 
    } 
} 

對於第二部分,你可以使用的QApplication :: focusWidget,看看當前具有焦點(我沒有測試這個雖然)。我有一個主窗口,它查看兩個可能的窗口來確定哪個窗口具有焦點,並將撤消操作應用於具有焦點的窗口。

我意識到你的問題很古老,但我希望這有助於。

+1

謝謝!我可以通過事件過濾器來捕捉按鍵,但我仍然無法讓它們冒泡到主應用程序。我可以傳遞一個引用並明確地調用它,但我仍然想知道是否有更好的方法:) –