Конфликт QShortCut и QSpinBox - PullRequest
       0

Конфликт QShortCut и QSpinBox

5 голосов
/ 12 апреля 2011

Я пишу приложение, где я использую свой собственный ярлык.Это выглядит так:

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

Я определил его в конструкторе основного виджета, и он работает нормально, пока я не нажму одну из кнопок spinbox, которые также расположены в главном виджете.После этого мой ярлык перестает работать, и он не работает, пока я не нажму кнопку или флажок.Когда я делаю это, все снова хорошо.Я хотел бы добавить, что после того, как я нажимаю spinbox, он кажется «активным» (потому что курсор все еще «мигает» на нем), пока я не нажму одну из других кнопок.Ты хоть представляешь, что не так?Это какая-то проблема процесса или события?Спасибо за все ответы ~ Marwroc

Ответы [ 3 ]

4 голосов
/ 12 апреля 2011

Ярлык "прослушивается" Qt's цикл событий, когда родитель ярлыка Виджет получает события.

Когда QSpinBox имеет фокус клавиатуры , родительский объект объекта QShortcut больше не получает события. Поэтому ярлык не работает до тех пор, пока фокус клавиатуры не будет удален из QSpinBox. Вы можете изменить это поведение, передав Qt :: WidgetWithChildrenShortcut или Qt :: ApplicationShortcut методу QShortcut :: setContext вашего QShortcut.

2 голосов
/ 10 мая 2016

Прежде чем активировать ярлык, виджет фокусировки получает событие 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);
}
1 голос
/ 12 апреля 2011

Вы пробовали MySpinBox -> setFocusPolicy (Qt::NoFocus)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...