1、楼主最近需要一个需求:在QLineEdit里面获取键盘的按键,并显示,保存并且响应
2、当然QLineEdit本身是无法支持此功能的,故封装了一个空间仅供参考
3、思路通过重载keyPressEvent实现
#pragma once
#include <QLineEdit>
#include <QKeyEvent>
#include <QFocusEvent>
class KeyLineEdit : public QLineEdit
{
Q_OBJECT
public:
KeyLineEdit(QWidget *parent = nullptr);
~KeyLineEdit();
public:
void setKey(int key);
int getKey();
void setText(QString qsText);
signals:
void sigKeyChange(int key);
protected:
void keyPressEvent(QKeyEvent *e) override;
private:
int m_key = Qt::Key_unknown;
};
#include "KeyLineEdit.h"
#include <QMessageBox>
#include <QTextEdit>
KeyLineEdit::KeyLineEdit(QWidget *parent /*= nullptr*/)
: QLineEdit(parent)
{
//设置setReadOnly能解决和输入法冲突的问题,但需要重新实现selected方法,否则选中状态不明显
//setReadOnly(true);
setText("无");
}
KeyLineEdit::~KeyLineEdit()
{
}
void KeyLineEdit::setKey(int key)
{
Qt::Key qkey = static_cast<Qt::Key>(key);
if (qkey != Qt::Key_unknown)
{
m_key = qkey;
setText(QKeySequence(qkey).toString());
}
else
{
m_key = Qt::Key_unknown;
setText("无");
}
}
int KeyLineEdit::getKey()
{
return m_key;
}
void KeyLineEdit::setText(QString qsText)
{
QLineEdit::setText(qsText);
}
void KeyLineEdit::keyPressEvent(QKeyEvent *e)
{
int uKey = e->key();
Qt::Key key = static_cast<Qt::Key>(uKey);
if (key == Qt::Key_unknown)
{
return;
}
//除去单个的特殊按键
if (key == Qt::Key_Control
|| key == Qt::Key_Shift
|| key == Qt::Key_Alt
|| key == Qt::Key_Enter
|| key == Qt::Key_Return
|| key == Qt::Key_Tab
|| key == Qt::Key_CapsLock
|| key == Qt::Key_Escape)
{
return;
}
if (key == Qt::Key_Backspace)
{
sigKeyChange(Qt::Key_unknown);
m_key = Qt::Key_unknown;
setText("无");
return;
}
bool bModifiers = false;
Qt::KeyboardModifiers modifiers = e->modifiers();
if (modifiers & Qt::ShiftModifier)
{
uKey += Qt::SHIFT;
bModifiers = true;
setText("无");
m_key = Qt::Key_unknown;
sigKeyChange(Qt::Key_unknown);
return;
}
if (modifiers & Qt::ControlModifier)
{
uKey += Qt::CTRL;
bModifiers = true;
}
if (modifiers & Qt::AltModifier)
{
uKey += Qt::ALT;
bModifiers = true;
}
//不支持单个数字 字母
bool bNum = (e->key() >= Qt::Key_0 && e->key() <= Qt::Key_9);
bool bChar = (e->key() >= Qt::Key_A && e->key() <= Qt::Key_Z);
if ((bNum || bChar) && !bModifiers)
{
QMessageBox::warning(NULL, QObject::tr("提示"), QObject::tr("快捷键不支持单独数字或者字母!"), QMessageBox::Yes);
setText("无");
m_key = Qt::Key_unknown;
sigKeyChange(Qt::Key_unknown);
return;
}
QString qsKey = QKeySequence(uKey).toString();
//除去Windows常用快捷键
QStringList blackList;
blackList << "CTRL+S" << "CTRL+C" << "CTRL+V" << "CTRL+A" << "CTRL+D" << "CTRL+Z" << "CTRL+X";
if (blackList.contains(qsKey, Qt::CaseInsensitive))
{
return;
}
setText(QKeySequence(uKey).toString());
m_key = key;
emit sigKeyChange(uKey);
}
当我们实现了此QLineEdit输入快捷键功能和,如何响应主程序呢?
1、我们可以使用QAction操作,设置快捷键后,响应QAction的SIGNAL(toggled(bool),然后试此信号和我们想要的槽链接起来即可
2、当我们需要重新设置按键的时候,需要删除前面设置的QAction,并且断开槽函数和SIGNAL(toggled(bool)的链接
3、因此我们需要存储快捷键和QAction的对应关系,使用QMap
QMap<int, QAction*> m_mAction;
void addAction(int shortCut, const char * slot)
{
QAction *act = new QAction(this);
act->setShortcut(shortCut);
act->setCheckable(true);
connect(act, SIGNAL(toggled(bool)), this, slot);
this->addAction(act);
m_mAction.insert(shortCut, act);
}
void delAction(int shortCut, const char * slot)
{
if (m_mAction.contains(shortCut))
{
QAction *act = m_mAction[shortCut];
if (act)
{
disconnect(act, SIGNAL(toggled(bool)), this, slot);
this->removeAction(act);
m_mAction.remove(shortCut);
delete act;
act = nullptr;
}
}
}