Ограничьте 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
}