将 QKeySequence/QKeySequenceEdit 限制为只有一个快捷方式

Limit QKeySequence/QKeySequenceEdit to only one shortcut

本文关键字:有一个 快捷方式 QKeySequence QKeySequenceEdit      更新时间:2023-10-16

是否可以将QKeySequence限制为仅显示一个QKeySequenceEdit快捷方式?目前,它最多支持4个快捷方式。我的应用程序仅支持一个快捷键的键序列,例如 Ctrl+ACtrl+C,而不是例如 Ctrl+A, DCtrl+C, X, Z .

是否可以将QKeySequenceQKeySequenceEdit限制为仅一个键序列?

解决了,不是最好的解决方案,但很快...如果你想要更多定制的东西,我认为你必须自己构建它......

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

自定义键序列编辑.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#operator-5b-5d

所以在你的接口构造函数中,写这个:

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,并且不依赖于,字符,这是非常危险的。

大多数答案是在输入完成后截断快捷方式。无论如何,它在输入过程中会显示多个shorcut,这有点烦人。

我找到了一个甚至不会显示超过一个 shorcut 的溶液。

输入

一个快捷方式后,通过清晰的焦点完成输入,并通过类keyPressEvent函数的覆盖QKeySequenceEdit setKeySequence

更重要的是,这种方法非常简单和优雅!

首先创建一个从QKeySequenceEdit myKeySequenceEdit继承的类,下面是代码:

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
}
相关文章: