Ограничьте QKeySequence/QKeySequenceEdit только одним ярлыком

Можно ли ограничить QKeySequence показать только один ярлык в QKeySequenceEdit? В настоящее время он поддерживает до 4 ярлыков. Мое приложение поддерживает последовательности клавиш только одного ярлыка, например Ctrl+A или же Ctrl+C а не например Ctrl+A, D или же Ctrl+C, X, Z,

Можно ли ограничить QKeySequence или же QKeySequenceEdit только к одной последовательности клавиш?

4 ответа

Решение

Решил это, не лучшее решение, но быстрое... Если вы хотите что-то более индивидуальное, я думаю, что вы должны создать это самостоятельно...

customkeysequenceedit.h:

#ifndef CUSTOMKEYSEQUENCEEDIT_H
#define CUSTOMKEYSEQUENCEEDIT_H

#include <QKeySequenceEdit>

class QKeyEvent;

class CustomKeySequenceEdit : public QKeySequenceEdit
{
    Q_OBJECT

public:
    explicit CustomKeySequenceEdit(QWidget *parent = 0);
    ~CustomKeySequenceEdit();

protected:
    void keyPressEvent(QKeyEvent *pEvent);
};

#endif // CUSTOMKEYSEQUENCEEDIT_H

customkeysequenceedit.cpp:

#include "customkeysequenceedit.h"

#include <QKeyEvent>

CustomKeySequenceEdit::CustomKeySequenceEdit(QWidget *parent) : QKeySequenceEdit(parent) { }

CustomKeySequenceEdit::~CustomKeySequenceEdit() { }

void CustomKeySequenceEdit::keyPressEvent(QKeyEvent *pEvent)
{
    QKeySequenceEdit::keyPressEvent(pEvent);

    QKeySequence seq(QKeySequence::fromString(keySequence().toString().split(", ").first()));
    setKeySequence(seq);

}

Вы можете использовать [] оператор QKeySequence: http://doc.qt.io/qt-5/qkeysequence.html

Итак, в вашем конструкторе интерфейса напишите это:

connect(ui->editShortcut, &QKeySequenceEdit::editingFinished, 
        this, &dialog::truncateShortcut);

И добавьте этот приватный метод в ваш класс диалога:

void dialog::truncateShortcut()
{
    int value = ui->editShortcut->keySequence()[0];
    QKeySequence shortcut(value);
    ui->editShortcut->setKeySequence(shortcut);
}

Делая это, вы полностью уважаете API и не зависите от , персонаж, который довольно рискованно.

Большинство ответов заключается в том, чтобы обрезать ярлык после выполненного ввода . В любом случае, в процессе ввода будет отображаться более одного ярлыка , что немного раздражает.

Я нашел решение, которое даже не покажет более одного ярлыка .

После ввода одного ярлыка завершите ввод с помощью очистки фокуса иsetKeySequenceчерез класс переопределенияkeyPressEventфункция.

Более того, этот метод очень прост и грациозен!

Сначала создайте классmyKeySequenceEditунаследовано отQKeySequenceEdit, а ниже коды:

mykeysequenceedit.h:

      #ifndef MYKEYSEQUENCEEDIT_H
#define MYKEYSEQUENCEEDIT_H

#include <QKeySequenceEdit>
#include <QWidget>

class myKeySequenceEdit : public QKeySequenceEdit
{
    Q_OBJECT
public:
    myKeySequenceEdit(QWidget *parent = nullptr);

    void keyPressEvent(QKeyEvent *) override;
};

#endif // MYKEYSEQUENCEEDIT_H

mykeysequenceedit.cpp:

      #include "mykeysequenceedit.h"

myKeySequenceEdit::myKeySequenceEdit(QWidget *parent) : QKeySequenceEdit(parent) {}

void myKeySequenceEdit::keyPressEvent(QKeyEvent *event)
{
    QKeySequenceEdit::keyPressEvent(event);
    if (this->keySequence().count() > 0) {
        QKeySequenceEdit::setKeySequence(this->keySequence());
        
        emit editingFinished(); // Optinal, depend on if you need the editingFinished signal to be triggered
    }
}

Мой взгляд на это: зачем нам ждать в режиме редактирования, если нужен только единственный ярлык. Таким образом прерывая редактирование сразу после успеха:

      inline bool QKeySequence_valid( const QKeySequence& accelerator ){
    return !accelerator.isEmpty() && accelerator[0] != Qt::Key_unknown;
}

class Single_QKeySequenceEdit : public QKeySequenceEdit
{
protected:
    void keyPressEvent( QKeyEvent *e ) override {
        QKeySequenceEdit::keyPressEvent( e );
        if( QKeySequence_valid( keySequence() ) )
            editingFinished();
    }
};

Реальная реализация, потому что я изо всех сил пытался найти что-то вроде этого:

      class Single_QKeySequenceEdit : public QKeySequenceEdit
{
protected:
    void keyPressEvent( QKeyEvent *e ) override {
        QKeySequenceEdit::keyPressEvent( e );
        if( QKeySequence_valid( keySequence() ) )
            clearFocus(); // trigger editingFinished(); via losing focus 
                          // because this can still receive focus loss b4 getting deleted (practically because modal msgbox)
                          // and two editingFinished(); b no good
    }
    void focusOutEvent( QFocusEvent *event ) override {
        editingFinished();
    }
    bool event( QEvent *event ) override { // comsume ALL key presses including Tab
        if( event->type() == QEvent::KeyPress ){
            keyPressEvent( static_cast<QKeyEvent*>( event ) );
            return true;
        }
        return QKeySequenceEdit::event( event );
    }
};

void accelerator_edit( QTreeWidgetItem *item ){
        auto edit = new Single_QKeySequenceEdit;
        QObject::connect( edit, &QKeySequenceEdit::editingFinished, [item, edit](){
            const QKeySequence accelerator = edit->keySequence();
            item->treeWidget()->setItemWidget( item, 1, nullptr );
            if( QKeySequence_valid( accelerator ) )
                accelerator_alter( item, accelerator );
        } );
        item->treeWidget()->setItemWidget( item, 1, edit );
        edit->setFocus(); // track sanity gently via edit being focused property
}
Другие вопросы по тегам