Qt QShortCut和QSpinBox冲突

Qt QShortCut和QSpinBox冲突,qt,qt4,Qt,Qt4,我正在写一个应用程序,如果我使用自己的快捷方式。看起来是这样的: myShortcut= new QShortcut(Qt::SHIFT + Qt::Key_B,this); connect(myShortcut, SIGNAL(activated()), this, SLOT(setCameraBack())); 我在主窗口小部件的构造函数中定义了它,它工作正常,直到我单击主窗口小部件上的一个spinbox按钮。之后,我的快捷方式停止工作,直到我单击按钮或复选框,它才工作。当我这样做的时候,

我正在写一个应用程序,如果我使用自己的快捷方式。看起来是这样的:

myShortcut= new QShortcut(Qt::SHIFT + Qt::Key_B,this);
connect(myShortcut, SIGNAL(activated()), this, SLOT(setCameraBack()));
我在主窗口小部件的构造函数中定义了它,它工作正常,直到我单击主窗口小部件上的一个spinbox按钮。之后,我的快捷方式停止工作,直到我单击按钮或复选框,它才工作。当我这样做的时候,一切又都好了。我想补充一点,单击spinbox之后,它似乎处于“活动”状态(因为光标仍在其上“闪烁”),直到我单击其他按钮之一。你知道怎么了吗?这是某种过程或事件问题吗?谢谢你的回答 ~Marwroc

Qt的“监听”是一个快捷方式 当快捷方式的父级 小部件正在接收事件


当QSpinBox停止时,QShortcut对象的父对象不再接收事件。因此,在从QSpinBox中删除快捷方式之前,快捷方式不起作用。您可以通过传递到QShortcut的方法来更改此行为。

您是否尝试过
MySpinBox->setFocusPolicy(Qt::NoFocus)

在激活快捷方式之前,焦点小部件会收到一个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;
                }
            }
        }
    }
案例QEvent::ShortcutOverride:{
if(isReadOnly())
返回false;
QKeyEvent*ke=静态(ev);
if(ke==QKeySequence::Copy
||ke==QKeySequence::Paste
||ke==QKeySequence::Cut
||ke==QKeySequence::重做
||ke==QKeySequence::Undo
||ke==QKeySequence::MoveToNextWord
||ke==QKeySequence::MoveToPreviousWord
||ke==QKeySequence::MoveToStartOfDocument
||ke==QKeySequence::MoveToEndOfDocument
||ke==QKeySequence::选择下一步
||ke==QKeySequence::SelectPreviousWord
||ke==QKeySequence::SelectStartOffline
||ke==QKeySequence::SelectEndOfLine
||ke==QKeySequence::SelectStartOfBlock
||ke==QKeySequence::SelectEndOfBlock
||ke==QKeySequence::SelectStartOfDocument
||ke==QKeySequence::SelectAll
||ke==QKeySequence::SelectEndOfDocument){
ke->accept();
}如果(ke->modifiers()==Qt::NoModifier | | ke->modifiers()==Qt::ShiftModifier
||ke->modifiers()==Qt::KeypadModifier){
如果(ke->key()accept();
}否则{
开关(ke->key()){
案例Qt::键_删除:
案例Qt::键_Home:
案例Qt::关键点结束:
案例Qt::键_退格:
案例Qt::左键:
案例Qt::键右:
ke->accept();
违约:
打破
}
}
}
}
如果未按下控制键,此代码接受大多数键

因此,最简单的解决方案是更改快捷方式以包含控件修改器

或者,您可以将自旋框子类化并重写事件函数

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);
}
bool MySpinBox::事件(QEvent*event)
{
如果(事件->类型()==QEvent::ShortcutOverride&&!isReadOnly())
{
QKeyEvent*keyEvent=静态广播(事件);
//忽略“B”快捷方式
if(keyEvent->key()==Qt::key_B)
{
Q_ASSERT(!event->isAccepted());
返回true;
}
返回QSpinBox::事件(event);
}

谢谢您的回答。您是否知道如何解决此问题?我的意思是如何在每次“单击”后自动从QSpinBox中删除键盘焦点?@Marwroc我更新了答案。你试过
QShortcut::setContext
了吗?是的,我两个选项都试过了,但仍然不起作用;/我读了一些关于setFocusPolicy()的内容但我真的不知道如何使用它以及它是否是解决方案。@Marwroc你必须使用Shift-B吗?Ctrl-B或Alt-B可能有效。谢谢,它有效,但现在的问题是我不能在QSpinBox中键入任何内容,只需单击即可。我的QSpinBox的范围是从0到500,因此键入是非常必要的;/我找到了解决方案。我使用了setFocusPolicy(Qt::ClickFocus)打开主_小部件,现在它工作正常。再次感谢您的帮助;)