参考KeySequenceEdit控件吧快捷键限制为输入一个人
#include <QWidget>
#include <QKeySequence>
class KCustomKeySequenceEdit : public QWidget
{
Q_OBJECT
public:
explicit KCustomKeySequenceEdit(QWidget *parent = nullptr);
explicit KCustomKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent = nullptr);
~KCustomKeySequenceEdit();
QKeySequence getKeySequence() const;
void init();
int translateModifiers(Qt::KeyboardModifiers state, const QString &text);
void resetState();
void finishEditing();
void setMultiple(bool bMultiple) { _bMultiple = bMultiple; }
public Q_SLOTS:
void setKeySequence(const QKeySequence &k);
void clear();
Q_SIGNALS:
void editingFinished();
void keySequenceChanged(const QKeySequence &keySequence);
protected:
bool event(QEvent *) override;
void keyPressEvent(QKeyEvent *) override;
void keyReleaseEvent(QKeyEvent *) override;
QList<int> KCustomKeySequenceEdit::customPossibleKeys(QKeyEvent *e);
private:
QLineEdit *lineEdit;
QKeySequence keySequence;
int keyNum = 0;
int key;
int prevKey;
bool _bMultiple = false;
};
#include "KCustomKeySequenceEdit.h"
#include "qboxlayout.h"
#include "qlineedit.h"
KCustomKeySequenceEdit::KCustomKeySequenceEdit(QWidget *parent)
: QWidget(parent)
{
init();
}
/*!
Constructs a QKeySequenceEdit widget with the given \a keySequence and \a parent.
*/
KCustomKeySequenceEdit::KCustomKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent)
: KCustomKeySequenceEdit(parent)
{
setKeySequence(keySequence);
}
KCustomKeySequenceEdit::~KCustomKeySequenceEdit()
{
}
void KCustomKeySequenceEdit::init()
{
lineEdit = new QLineEdit(this);
lineEdit->setObjectName(QStringLiteral("qt_keysequenceedit_lineedit"));
keyNum = 0;
prevKey = -1;
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(lineEdit);
key = 0;
lineEdit->setFocusProxy(this);
lineEdit->installEventFilter(this);
resetState();
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
setFocusPolicy(Qt::StrongFocus);
setAttribute(Qt::WA_MacShowFocusRect, true);
setAttribute(Qt::WA_InputMethodEnabled, false);
// TODO: add clear button
}
int KCustomKeySequenceEdit::translateModifiers(Qt::KeyboardModifiers state, const QString &text)
{
int result = 0;
if (state & Qt::ControlModifier)
result |= Qt::CTRL;
if (state & Qt::MetaModifier)
result |= Qt::META;
if (state & Qt::AltModifier)
result |= Qt::ALT;
return result;
}
void KCustomKeySequenceEdit::resetState()
{
prevKey = -1;
lineEdit->setText(keySequence.toString(QKeySequence::NativeText));
}
void KCustomKeySequenceEdit::finishEditing()
{
resetState();
emit keySequenceChanged(keySequence);
emit editingFinished();
}
QKeySequence KCustomKeySequenceEdit::getKeySequence() const
{
return keySequence;
}
void KCustomKeySequenceEdit::setKeySequence(const QKeySequence &k)
{
resetState();
if (keySequence == k)
{
keyNum = k.count() > 0 ? 1 : 0;
return;
}
keySequence = k;
key = 0;
keyNum = 0;
if (k.count() > 0)
{
key = k[0];
keyNum = 1;
}
lineEdit->setText(k.toString(QKeySequence::NativeText));
emit keySequenceChanged(k);
}
void KCustomKeySequenceEdit::clear()
{
setKeySequence(QKeySequence());
}
bool KCustomKeySequenceEdit::event(QEvent *e)
{
switch (e->type()) {
case QEvent::Shortcut:
return true;
case QEvent::ShortcutOverride:
e->accept();
return true;
default:
break;
}
return QWidget::event(e);
}
void KCustomKeySequenceEdit::keyPressEvent(QKeyEvent *e)
{
int nextKey = e->key();
if (nextKey == Qt::Key::Key_Backspace)
{
clear();
emit editingFinished();
}
if (!_bMultiple)
{
if (!(nextKey >= Qt::Key_A && nextKey <= Qt::Key_Z ||
nextKey >= Qt::Key_F1 && nextKey <= Qt::Key_F12 ||
nextKey >= Qt::Key_0 && nextKey <= Qt::Key_9))
return;
}
if (prevKey == -1) {
clear();
prevKey = nextKey;
}
lineEdit->setPlaceholderText(QString());
if (nextKey == Qt::Key_Control
|| nextKey == Qt::Key_Shift
|| nextKey == Qt::Key_Meta
|| nextKey == Qt::Key_Alt
|| nextKey == Qt::Key_unknown) {
return;
}
QString selectedText = lineEdit->selectedText();
if (!selectedText.isEmpty() && selectedText == lineEdit->text()) {
clear();
if (nextKey == Qt::Key_Backspace)
return;
}
if (keyNum)
return;
if (_bMultiple)
{
if (e->modifiers() & Qt::ShiftModifier) {
QList<int> possibleKeys = customPossibleKeys(e);
int pkTotal = possibleKeys.count();
if (!pkTotal)
return;
bool found = false;
for (int i = 0; i < possibleKeys.size(); ++i) {
if (possibleKeys.at(i) - nextKey == int(e->modifiers())
|| (possibleKeys.at(i) == nextKey && e->modifiers() == Qt::ShiftModifier)) {
nextKey = possibleKeys.at(i);
found = true;
break;
}
}
if (!found)
nextKey = possibleKeys.first();
}
else
{
nextKey |= translateModifiers(e->modifiers(), e->text());
}
}
key = nextKey;
keyNum = 1;
QKeySequence key(key);
keySequence = key;
QString text = key.toString(QKeySequence::NativeText);
lineEdit->setText(text);
e->accept();
}
QList<int> KCustomKeySequenceEdit::customPossibleKeys(QKeyEvent *e)
{
QList<int> result;
if (!e->nativeScanCode()) {
if (e->key() && (e->key() != Qt::Key_unknown))
result << int(e->key() + e->modifiers());
else if (!e->text().isEmpty())
result << int(e->text().at(0).unicode() + e->modifiers());
return result;
}
else
{
QList<int> result;
if (e->key() && (e->key() != Qt::Key_unknown))
result << int(e->key() + e->modifiers());
else if (!e->text().isEmpty())
result << int(e->text().at(0).unicode() + e->modifiers());
return result;
}
}
void KCustomKeySequenceEdit::keyReleaseEvent(QKeyEvent *e)
{
if (prevKey == e->key()) {
if (keyNum )
finishEditing();
}
e->accept();
}