文章目录
QKeyEvent键盘事件
- 构造函数:
QKeyEvent(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, const QString &text = QString(), bool autorep = false, ushort count = 1)
- 参数说明:
-
type
--> 事件的类型(QEvent::KeyPress、QEvent::KeyRelease、QEvent::ShortCutOverride) -
key
--> 产生事件的按键键值(在Qt::Key枚举查看, 通常字符于对应ascll码值是一致的) -
modifiers
– 修饰符,用以判断是否是组合按键,有以下值(可以用位或进行组合)Qt::NoModifier
-
Qt::ShiftModifier
--> shift键被同时按下 -
Qt::ControlModifier
--> ctrl键被同时按下,以下类似 Qt::AltModifier
-
Qt::MetaModifier
--> win键 Qt::KeypadModifier
Qt::GroupSwitchModifier
-
text
--> 字符信息,当key是一个字符输入时,则在相应的则在焦点组件输入字符信息,否则text为无效 - (例如:key = Qt::key_0,则焦点输入组件输入字符’0’,key = Qt::Key_backspace,则text无效,而是表示退格键按下)
-
autorep
--> 是否是自动重复按键 -
count
--> 事件中涉及按键的数量
-
- 成员函数:
-
bool matches(QKeySequence::StandardKey key) const
- 匹配按键所触发的标准行为(例如:复制(QKeySequence::Copy))
- 匹配成功返回true,否则返回false
-
- 事件处理函数:
-
QWidget::keyPressEvent(QKeyEvent *)
--> 有按键被按压 -
QWidget::keyReleaseEvent(QKeyEvent *)
--> 有按键被释放
-
- 软键盘制作思路:
- 按钮布局,定义槽函数(最好使用按钮组, 或者直接派生QPushButton在自定义的按钮中定义槽函数,避免为每个按钮都定义槽函数)
setFocusPolicy(Qt::NoFocus)
设置软件盘按钮的焦点策略为Qt::NoFocus, 防止点击软键盘按键后输入框失去焦点,无法正常输入- 在槽函数中根据所按下的按钮创建相应的
QKeyEvent
事件对象keyeventobj - 用
void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority)
函数向焦点组件发送按键事件- 参数说明:
- receiver为事件接收的对象(这里为对应按钮)
- event创建的键盘事件keyeventobj(Event为QKeyEvent的基类,所以是兼容的)
- priority事件优先级(APPlication对象会对所有产生的事件按优先级排序,顺序派发处理)
- 参数说明:
- 可以通过
QApplication::FocusWidget()
获得当前焦点组件(例如TextEidt类对象)
- 自定义键盘于鼠标的组合键(eg.Ctrl+鼠标左键)事件思路:
- 自定义鼠标按压事件
- 在进入鼠标按压事件处理函数中做如下判断:
- 判断鼠标按下的具体键
- 判断键盘按键修饰符(通过函数
QApplication::keyboardModifiers()
可返回按下的Modifiers)
- 如果判断为Ctrl和鼠标左键按下,则执行相应的操作
改变焦点的方式以及策略(focusPolicy)
- 改变方式:
- Tab键或者Shift+Tab
- 鼠标点击
- 鼠标滚轮
- 代码
setFocus()
- focusPolicy:
-
Qt::TabFouc
--> 可通过Tab获得焦点 -
Qt::ClickFocus
--> 可通过点击获得焦点 -
Qt::StrongFocus
--> 可通过上述两种方式获得焦点 -
Qt::NoFocus
--> 不能通过上述方式获得焦点,但setFocus()仍然有效
-
简单软键盘(部分按键)制作代码:
- 效果:
自定义派生PushButton类的头文件btkey.h
#ifndef BTKEY_H
#define BTKEY_H
#include <QPushButton>
#include <QKeyEvent>
#include <QApplication>
#include <QObject>
#include "mykeyboard.h"
#include <QDebug>
class Btkey : public QPushButton
{
Q_OBJECT
public:
// 用两个bool静态成员来表示键盘的caps和shift键是否按下
static bool capstatus;
static bool shiftstatus;
Btkey(QWidget *parent = nullptr);
~Btkey();
private slots:
void handler_slot(bool k);
};
#endif // BTKEY_H
自定义派生PushButton类的源文件btkey.cpp
#include "btkey.h"
bool Btkey::capstatus = false;
bool Btkey::shiftstatus = false;
Btkey::Btkey(QWidget *parent) :
QPushButton(parent)
{
// 将按钮的颜色置为半透明的蓝色
this->setStyleSheet("background-color: rgba(153, 215, 255, 150);");
// 设置焦点获得策略
this->setFocusPolicy(Qt::NoFocus);
// 链接槽函数
connect(this, SIGNAL(clicked(bool)), this, SLOT(handler_slot(bool)));
}
Btkey::~Btkey()
{
this->destroy();
}
void Btkey::handler_slot(bool k)
{
QApplication::keyboardModifiers();
auto *objfous = QApplication::focusWidget();
bool ok;
int key = this->text().toInt(&ok, 16);
QString text(this->text());
qDebug() << this->text();
if(this->text() == "CapsLK"){
qDebug() << "按下CapsLk键";
capstatus = k;
qobject_cast<MyKeyBoard *>(this->parent())->letterToggle();
text = "";
}else if(this->text() == "Shift"){
qDebug() << "按下Shift键";
shiftstatus = k;
qobject_cast<MyKeyBoard *>(this->parent())->letterToggle();
key = Qt::Key_Shift;
text = "";
}else if(this->text() == "Enter"){
qDebug() << "按下Enter键";
key = Qt::Key_Enter;
}else if(this->text() == "Backspace"){
qDebug() << "按下BackSpace键";
key = Qt::Key_Backspace;
}else if(this->text() == "Tab"){
qDebug() << "按下Tab键";
key = Qt::Key_Tab;
}else{
qDebug() << "按下数字、字母或符号";
}
// 创建相应的按键事件对象
QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, key
, Qt::NoModifier, text
, false, 1);
// fousWidget() 返回光标所在的对象
// 派发事件
QCoreApplication::postEvent(objfous, event);
// 如果shift被按下,且又按下其他键,将让shift键弹起
if(shiftstatus && key != Qt::Key_Shift){
shiftstatus = false;
qobject_cast<MyKeyBoard *>(this->parent())->shift_recover();
qobject_cast<MyKeyBoard *>(this->parent())->letterToggle();
}
}
软键盘类的头文件mykeyboard.h
#ifndef MYKEYBOARD_H
#define MYKEYBOARD_H
#include <QWidget>
#include "btkey.h"
#include <QButtonGroup>
#include <QBrush>
QT_BEGIN_NAMESPACE
namespace Ui { class MyKeyBoard; }
QT_END_NAMESPACE
class MyKeyBoard : public QWidget
{
Q_OBJECT
public:
MyKeyBoard(QWidget *parent = nullptr);
~MyKeyBoard();
void letterToggle(void);
void shift_recover(void);
private slots:
private:
Ui::MyKeyBoard *ui;
QButtonGroup *Btletter;
QList<QPushButton *> *Btlist;
};
#endif // MYKEYBOARD_H
软键盘类的源文件mykeyboard.cpp
#include "mykeyboard.h"
#include "ui_mykeyboard.h"
MyKeyBoard::MyKeyBoard(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MyKeyBoard)
, Btletter(new QButtonGroup(this))
, Btlist(new QList<QPushButton *>())
{
ui->setupUi(this);
/* 按钮的布局以及部分属性定义(autorepeat属性,让按下持续输出)在uidesigner中设计*/
// 将字母按键放到一个按键组方便大小写切换
{
Btletter->addButton(ui->key_a, 0);
Btletter->addButton(ui->key_b, 1);
Btletter->addButton(ui->key_c, 2);
Btletter->addButton(ui->key_d, 3);
Btletter->addButton(ui->key_e, 4);
Btletter->addButton(ui->key_f, 5);
Btletter->addButton(ui->key_g, 6);
Btletter->addButton(ui->key_h, 7);
Btletter->addButton(ui->key_i, 8);
Btletter->addButton(ui->key_j, 9);
Btletter->addButton(ui->key_k, 10);
Btletter->addButton(ui->key_l, 11);
Btletter->addButton(ui->key_n, 12);
Btletter->addButton(ui->key_m, 13);
Btletter->addButton(ui->key_o, 14);
Btletter->addButton(ui->key_p, 15);
Btletter->addButton(ui->key_q, 16);
Btletter->addButton(ui->key_r, 17);
Btletter->addButton(ui->key_s, 18);
Btletter->addButton(ui->key_t, 19);
Btletter->addButton(ui->key_u, 20);
Btletter->addButton(ui->key_v, 21);
Btletter->addButton(ui->key_w, 22);
Btletter->addButton(ui->key_x, 23);
Btletter->addButton(ui->key_y, 24);
Btletter->addButton(ui->key_z, 25);
}
// 将shift和capslk键设置为可校验(按下不自动弹起)
ui->key_capslk->setCheckable(true);
ui->key_shift->setCheckable(true);
// 设置背景为透明
this->setAutoFillBackground(true);
QPalette palette;
palette.setBrush(QPalette::Background, QBrush(QColor(0,0,0,0)));
this->setPalette(palette);
}
MyKeyBoard::~MyKeyBoard()
{
delete ui;
}
// 实现CapsLk和Shift键的大小写翻转
void MyKeyBoard::letterToggle()
{
for(int i = 0; i < 26; i++){
QString c = Btletter->button(i)->text();
// 等价于逻辑异或
if(Btkey::capstatus ^ Btkey::shiftstatus)
Btletter->button(i)->setText(c.toUpper());
else
Btletter->button(i)->setText(c.toLower());
}
}
void MyKeyBoard::shift_recover()
{
ui->key_shift->setChecked(false);
}
- 使用:
- 将键盘类的相关头文件和源文件(Btkey和MyKeyBoard)添加到工程
- 在designer界面中添加Widget组件
- 将Widget组件提升为MyKeyBoard类