2011-04-12 111 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); 
}