当前位置: 首页 > news >正文

QT C++ 软键盘/悬浮键盘/触摸屏键盘的制作

目录

1、前言

2、界面设计

3、英文、数字的输入

4、符号的输入

5、中文的输入

6、中文拼音库的选择

7、其他

8、结语

1、前言

        使用QT C++在带显示器的Linux系统 开发板上(树莓派等)编写操作UI界面时,很多时候都需要一个软键盘来输入文字、符号等(在Windows系统只有少数时候需要用软键盘)。这个时候使用QT自带的软键盘就可能会出现很多显示问题,大小不适、显示文本乱码等等。

    //QT自带的软键盘激活QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);//设置为默认键盘qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));

        当然,这个时候还可以查看你使用的liunx系统是否自带软键盘,你可以启动这个自带的,但是很多情况下还是会出现上面的问题:显示乱码、大小不适。

        最后,我们最佳方案就是自己动手编写一个软键盘,或者在网络上找一个已经实现的例程。但是我在网络上没有找到好用的软键盘例程,都有很大得缺陷,所以还是决定自己编写一个软键盘,这样也对于所对应得项目或者开发板具有更好兼容性。

2、界面设计

        这里建议先在能使用Qt Creator的系统上做好键盘得UI界面,因为在这个官方得编辑编译器中,有对应得UI设计工具界面,这个界面能够快速的做出你需要的界面的模样,并自动生成.ui文件。界面样式就按照手机输入法做一个大概的样子就行了,例如我的:

这里的选词我使用的label,然后结合link标签使用,点击时就可以取出对应的文字了,你也可以使用pushbutton来替代,只要最后能达到目的就行。

3、英文、数字的输入

        英文、数字以及符号的输入很简单,使用pushbutton,在对应的按钮上添加对应的文本,点击该按钮时获取该文本即可进行对应的输入操作,这里按钮很多建议使用Qt中的按钮组类(QButtonGroup)来管理按钮,我使用了两个按钮组来管理对应的输入操作:

    QButtonGroup *bigKey26; //26键QButtonGroup *numberKey; //数字键bigKey26 = new QButtonGroup(this);//26键按钮组初始化connect(bigKey26,SIGNAL(buttonClicked(int)),this,SLOT(bigKey26Slot(int)));for (int var = 1; var <= 26; ++var) {QPushButton *pushButton = this->findChild<QPushButton *>("bigKeyboardBtn_" + QString::number(var));if(pushButton != nullptr){bigKey26->addButton(pushButton,var);}}numberKey = new QButtonGroup(this);//数字键按钮组初始化connect(numberKey,SIGNAL(buttonClicked(int)),this,SLOT(numberKeySlot(int)));for (int var = 0; var <= 9; ++var) {QPushButton *pushButton = this->findChild<QPushButton *>("numberKekboard_" + QString::number(var));if(pushButton != nullptr){numberKey->addButton(pushButton,var);}}//26键功能函数,这里有英文,也有中文
void KeyBoardWidget::bigKey26Slot(int id)
{QString curBtnText = this->findChild<QPushButton *>("bigKeyboardBtn_" + QString::number(id))->text();if(bigKeyLanguagesFlag == 0){/** ********** 英 ***********/if(bigKey26UpAndDownFlag == 0){//小curBtnText = curBtnText.toLower();}else if(bigKey26UpAndDownFlag == 1){//大curBtnText = curBtnText.toUpper();}
//        this->addTextContentOfLabel(ui->label, "ret1-label", curBtnText);this->curFocusWidgetInsertText(curBtnText); //在当前焦点控件光标处添加文本}else if(bigKeyLanguagesFlag == 1){/** ********** 中 ***********/curBtnText = curBtnText.toLower();ui->label_9->setText(ui->label_9->text() + curBtnText);//        dictRetList = QStringList{"结果1", "结果2", "结果3", "结果4", "结果5", "结果6", "结果7", "结果8", "结果9", "结果10", "结果11", "结果12"};dictRetList = pinyinToHanzi(ui->label_9->text());this->showDictRetListToLabel(1);}
}//数字键的功能函数
void KeyBoardWidget::numberKeySlot(int id)
{QString curBtnText = this->findChild<QPushButton *>("numberKekboard_" + QString::number(id))->text();this->curFocusWidgetInsertText(curBtnText);//在当前焦点控件光标处添加文本
}

4、符号的输入

        符号按键的功能比较简单,我使用的是多个信号连接一个槽的机制来管理,区分按钮的方式是使用sender()来获取当前发送信号的按键。这里需要注意的是特殊符号&需要使用&&来转义显示,否则对应的按钮上不会显示,故在处理时需要判断一下。

connect(ui->numberKekboardPoint, &QPushButton::clicked, this, &KeyBoardWidget::on_symbolBtn_clicked);for (int var = 1; var <= 40; ++var) {QPushButton *curSymbolBtn = this->findChild<QPushButton *>("symbolBtn_" + QString::number(var));if(curSymbolBtn != nullptr){connect(curSymbolBtn, &QPushButton::clicked, this, &KeyBoardWidget::on_symbolBtn_clicked);}}void KeyBoardWidget::on_symbolBtn_clicked()
{QPushButton *curSymbolBtn = qobject_cast<QPushButton *>(sender());if(curSymbolBtn != nullptr){QString curSymbolStr = curSymbolBtn->text();if(curSymbolStr.isEmpty()){return;}if(curSymbolStr == "&&"){curSymbolStr = "&";}this->curFocusWidgetInsertText(curSymbolStr);}
}

5、中文的输入

        在软键盘的编写中,这个是最费时间的,也不是说多难,难的是找到一个可使用的开源的中文拼音库,很难找找了好几天才找到。找到拼音库后,移植到自己的代码中进行拼音的输入,这里我用了一个label来显示中文的拼音,然后从这里获取,如上在英文的输入中已有获取方式。

    if(bigKeyLanguagesFlag == 1){/** ********** 中 ***********/curBtnText = curBtnText.toLower();ui->label_9->setText(ui->label_9->text() + curBtnText);//        dictRetList = QStringList{"结果1", "结果2", "结果3", "结果4", "结果5", "结果6", "结果7", "结果8", "结果9", "结果10", "结果11", "结果12"};dictRetList = pinyinToHanzi(ui->label_9->text());this->showDictRetListToLabel(1);}

这里我已经将拼音库的使用封装为函数pinyinToHanzi(),传入拼音即可返回对应的汉字列表。获取到汉字列表后,使用showDictRetListToLabel()函数来更新显示,这个函数将列表以5为单位分页,传入的数字即显示的页码。前面说过,我的结果显示在label中的,所以使用link事件来获取对应的文字和事件,设置链接函数如下:

void KeyBoardWidget::setTextContentOfLabel(QLabel *label, QString linkStr, QString text)
{label->setText(QString("<a href = '%1' style=\"text-decoration: none;\" style=\"color: white;\">%2</a>").arg(linkStr).arg(text));
}

6、中文拼音库的选择

        这里可以选择libpinyin或者googlepinyin,前者在Linux系统上使用很方便,直接使用apt下载即可,后者需要下载源码自行进行引用。注意的是libpinyin在Windows系统上使用起来很麻烦,建议使用googlepinyin。

libpinyin下载方式:

Ubuntu/Debian:
sudo apt-get install libpinyin-dev
Fedora:
sudo dnf install libpinyin-devel源码下载:https://github.com/libpinyin/libpinyin

googlepinyin下载:

https://github.com/aron566/google_pinyinim

下载完成后,他们在github中都有使用示例 ,照着用就可以,不需要额外的什么,但是要注意词库的路径要正确。

7、其他

再补充几个关键点:

//防止当前窗口获取焦点,导致输入控件丢失
this->setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool | Qt::WindowDoesNotAcceptFocus);
//获取当前焦点在哪个控件
curFocusWidget = QApplication::focusWidget();
//判断焦点控件是否是QLineEdit 类型
if (QLineEdit *lineEdit = qobject_cast<QLineEdit *>(curFocusWidget)) {curText = lineEdit->text();
} 
//清除当前焦点,关闭键盘的时候会用到
if(curFocusWidget != nullptr){curFocusWidget->setFocusPolicy(Qt::ClickFocus);curFocusWidget->clearFocus();curFocusWidget = nullptr;
}
//多label链接一个link事件槽
connect(curlabel, &QLabel::linkActivated, this, &KeyBoardWidget::on_label_1_linkActivated);
//使用libpinyin获取的结果格式const char *word
retList.append(QString(word));
//使用googlepinyin获取的结果格式ime_pinyin::char16 buf[256]
retList.append(QString::fromUtf16(buf));

8、结语

        关于其他的布局或功能实现、结果获取后放入目标控件等等,就不过多赘述了,还有问题请留言,最后放一张我的效果图片:

相关文章:

QT C++ 软键盘/悬浮键盘/触摸屏键盘的制作

目录 1、前言 2、界面设计 3、英文、数字的输入 4、符号的输入 5、中文的输入 6、中文拼音库的选择 7、其他 8、结语 1、前言 使用QT C在带显示器的Linux系统 开发板上&#xff08;树莓派等&#xff09;编写操作UI界面时&#xff0c;很多时候都需要一个软键盘来输入文字…...

element-ui点击文字查看图片预览功能

今天做一个点击文字查看图片的功能&#xff0c;大体页面长这样子&#xff0c;点击查看显示对应的图片 引入el-image-viewer&#xff0c;点击的文字时候设置图片预览组件显示并传入图片的地址 关键代码 <el-link v-if"scope.row.fileList.length > 0" type&…...

SpringBoot集成Redis使用Cache缓存

使用SpringBoot集成Redis使用Cache缓存只要配置相应的配置类&#xff0c;然后使用Cache注解就能实现 RedisConfig配置 新建RedisConfig配置类 package com.bdqn.redis.config;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annota…...

【瑞萨RA8D1 CPK开发板】lcd显示

1.8寸lcd使用gpio模拟spi驱动 由于板子引出的接口限制&#xff0c;故使用gpio模拟spi驱动中景园的1.8寸lcd 1.77寸液晶屏 1.8寸TFT LCD SPI TFT彩屏st7735驱动128x160高清屏-淘宝网 (taobao.com) 使用RASC 的gpio配置 根据厂家提供的驱动文件移植 #define LCD_SCLK_Clr() g…...

算法收敛的一些证明方法与案例

证明一个算法收敛通常涉及多个角度&#xff0c;以下是一些常用的方法和示例&#xff1a; 一、方法 1. 数学归纳法 通过数学归纳法证明算法在每一步的输出结果都在收敛范围内。 示例&#xff1a;考虑一个递归算法&#xff0c;假设我们要证明它在每一步中输出的值逐渐接近目标…...

基于vue框架的蛋糕店网上商城740g7(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,店长,商品分类,商品信息,订单投诉,反馈信息 开题报告内容 基于Vue框架的蛋糕店网上商城开题报告 一、项目背景与意义 随着互联网技术的快速发展和普及&#xff0c;电子商务已成为现代商业的重要组成部分。蛋糕作为一种受欢迎的美…...

你真的了解Canvas吗--解密六【ZRender篇】

目录 &#x1f4da;入口 Circle - 图形 Group - 组 事件捕获 - 流程 step - 1 step - 2 总结 这篇文章我们讲讲Circle圆形&#xff0c;Group组的使用以及大家最熟悉又陌生的事件捕获和冒泡在ZRender中的实现&#xff0c;篇幅较长&#xff0c;且听我慢慢分析。 &#x…...

孤独相伴 - 结婚十七年

07年的今天&#xff0c;我和老公请假&#xff0c;去了新加坡的大使馆领证。 17年后的今天&#xff0c;此刻凌晨16分&#xff0c; 这是17年来我第一次这么早写结婚纪念&#xff0c;只是凑巧。 今天的心情莫名其妙。 此刻&#xff0c;两个词出现在我的脑海&#xff1a;孤独 &am…...

json-server,跨域

启动json-serer json-server --watch db.json 注意&#xff1a; db.json为json文件的名称&#xff0c;你自己的文件名叫什么&#xff0c;就启动对应的文件就可以了 启动json-server的时候&#xff0c;必须在你db.json所在的文件夹下进行启动 这样服务器就可以启动成功了&…...

【Conda】修复 Anaconda 安装并保留虚拟环境的详细指南

目录 流程图示1. 下载 Anaconda 安装程序2. 重命名现有的 Anaconda 安装目录Windows 操作系统Linux 操作系统 3. 运行新的 Anaconda 安装程序Windows 操作系统Linux 操作系统 4. 同步原环境使用 robocopy 命令&#xff08;Windows&#xff09;使用 rsync 命令&#xff08;Linux…...

转行高薪 AI 产品经理,快速入门方法在此处

根据《2024年中国AI大模型场景探索及产业应用调研报告》&#xff0c;当前整体AI大模型行业仍然处于萌芽期&#xff0c;但市场规模增速较快。2023年我国AI大模型行业规模达到了147亿元&#xff0c;近三年复合增速高达114%。预计2024年&#xff0c;该市场规模将进一步增长至216亿…...

初识环境变量

初识环境变量 目录&#xff1a; 什么是环境变量常见的环境变量Linux中与环境变量的有关的命令如何获取环境变量环境变量的特点环境变量的作用 1.什么是环境变量 我们在Linux操作系统下&#xff0c;使用指令&#xff0c;比如ls,pwd,cd等等&#xff0c;可以直接使用&#xff0c…...

成像基础 -- 景深计算

景深计算 景深&#xff08;Depth of Field, DOF&#xff09;指的是在摄影中&#xff0c;能够清晰成像的物体前后距离的范围。景深的大小取决于多个因素&#xff0c;包括焦距、光圈值、物距以及相机感光元件的尺寸。 1. 景深的主要参数 焦距&#xff08; f f f&#xff09;&a…...

Git中从dev分支恢复master分支

问题 需要从dev分支恢复master分支。之前搞错远程地址了&#xff0c;把master分支搞乱了&#xff0c;现在需要从dev分支恢复代码到master分支。 步骤 git checkout dev # 切换到 dev 分支 git branch -D master # 删除本地 master 分支 git checko…...

12.5 Linux_进程间通信_信号灯

概述 什么是信号灯&#xff1a; 信号灯也称为信号量&#xff0c;代表的是一类资源&#xff0c;其值表示系统中该资源的数量。 主要用途是实现进程、线程的同步。 什么是P/V操作&#xff1a; P操作就是申请资源&#xff0c;V操作就是释放操作。 信号灯的种类&#xff1a; …...

Linux——cp-mv-rm命令

cp命令 复制文件 cp test01.txt test02.txt 复制文件夹 cp -r hsy01 hsy02 mv命令 移动文件/文件夹 rm命令 删除文件 rm test.txt 删除文件夹&#xff08;目录 rm -r hsy01 通配符 * 匹配任意内容 注意* 位置 强制删除-f root超级管理员...

上升点列

题目描述 在一个二维平面内&#xff0c;给定 n 个整数点 (xi​,yi​)&#xff0c;此外你还可以自由添加 k 个整数点。 你在自由添加 k 个点后&#xff0c;还需要从 nk 个点中选出若干个整数点并组成一个序列&#xff0c;使得序列中任意相邻两点间的欧几里得距离恰好为 1 而且…...

刷题 链表

面试经典150题 - 链表 141. 环形链表 class Solution { public:bool hasCycle(ListNode *head) {ListNode* slow head, *fast head;while (fast ! nullptr && fast->next ! nullptr) {slow slow->next;fast fast->next->next;if (slow fast) {return…...

SQL 语法学习指南

目录 前言1. SQL 的基本概念1.1 SQL 的作用1.2 SQL 的特点 2. SQL 的基础语法2.1 数据查询 - SELECT 语句2.2 数据插入 - INSERT 语句2.3 数据更新 - UPDATE 语句2.4 数据删除 - DELETE 语句 3. SQL 的进阶语法3.1 聚合函数3.2 表连接 - JOIN3.3 子查询 4. SQL 学习建议4.1 多实…...

低代码可视化-uniapp商城首页小程序-代码生成器

在设计一个小程序的首页时&#xff0c;包含轮播图、通知栏和商品列表这三个元素是非常常见且有效的布局方式。这样的设计既能够吸引用户的注意力&#xff0c;又能够高效地展示信息和商品。 轮播组件 小程序首页幻灯片通常位于小程序的顶部或显著位置&#xff0c;通过滑动屏幕可…...

Vue3 富文本:WangEditor

wangEditor 开源 Web 富文本编辑器&#xff0c;开箱即用&#xff0c;配置简单 wangEditor 1. 安装依赖包 npm install wangeditor/editor-for-vuenext --save 2. 在引用页面加入如下代码 <template><div style"border: 1px solid #ccc"><Toolbar …...

Unity实现自定义图集(四)

以下内容是根据Unity 2020.1.0f1版本进行编写的   在之前的篇章中已经把自定义图集在编辑器上的使用,以及运行时所需的信息都准备好了,接下来就是魔改UGUI的Image组件,使其能够像Image那样运行时如果引用的资源有打自定义图集,则加载对应自定义图集的Texture。 1、思路 …...

k8s-pod的管理及优化设置

Pod是Kubernetes&#xff08;k8s&#xff09;中最小的资源管理组件&#xff0c;也是最小化运行容器化应用的资源对象。以下是对Pod的详细介绍&#xff1a; 一、Pod的基本概念 定义&#xff1a;Pod是Kubernetes中可以创建和管理的最小单元&#xff0c;是资源对象模型中由用户创…...

软件测试面试题大全

什么是软件测试&#xff1f; 答案&#xff1a;软件测试是一系列活动&#xff0c;旨在评估软件产品的质量&#xff0c;并验证它是否满足规定的需求。它包括执行程序或系统以识别任何缺陷、问题或错误&#xff0c;并确保软件产品符合用户期望。 软件测试的目的是什么&#xff1f…...

SQL第16课挑战题

1. 美国各州的缩写应始终用大写。更新所有美国地址&#xff0c;包括供应商状态&#xff08;Vendors表中的vend_state)和顾客状态&#xff08;customers表中的cust_state),使它们均为大写。 2. 第15课挑战题1要求将自己添加到customers表中&#xff0c;现在删除自己&#xff0c;…...

Python3 爬虫 中间人爬虫

中间人&#xff08;Man-in-the-Middle&#xff0c;MITM&#xff09;攻击是指攻击者与通信的两端分别创建独立的联系&#xff0c;并交换其所收到的数据&#xff0c;使通信的两端认为其正在通过一个私密的连接与对方直接对话&#xff0c;但事实上整个会话都被攻击者完全控制。在中…...

Leetcode 50. Pow ( x , n ) 快速幂、取模 C++实现

问题&#xff1a;Leetcode 50. Pow ( x , n ) 实现 pow(x, n) &#xff0c;即计算 x 的整数 n 次幂函数。 算法&#xff1a; 具体实现流程如下&#xff1a; 代码&#xff1a; class Solution { public:double myPow(double x, int N) {double ans 1;long long n N;if (n <…...

Java SE vs Java EE 与 JVM vs JDK vs JRE

Java SE&#xff08;Java Platform&#xff0c;Standard Edition&#xff09;: Java 平台标准版&#xff0c;Java 编程语言的基础&#xff0c;它包含了支持 Java 应用程序开发和运行的核心类库以及虚拟机等核心组件。Java SE 可以用于构建桌面应用程序或简单的服务器应用程序。…...

Linux YUM设置仓库优先级

1.安装yum-plugin-priorities优先级插件 yum install yum-plugin-priorities -y 2.设置仓库优先级 vim /etc/yum.repos.d/local.repo [local] namecentos7.5 baseurlfile:///mnt enable1 gpgcheck0 priority1 注释&#xff1a; priority1 #数字越小代表优先级越高&#xff…...

做一个不断更新的链接库

做一个不断更新的链接库 anaconda anaconda官方镜像源 anaconda清华镜像源 社区 CSDN CSDN-华为开发者空间 python开发库 股票爬虫 - akshare...