Qt 软键盘的实现(QWidget),支持中文输入法、数字、英文切换
**出发点:由于Qt自带的软键盘是QML的,如果使用QWidget模式去编写调用自带的软键盘的话,在ARM下运行会全屏漆黑,并不是我们想要的效果,所以,在网上搜了很多的资料,自己去做了自制键盘,在项目中使用。 **
新建一个keyboard的Demo
以下是键盘的布局
键盘初始化
准备好26个输入的字符列表,用作大小写、数字切换
QMap<int,QList<QString>> modelMap;QList<QString> firstList,secordList,thirdList;firstList<<"Q"<<"W"<<"E"<<"R"<<"T"<<"Y"<<"U"<<"I"<<"O"<<"P"<<"A"<<"S"<<"D"<<"F"<<"G"<<"H"<<"J"<<"K"<<"L"<<"Z"<<"X"<<"C"<<"V"<<"B"<<"N"<<"M";secordList<<"q"<<"w"<<"e"<<"r"<<"t"<<"y"<<"u"<<"i"<<"o"<<"p"<<"a"<<"s"<<"d"<<"f"<<"g"<<"h"<<"j"<<"k"<<"l"<<"z"<<"x"<<"c"<<"v"<<"b"<<"n"<<"m";thirdList<<"1"<<"2"<<"3"<<"4"<<"5"<<"6"<<"7"<<"8"<<"9"<<"0"<<"~"<<"!"<<"@"<<"#"<<"%"<<"^"<<"&"<<"*"<<"?"<<"("<<")"<<"-"<<"_"<<":"<<";"<<"/";modelMap.insert(1,firstList);modelMap.insert(2,secordList);modelMap.insert(3,thirdList);
以下是大小写、数字切换的函数接口
/*************************************************
Function:modeExchange// 函数名称
Description: 模式切换// 函数功能、性能等的描述
Input: int modeNum -> 模式值// 输入参数说明,包括每个参数的作用、取值说明及参数间关系。
Return: 无// 函数返回值的说明
*************************************************/
void Dialog::modeExchange(int modeNum)
{switch (modeNum) {case 2://小写for (int i=0;i<modelMap.value(2).length();i++){btngroup->button(i+1)->setText(modelMap.value(2).at(i));}break;case 1://大写for (int i=0;i<modelMap.value(2).length();i++){btngroup->button(i+1)->setText(modelMap.value(1).at(i));}break;case 3://数字for (int i=0;i<modelMap.value(2).length();i++){btngroup->button(i+1)->setText(modelMap.value(3).at(i));}break;default:break;}
}
26个字符按键输入函数接口
/*************************************************
Function:onClick// 函数名称
Description: 模式切换// 函数功能、性能等的描述
Input: int modeNum -> 模式值// 输入参数说明,包括每个参数的作用、取值说明及参数间关系。
Return: 无// 函数返回值的说明
*************************************************/
void Dialog::onClick(int value)
{QString buffer;switch (modeIndex) {case 0:buffer=modelMap.value(2).at(value-1);break;case 1:buffer=modelMap.value(1).at(value-1);break;case 2:buffer=modelMap.value(3).at(value-1);break;default:break;} if(isChinese){recordBuf+=buffer;findFontData(recordBuf);}else{recordBuf.clear();insertValue(buffer);}
}
除了26个基本字符按键外,还有一些功能按键,如数字切换键,大小写切换键,中英文切换键,删除键等等。。。。。
/*************************************************
Function:otherBtnClick()// 函数名称
Description: 功能按键槽函数// 函数功能、性能等的描述
Input: 无// 输入参数说明,包括每个参数的作用、取值说明及参数间关系。
Return: 无// 函数返回值的说明
*************************************************/
void Dialog::otherBtnClick()
{QPushButton *b = (QPushButton *)sender();if(b==ui->spacebtn){//空格recordBuf+=" ";findFontData(recordBuf);}else if(b==ui->keydelbtn){//删除if(recordBuf.length()!=0){recordBuf.remove(recordBuf.length()-1,1);findFontData(recordBuf);}else{deleteValue();}}else if((b==ui->oneSwitchbtn||b==ui->oneSwitchbtn)&&numFlag==false){//大小写if(sizeFlag==true){//小写modeIndex=1;sizeFlag=false;modeExchange(1);}else{modeIndex=0;sizeFlag=true;modeExchange(2);}}else if(b==ui->numbtn){if(!numFlag){modeIndex=2;modeExchange(3);}else{modeIndex=0;modeExchange(2);}numFlag=!numFlag;} else if(b==ui->ChEnbtn&&numFlag==false){if(isChinese){ui->ChEnbtn->setText("英文");}else{ui->ChEnbtn->setText("中文");}isChinese = !isChinese;}else if(b==ui->keyexitbtn) {this->close();}
}
按键功能接口编写好后,接下来我们需要加载自定义的字库
/*************************************************
Function:loadFontData// 函数名称
Description: 加载字库函数// 函数功能、性能等的描述
Input: 无// 输入参数说明,包括每个参数的作用、取值说明及参数间关系。
Return: 无// 函数返回值的说明
*************************************************/
void Dialog::loadFontData()
{QFile pinyin(":/pinyin.txt");if (! pinyin.open(QIODevice::ReadOnly)) {qDebug() << "Open pinyin file failed!";return;}while (! pinyin.atEnd()) {QString buf = QString::fromUtf8(pinyin.readLine()).trimmed();// qDebug()<<buf;if (buf.isEmpty())continue;/* 去除#号后的注释内容 */if (buf.left(1) == "#")continue;buf=buf.replace("\t"," ");// qDebug()<<buf;/* 正则匹配词组内容并通过组捕获获取'词组'和'拼音' */QRegExp regExp("(\\S+) : ([\\S ]+)");int pos = 0;while ((pos = regExp.indexIn(buf, pos)) != -1) {pos += regExp.matchedLength();QString second = regExp.cap(1); /* 词组 */QString first = regExp.cap(2); /* 拼音 */QStringList strList = first.split(" ");QString abb;for (int i = 0; i < strList.count(); i++) {/* 获得拼音词组的首字母(用于缩写匹配) */abb += strList.at(i).left(1);}QList<QPair<QString, QString> > &tmp = m_data[first.left(1)];/* 将'拼音(缩写)'和'词组'写入匹配容器 */tmp.append(qMakePair(abb, second));/* 将'拼音(全拼)'和'词组'写入匹配容器 */tmp.append(qMakePair(first.remove(" "), second));}}// qDebug()<<m_data["b"];
}
通过用户输入的字符从字库中提取出来
/*************************************************
Function:findFontData()// 函数名称
Description: 从字库中找相对应的中文// 函数功能、性能等的描述
Input: QString text ->输入的字符// 输入参数说明,包括每个参数的作用、取值说明及参数间关系。
Return: 无// 函数返回值的说明
*************************************************/
void Dialog::findFontData(QString text)
{for (int i = 0; i < ui->listWidget->count(); i++) {QListWidgetItem *item = ui->listWidget->takeItem(i);delete item;item = NULL;}ui->listWidget->clear();addOneItem(text);/* 通过获取首字母索引词库内容,用于加快匹配词(组)。 */const QList<QPair<QString, QString> > &tmp = m_data[text.left(1)];for (int i = 0; i < tmp.count(); i++) {const QPair<QString, QString> &each = tmp.at(i);/* 模糊匹配 */if (each.first.left(text.count()) != text)continue;/* 添加到候选栏 */addOneItem(each.second);}
}
/*************************************************
Function:addOneItem()// 函数名称
Description: 将词组添加到显示列表// 函数功能、性能等的描述
Input: QString text ->从字库中提取出来的词组// 输入参数说明,包括每个参数的作用、取值说明及参数间关系。
Return: 无// 函数返回值的说明
*************************************************/
void Dialog::addOneItem(QString text)
{QListWidgetItem *item = new QListWidgetItem(text);QFont font;font.setPointSize(18);font.setBold(true);font.setWeight(50);item->setFont(font);/* 设置文字居中 */item->setTextAlignment(Qt::AlignCenter);bool isChineseFlag = QRegExp("^[\u4E00-\u9FA5]+").indexIn(text.left(1)) != -1;int width = font.pointSize();if (isChineseFlag)width += text.count()*font.pointSize()*1.5;elsewidth += text.count()*font.pointSize()*2/3;item->setSizeHint(QSize(width, 50));ui->listWidget->addItem(item);
}
双击listWidget列表的选项
connect(ui->listWidget,SIGNAL(itemDoubleClicked(QListWidgetItem *)),this,SLOT(listWidgetDoubleClick(QListWidgetItem *)));void Dialog::listWidgetDoubleClick(QListWidgetItem *item)
{qDebug()<<item->text();recordBuf.clear();findFontData(recordBuf);
}
删除QlineEdit中的字符
void Dialog::deleteValue()
{if (currentEditType == "QLineEdit"){currentLineEdit->backspace();}
}
插入字符到QLineedit上
/*************************************************
Function:insertValue// 函数名称
Description: 插入值到当前焦点控件// 函数功能、性能等的描述
Input: QString value ->插入的字符// 输入参数说明,包括每个参数的作用、取值说明及参数间关系。
Return: 无// 函数返回值的说明
*************************************************/
void Dialog::insertValue(QString value)
{if (currentEditType == "QLineEdit"){currentLineEdit->insert(value);}
}
接口写好后,接下来是触发启动键盘的条件
首先安装事件过滤器
qApp->installEventFilter(this);
绑定全局焦点信号槽
connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)),this, SLOT(focusChanged(QWidget *, QWidget *)));
/*************************************************
Function:focusChanged// 函数名称
Description: 判断焦点改变// 函数功能、性能等的描述
Input: QWidget *oldWidget ->上一个控件QWidget *nowWidget ->新控件// 输入参数说明,包括每个参数的作用、取值说明及参数间关系。
Return: 无// 函数返回值的说明
*************************************************/
void Dialog::focusChanged(QWidget *oldWidget, QWidget *nowWidget)
{qDebug() << "oldWidget:" << oldWidget << " nowWidget:" << nowWidget;if (nowWidget != nullptr && !this->isAncestorOf(nowWidget)){if (oldWidget == nullptr && !isFirst){return;}isFirst = false;if (nowWidget->inherits("QLineEdit")){currentLineEdit = static_cast<QLineEdit *>(nowWidget);currentEditType = "QLineEdit";this->setVisible(true);}else{currentWidget = nullptr;currentLineEdit = nullptr;currentEditType = "";this->setVisible(false);}}
}
/*************************************************
Function:eventFilter// 函数名称
Description://事件过滤器 QLineEdit弹出小键盘 // 函数功能、性能等的描述
Input: QObject *obj ->对象QEvent *event ->事件// 输入参数说明,包括每个参数的作用、取值说明及参数间关系。
Return: 无// 函数返回值的说明
*************************************************/
bool Dialog::eventFilter(QObject *obj, QEvent *event)
{//qDebug()<<__func__<<":"<<obj->objectName();if (event->type() == QEvent::MouseButtonPress){//确保每次点击输入栏都弹出虚拟键盘if (currentEditType == "QLineEdit"){this->setVisible(true);}return false;}return QWidget::eventFilter(obj, event);
}
部分效果图如下
由于拍的视频太大,Gif图上传不了,只能截取部分图出来
Qt 软键盘的实现(QWidget),支持中文输入法、数字、英文切换相关推荐
- Qt软键盘使用和修改软键盘参数 支持中文
Qt软键盘使用和修改软键盘参数 概述 效果预览 一.修改pro文件,添加软键盘模块 二.修改main.cpp文件,加载软键盘 三.代码没有写错但是软键盘显示不出来问题 四. 修改软件盘的尺寸 1.下载 ...
- Qt软键盘中/英文输入法
Qt软键盘中/英文输入法 Qt软键盘,实现中文/英文输入法功能. Qt5.7版本之后,Qt官网也推出了一款支持中文输入的软键盘. 此软键盘来源于笑颜,得到同意才发此文章.一是进行记录,二是后期会在此版 ...
- Qt之Windows下禁用和启用中文输入法
在密码框输入密码的时候,一般要输入字母.数字或者其他特殊字符,如果当前输入法是中文输入法,比如说搜狗拼音中文,需要手动切换成英文输入法,非常麻烦.如果能在密码框获取到焦点的时候,将输入法切换到美式英语 ...
- QT 软键盘 兼容QT4/QT5
前言 软键盘在嵌入式平台开发中被广泛使用 本章代码功能: 1.支持中英双语输入法 2.同时支持QT4/QT5版本 3.支持linux/windows系统 源码地址 https://gitee.com/ ...
- QT 软键盘实现
在树莓派下面运行了一下我的写的代码,发现在输入框中并不能使用键盘输入内容,什么都不能输入,只能自己实现软键盘. QT 的事件处理: Qt 程序需要在main()函数创建一个QCoreApplicati ...
- qt调用android键盘,QT 软键盘输入
1.从QInputContext派生自己的InputContext类 ,例如: class MyInputPanelContext : public QInputContext { Q_OBJECT ...
- ubuntu下qt模拟键盘按键按下_基于Linux+Qt软键盘设计及其实现.pdf
计算机与现代化 YUXIANDAIHUA 2011年第12期 JISUANJI 总第196期 文章编号:1006-2475(2011)12-0179-03 基于Linux Qt的软键盘设计与实现 田福 ...
- 在Ubuntu 14.04中使SublimeText 3支持中文输入法
在Ubuntu 14.04中安装了SublimeText 3之后发现既然不支持输入中文,于是在网上搜罗一下,发现很多人遇到了同样的问题,但是解决办法大该就只有一个.下面根据自身的安装及解决办法总结如下 ...
- Google Chrome OS中文版下载 支持中文输入法
终于可以体验Google Chrome OS了,但怎么说Chrome OS个人感觉不怎么样,特别是对游戏玩家来说. 这个版本最大的特性是加入了Chromium浏览器的繁体中文界面,另外还提供了SCIM ...
最新文章
- windows平台下 c++获取 系统版本 网卡 内存 CPU 硬盘 显卡信息
- 计算机成绩表用函数怎么做,题用Excel函数以计算机成绩为依据计算出等次,怎么用函数IF 设定三个分类,如》90 为优秀 79~89为良好其余合格...
- MongoDB资料大全
- 信息竞赛进阶指南--归并排序求逆序对
- Eclipse快捷键以及设置
- 再好的工作是为了更好的生活
- IDEA 工具使用报错总结
- 社区团购的终局是不是团长被抛弃?
- H3C Private VLAN(私有vlan) 实验
- c语言习题集(含答案)
- 转动惯量与惯性矩(截面)比较
- Android双清卸载木马,刷机如何清除木马病毒
- 阿里云国际版服务器电子商务直播解决方案
- 计算机电源输出定义,电脑电源接口定义图解
- 方法重载和重写的区别
- Excel作图-制作复合饼图
- 数字图像处理 第八章 图像压缩
- Jquery获取单选框与复选框选中的值
- 知网根据作者及单位检索文献汇总到Excel(2021.6.9)
- 广东小学几年级有计算机课,广州小学开设网络班:小学生人手一台手提电脑