效果图:
项目中需要用到软键盘, 最初的时候,打算使用QT自带的软键盘, 但苦于不会QML, 再加上, 项目中的二级界面都是用的模态窗, QT自带软键盘不能输入。
不得已, 打算自己写一个。 好在项目不需要太复杂的输入, 主要是参数这些
先是找到了一个例子
https://blog.csdn.net/wzs250969969/article/details/78418725
大概是这样的
但这个例子我运行的时候, 关闭按钮关不掉, 并且按钮这些都是手写的, 所以没法直观的进行修改, 因此参考了他的核心代码, 写了一个简单的软键盘出来, 并且用到了一些图片, 使得软键盘好看了点
在使用的时候, 只需要在主函数中创建一个对象即可
MyKeyBoard keybord;
MyKeyBoard.h
#ifndef MYKEYBOARD_H
#define MYKEYBOARD_H
#include <QDialog>
#include <QLineEdit>
#include <QMouseEvent>
namespace Ui {
class MyKeyBoard;
}
class MyKeyBoard : public QDialog
{
Q_OBJECT
public:
explicit MyKeyBoard(QWidget *parent = nullptr);
~MyKeyBoard();
private slots:
void btn_click(); //按钮被点击事件
bool eventFilter(QObject *obj, QEvent *e);
private:
Ui::MyKeyBoard *ui;
void init(); //初始化, 进行所有按钮的事件绑定
private:
QLineEdit *currentLineEdit; //当前焦点的文本框
QString currentType; //当前输入法类型
bool mousePressed; //是否按下
int deskWidth; //屏幕宽度高度, 以及自身宽度高度
int deskHeight;
int frmWidth;
int frmHeight;
int _cur_pos; //编辑框中, 当前光标的位置
bool is_exit; //是否要退出 如果是true则表示要退出;
/*窗口移动*/
protected:
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
private:
bool _is_down;
QPoint _point;
};
#endif // MYKEYBOARD_H
MyKeyBoard.cpp
#include "mykeyboard.h"
#include "ui_mykeyboard.h"
#include <QDesktopWidget>
#include <QApplication>
#include <QDebug>
#include <QComboBox>
#include <QKeyEvent>
#include <QFile>
#include <QMouseEvent>
MyKeyBoard::MyKeyBoard(QWidget *parent) :
QDialog(parent),
ui(new Ui::MyKeyBoard)
{
ui->setupUi(this);
this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); //Qt::WindowStaysOnTopHint |
ui->btn_move->setAttribute( Qt::WA_TransparentForMouseEvents, true );
ui->btn_close->setIcon( QIcon(":/image/icon/close.png") );
ui->btn_move->setIcon( QIcon(":/image/icon/move.png") );
ui->btn_del->setIcon( QIcon(":/image/icon/backspace.png") );
ui->btn_enter->setIcon( QIcon(":/image/icon/enter.png") );
ui->btn_space->setIcon( QIcon(":/image/icon/space.png") );
ui->btn_clear->setIcon( QIcon(":/image/icon/clear.png") );
deskWidth = QApplication::desktop()->width();
deskHeight = QApplication::desktop()->height();
frmWidth = this->width();
frmHeight = this->height();
is_exit = false;
init();
}
MyKeyBoard::~MyKeyBoard()
{
delete ui;
}
/*实现窗口移动*/
void MyKeyBoard::mousePressEvent(QMouseEvent *e)
{
if(e->button() != Qt::LeftButton)
return;
int x = ui->btn_move->x();
int y = ui->btn_move->y();
int rx = ui->btn_move->width();
int ry = ui->btn_move->height();
int cur_x = e->pos().x();
int cur_y = e->pos().y();
if(cur_x>x && cur_y>y && cur_x<rx+x && cur_y<ry+y)
{
_is_down = true;
_point = e->globalPos();
}
}
void MyKeyBoard::mouseMoveEvent(QMouseEvent *e)
{
if(_point.isNull())
return;
if(_is_down)
{
QPoint n_pos = e->globalPos();
QPoint update_pos = mapToParent(n_pos - _point);
move(update_pos);
_point = n_pos;
}
}
void MyKeyBoard::mouseReleaseEvent(QMouseEvent *)
{
_is_down = false;
}
/***********/
void MyKeyBoard::btn_click()
{
QPushButton *btn = (QPushButton *)sender();
QString objectName = btn->objectName();
if (objectName == "btn_del")
{
if (currentLineEdit != nullptr) //点击删除
{
ui->_key_board_input_lineedit->backspace();
currentLineEdit->setText( ui->_key_board_input_lineedit->text() ); //这里是因为, 点击删除的时候, 有可能是删除了选中的多个文本, 如果也用backspace的话, 会导致2个编辑框文本不一致
}
}
else if (objectName == "btn_close") //点击关闭窗口
{
is_exit = true;
currentLineEdit->setText( ui->_key_board_input_lineedit->text() );
currentLineEdit->setFocusPolicy(Qt::ClickFocus);
this->close();
}
else if(objectName == "btn_enter") //点击回车
{
currentLineEdit->setText( ui->_key_board_input_lineedit->text() );
QKeyEvent enterkey(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
QCoreApplication::sendEvent( currentLineEdit, &enterkey );
this->close();
}
else if(objectName == "btn_space") //按下空格
{
if (currentLineEdit != nullptr)
{
currentLineEdit->insert(" ");
ui->_key_board_input_lineedit->insert( " " );
}
}
else if(objectName == "btn_clear") //按下清空
{
if (currentLineEdit != nullptr)
{
currentLineEdit->setText("");
ui->_key_board_input_lineedit->setText("");
}
}
else
{
QString value = btn->text();
//当前的焦点是编辑框, 那么就插入一个字符
if (currentLineEdit != nullptr)
{
ui->_key_board_input_lineedit->insert(value);
currentLineEdit->setText( ui->_key_board_input_lineedit->text() );
if(ui->_key_board_input_lineedit != nullptr)
{
currentLineEdit->setCursorPosition( ui->_key_board_input_lineedit->cursorPosition() );
}
}
}
}
//这个被放弃了, 现在使用事件过滤器的方式
void MyKeyBoard::focus_changed(QWidget *, QWidget *nowWidget)
{
if (nowWidget != 0 && !this->isAncestorOf(nowWidget))
{
if (nowWidget->inherits("QLineEdit"))
{
currentLineEdit = (QLineEdit *)nowWidget;
QPoint movePoint;
// 鼠标点击位置坐标
if (QCursor::pos().y() > deskHeight / 2)
{
// 靠上居中显示
movePoint = QPoint(deskWidth/2 - frmWidth/2, 0);
}
else
{
// 靠下居中显示
movePoint = QPoint(deskWidth/2 - frmWidth/2, deskHeight - frmHeight);
}
this->move(movePoint);
this->repaint();
if(!is_exit)
{
this->exec();
}
else {
is_exit = false;
this->close();
}
}
else if(nowWidget->inherits("QComboBox"))
{
currentLineEdit = static_cast<QComboBox *>(nowWidget)->lineEdit() ;
if(!is_exit)
{
is_exit = true;
this->exec();
}
else {
is_exit = false;
this->close();
}
}
else
{
currentLineEdit = nullptr;
this->close();
}
}
}
bool MyKeyBoard::eventFilter(QObject *obj, QEvent *e)
{
if(obj->metaObject()->className() == QStringLiteral("QLineEdit"))
{
QLineEdit *tmp_edit = static_cast< QLineEdit* >(obj); //第一步判断
if(tmp_edit->objectName() == "_key_board_input_lineedit") //如果点击的是自己自带的编辑框的话, 那就是要修改光标位置了
{
QMouseEvent *mEvent = static_cast< QMouseEvent* >(e);
if(mEvent->button() == Qt::LeftButton)
{
if(tmp_edit != nullptr)
{
_cur_pos = ui->_key_board_input_lineedit->cursorPosition();
currentLineEdit->setCursorPosition( _cur_pos );
}
}
return false;
}
QLineEdit *edit = static_cast< QLineEdit* >(obj);
if(e->type() == QEvent::MouseButtonPress && edit->isEnabled())
{
currentLineEdit = (QLineEdit *)obj;
ui->_key_board_input_lineedit->setText( currentLineEdit->text() );
ui->_key_board_input_lineedit->setCursorPosition( currentLineEdit->cursorPosition() );
QPoint movePoint = QCursor::pos();
this->move( movePoint.x(), movePoint.y()+edit->height() );
this->repaint();
this->exec();
}
}
}
void MyKeyBoard::init()
{
currentLineEdit = 0;
mousePressed = false;
currentType = "min";
QList<QPushButton *> btn = this->findChildren<QPushButton *>();
foreach (QPushButton * b, btn) {
connect(b, SIGNAL(clicked()), this, SLOT(btn_click()));
}
qApp->installEventFilter(this);
}
很多代码都是用的上边的参考例子, 修改了布局, 以及模态输入, 和实现逻辑。使用还是很方便的。
这套软键盘的配色也很简单, 只需要几行css即可
#_key_board_input_lineedit{
border: 1px solid rgb(155,155,155);
background:rgb(28,29,30);
border-radius:2px;
font-size:20px;
color:rgb(230,230,230);
}
/*软键盘的CSS*/
#MyKeyBoard{
background:rgb(28,29,30);
}
.MyKeyBoard QPushButton{
border-radius:1px;
text-align:center;
background:rgb(48,50,50);
margin:1px;
font-size:22px;
color:rgb(255,255,255);
}
.MyKeyBoard QPushButton:enabled:hover{
background:rgb(48,50,50);
}
.MyKeyBoard QPushButton:enabled:pressed{
background:rgb(60,60,60);
}
主要代码全在这里了。 ui文件可以自己对应着拖一个好看的出来