2011-04-12 115 views
5

我寫了一個應用程序,我用我自己的快捷方式。它看起來像這樣:QShortCut和QSpinBox衝突

myShortcut= new QShortcut(Qt::SHIFT + Qt::Key_B,this); 
connect(myShortcut, SIGNAL(activated()), this, SLOT(setCameraBack())); 

我在主要部件的構造函數中定義它,直到我點擊紡紗器按鈕,它也位於主窗口部件之一,它工作正常。之後,我的快捷停止工作,它不工作,直到我點擊按鈕或複選框。當我這樣做時,一切都很好。我想補充說,我點擊spinbox後,它似乎是「活躍」(因爲光標仍然「閃爍」,直到我點擊其他按鈕之一)。你有什麼想法嗎?這是一種過程或事件問題嗎?感謝所有答案 〜Marwroc

回答

4

快捷方式是「聽了」通過Qt的 事件循環時快捷的父 小部件接收事件。

當QSpinBox有keyboard focus時,QShortcut對象的父對象不再接收事件。因此,直到keyboard focus從QSpinBox中刪除,快捷方式才起作用。您可以通過將Qt::WidgetWithChildrenShortcut or Qt::ApplicationShortcut傳遞給QShortcut的QShortcut::setContext方法來更改此行爲。

+0

謝謝您的回答。你可能有任何想法如何解決這個問題?我的意思是如何在每次「點擊」後自動從QSpinBox中刪除keyboard_focus? – Marwroc 2011-04-12 18:33:18

+0

@Marwroc我更新了答案。你嘗試過'QShortcut :: setContext'嗎? – 2011-04-12 18:35:11

+0

是的,我已經嘗試了這兩個選項,但它仍然不起作用; /我讀了一些關於setFocusPolicy(),但我不確定如何使用它,如果它是解決方案。 – Marwroc 2011-04-12 18:43:31

1

你試過MySpinBox -> setFocusPolicy (Qt::NoFocus)嗎?

+0

謝謝,它的工作原理,但現在的問題是,我不能輸入任何東西到QSpinBox只需點擊。我的QSpinBox的範圍是從0到500,所以打字是相當必要的;/ – Marwroc 2011-04-12 19:02:27

+0

我找到了解決方案。我在main_widget上使用了setFocusPolicy(Qt :: ClickFocus),現在它工作正常。再次感謝您的幫助;) – Marwroc 2011-04-12 19:17:24

2

在激活快捷方式之前,焦點窗口小部件會被指定一個ShortcutOverride事件。如果事件被接受,則關鍵事件被傳遞給小部件,並且快捷方式未被激活。

來源:https://wiki.qt.io/ShortcutOverride

看着Qt的源

QAbstractSpinBox::event(QEvent *event) 
{ 
    Q_D(QAbstractSpinBox); 
    switch (event->type()) { 
    ... 
    case QEvent::ShortcutOverride: 
     if (d->edit->event(event)) 
      return true; 
     break; 
    ... 
    } 
    return QWidget::event(event); 
} 

QAbstractSpinBox被允許內部編輯接受該事件。 QLineEdit遵循QLineControl。來自qt/src/gui/widgets/qlinecontrol.cpp

case QEvent::ShortcutOverride:{ 
     if (isReadOnly()) 
      return false; 
     QKeyEvent* ke = static_cast<QKeyEvent*>(ev); 
     if (ke == QKeySequence::Copy 
      || ke == QKeySequence::Paste 
      || ke == QKeySequence::Cut 
      || ke == QKeySequence::Redo 
      || ke == QKeySequence::Undo 
      || ke == QKeySequence::MoveToNextWord 
      || ke == QKeySequence::MoveToPreviousWord 
      || ke == QKeySequence::MoveToStartOfDocument 
      || ke == QKeySequence::MoveToEndOfDocument 
      || ke == QKeySequence::SelectNextWord 
      || ke == QKeySequence::SelectPreviousWord 
      || ke == QKeySequence::SelectStartOfLine 
      || ke == QKeySequence::SelectEndOfLine 
      || ke == QKeySequence::SelectStartOfBlock 
      || ke == QKeySequence::SelectEndOfBlock 
      || ke == QKeySequence::SelectStartOfDocument 
      || ke == QKeySequence::SelectAll 
      || ke == QKeySequence::SelectEndOfDocument) { 
      ke->accept(); 
     } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier 
        || ke->modifiers() == Qt::KeypadModifier) { 
      if (ke->key() < Qt::Key_Escape) { 
       ke->accept(); 
      } else { 
       switch (ke->key()) { 
       case Qt::Key_Delete: 
       case Qt::Key_Home: 
       case Qt::Key_End: 
       case Qt::Key_Backspace: 
       case Qt::Key_Left: 
       case Qt::Key_Right: 
        ke->accept(); 
       default: 
        break; 
       } 
      } 
     } 
    } 

如果還沒有按下控制鍵,則此代碼接受大多數鍵。

所以最簡單的解決方案是更改快捷方式以包含控件修飾符。

或者,你也可以繼承的旋轉框和重載事件函數

bool MySpinBox::event(QEvent *event) 
{ 
    if(event->type() == QEvent::ShortcutOverride && !isReadOnly()) 
    { 
     QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); 
     // Ignore 'B' shortcuts 
     if(keyEvent->key() == Qt::Key_B) 
     { 
      Q_ASSERT(!event->isAccepted()); 
      return true; 
    } 
    return QSpinBox::event(event); 
}