Qt之软键盘的实现

news2024/9/27 5:40:53

文章目录

  • 前言
  • 一、基于中文汉字数据库
    • 1、核心代码
    • 2、效果
  • 二、基于谷歌拼音输入引擎
    • 1、核心代码
    • 2、效果


前言

  Qt5.8版本开始推出了基于QML实现的软键盘功能,在此之前,并没有官方版本的软键盘。本篇主要介绍Qt实现软键盘的两种方案,一种基于中文汉字数据库,一种基于谷歌拼音输入引擎。
  第一种中文提示有所限制,不够智能,建议使用第二种方案,Qt官方推出的软键盘也是基于谷歌拼音输入引擎实现的。

一、基于中文汉字数据库

  这种方式将中文汉字存放在py.db文件中,按照拼音去库中查询匹配的汉字,然后将多个查询结果显示出来。
  工程组织结构,如下:
在这里插入图片描述

1、核心代码

  核心代码如下:

//事件过滤器,用于识别鼠标单击汉字标签处获取对应汉字
bool frmInput::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress) {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
        if (mouseEvent->button() == Qt::LeftButton) {
            if (obj == ui->labCh0) {
                setChinese(0);
            } else if (obj == ui->labCh1) {
                setChinese(1);
            } else if (obj == ui->labCh2) {
                setChinese(2);
            } else if (obj == ui->labCh3) {
                setChinese(3);
            } else if (obj == ui->labCh4) {
                setChinese(4);
            } else if (obj == ui->labCh5) {
                setChinese(5);
            } else if (obj == ui->labCh6) {
                setChinese(6);
            } else if (obj == ui->labCh7) {
                setChinese(7);
            } else if (obj == ui->labCh8) {
                setChinese(8);
            } else if (obj == ui->labCh9) {
                setChinese(9);
            } else if (currentEditType != "" && obj != ui->btnClose) {
                QString objName = obj->objectName();
                if (!obj->property("noinput").toBool() && objName != "frmMainWindow"
                        && objName != "frmInputWindow" && objName != "qt_edit_menu") {
                    ShowPanel();
                }
            }

            btnPress = (QPushButton *)obj;
            if (checkPress()) {
                isPress = true;
                timerPress->start(500);
            }
            return false;
        }
    } else if (event->type() == QEvent::MouseButtonRelease) {
        btnPress = (QPushButton *)obj;
        if (checkPress()) {
            isPress = false;
            timerPress->stop();
        }
        return false;
    } else if (event->type() == QEvent::KeyPress) {
        //如果输入法窗体不可见,则不需要处理
        if (!isVisible()) {
            return QWidget::eventFilter(obj, event);
        }

        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        //Shift切换输入法模式,esc键关闭输入法面板,空格取第一个汉字,退格键删除
        //中文模式下回车键取拼音,中文模式下当没有拼音时可以输入空格
        if (keyEvent->key() == Qt::Key_Space) {
            if (ui->labPY->text() != "") {
                setChinese(0);
                return true;
            } else {
                return false;
            }
        } else if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
            insertValue(ui->labPY->text());
            ui->labPY->setText("");
            selectChinese();
            return true;
        } else if (keyEvent->key() == Qt::Key_Shift) {
            ui->btnType->click();
            return true;
        } else if (keyEvent->key() == Qt::Key_Escape) {
            ui->btnClose->click();
            return true;
        } else if (keyEvent->key() == Qt::Key_Backspace) {
            ui->btnDelete->click();
            return true;
        } else if (keyEvent->text() == "+" || keyEvent->text() == "=") {
            if (ui->labPY->text() != "") {
                ui->btnNext->click();
                return true;
            } else {
                return false;
            }
        } else if (keyEvent->text() == "-" || keyEvent->text() == "_") {
            if (ui->labPY->text() != "") {
                ui->btnPre->click();
                return true;
            } else {
                return false;
            }
        } else if (keyEvent->key() == Qt::Key_CapsLock) {
            if (currentType != "max") {
                currentType = "max";
            } else {
                currentType = "min";
            }
            changeType(currentType);
            return true;
        } else {
            if (currentEditType == "QWidget") {
                return false;
            }
            QString key;
            if (currentType == "chinese") {
                key = keyEvent->text();
            } else if (currentType == "min") {
                key = keyEvent->text().toLower();
            } else if (currentType == "max") {
                key = keyEvent->text().toUpper();
            }
            QList<QPushButton *> btn = this->findChildren<QPushButton *>();
            foreach (QPushButton * b, btn) {
                if (b->text() == key) {
                    b->click();
                    return true;
                }
            }
        }
        return false;
    }
    return QWidget::eventFilter(obj, event);
}

查询中文汉字数据库,代码如下:

void frmInput::selectChinese()
{
    clearChinese();
    QSqlQuery query(QSqlDatabase::database("py"));
    QString currentPY = ui->labPY->text();
    QString sql = QString("select word from pinyin where pinyin='%1'").arg(currentPY);
    query.exec(sql);
    //逐个将查询到的字词加入汉字队列
    while(query.next()) {
        QString result = query.value(0).toString();
        QStringList text = result.split(" ");
        foreach (QString txt, text) {
            if (txt.length() > 0) {
                allPY.append(txt);
                currentPY_count++;
            }
        }
    }
    showChinese();
}

2、效果

效果如下:
在这里插入图片描述

二、基于谷歌拼音输入引擎

  这种方式基于谷歌拼音输入引擎,引擎源码在这里googlepinyin.7z,若想仔细研究,可自行下载。对外提供的接口在pinyinime.h文件里面,主要依赖dict_pinyin_user.dat和dict_pinyin.dat文件。
  工程组织结构,如下:
在这里插入图片描述

1、核心代码

  核心代码如下:

//事件过滤器,用于识别鼠标单击汉字标签处获取对应汉字
bool easyInput::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress) {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
        if (mouseEvent->button() == Qt::LeftButton) {
            if (obj == ui->labCh1) {
                setChinese(0);
            } else if (obj == ui->labCh2) {
                setChinese(1);
            } else if (obj == ui->labCh3) {
                setChinese(2);
            } else if (obj == ui->labCh4) {
                setChinese(3);
            } else if (obj == ui->labCh5) {
                setChinese(4);
            } else if (currentEditType != "" && obj != ui->btnClose) {
                QString objName = obj->objectName();
                if (obj->parent() != 0x0 && !obj->property("noinput").toBool() && objName != "frmMainWindow"
                        && objName != "frmInputWindow" && objName != "qt_edit_menu" && objName != "labPY") {
                    if (obj->inherits("QGroupBox") || obj->inherits("QFrame") || obj->inherits("QMenu")) {
                        hidePanel();
                    } else {
                        showPanel();
                    }
                }
            }
            btnPress = (QPushButton *)obj;
            if (checkPress()) {
                isPress = true;
                timerPress->start(500);
            }
            return false;
        }
    } else if (event->type() == QEvent::MouseButtonRelease) {
        btnPress = (QPushButton *)obj;
        if (checkPress()) {
            isPress = false;
            timerPress->stop();
        }

        return false;
    } else if (event->type() == QEvent::KeyPress) {
        //如果输入法窗体不可见,则不需要处理
        if (!isVisible() && !mini) {
            return QWidget::eventFilter(obj, event);
        }

        QString labText = ui->labPY->text();
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);

        //Shift切换输入法模式,esc键关闭输入法面板,空格取第一个汉字,退格键删除
        //中文模式下回车键取拼音,中文模式下当没有拼音时可以输入空格
        if (keyEvent->key() == Qt::Key_Space) {
            if (labText != "") {
                ui->labPY->setText("");
                setChinese(0);
                return true;
            } else {
                return false;
            }
        } else if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
            if (labText != "") {
                insertValue(labText);
                ui->labPY->setText("");
                selectChinese();
            } else {
                //hidePanel(); //2019年12月4日 14:56:03
            }
            //return true;
        } else if (keyEvent->key() == Qt::Key_Control) {
            //
        } else if (keyEvent->key() == Qt::Key_Shift) {
                ui->btnType->click();
                return true;
        } else if (keyEvent->key() == Qt::Key_Escape) {
            ui->btnClose->click();
            return true;
        } else if (keyEvent->key() == Qt::Key_Backspace) {
            if (inputType == "chinese") {
                QString txt = labText;
                int len = txt.length();
                if (len > 0) {
                    ui->labPY->setText(txt.left(len - 1));
                    selectChinese();
                    return true;
                }
            }
        } else if (keyEvent->key() == Qt::Key_CapsLock) {
            ui->btnUpper->click();
            return true;
        } else if (keyEvent->text() == "+" || keyEvent->text() == "=") {
            if (labText != "") {
                ui->btnNext->click();
                return true;
            } else {
                return false;
            }
        } else if (keyEvent->text() == "-" || keyEvent->text() == "_") {
            if (labText != "") {
                ui->btnPre->click();
                return true;
            } else {
                return false;
            }
        } else {
            if (currentEditType == "QWidget") {
                return false;
            }

            QString key;
            if (inputType == "chinese") {
                key = keyEvent->text();
            } else if (inputType == "english") {
                if (upper) {
                    key = keyEvent->text().toUpper();
                } else {
                    key = keyEvent->text().toLower();
                }
            }

            if (!key.isEmpty()) {
                QList<QPushButton *> btn = ui->widgetMain->findChildren<QPushButton *>();
                foreach (QPushButton *b, btn) {
                    QString text = b->text();
                    if (!text.isEmpty() && text == key) {
                        b->click();
                        return true;
                    }
                }
            }
        }

        return false;
    }

    return QWidget::eventFilter(obj, event);
}

2、效果

效果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/127191.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[python][GUI]pyside6

------------------------------------------------------------------------------------------------------------------ #非常好资料和教程&#xff1a; 1. Module Index - Qt for Python 2. muziing/PySide6-Code-Tutorial: 可能是最好的PySide6中文教程&#xff01;用代…

Spring boot 日志直接推送到elasticsearch上

Spring boot 日志直接推送到elasticsearch前言核心依赖elasticsearch配置文件1.url格式如下2.index索引前缀 "xxx"3.maxMessageSize参数数据内容最大值&#xff0c;本文未使用&#xff08;默认值-1全部数据接收&#xff09;如下4.BasicAuthentication.java 重写该类用…

详解opencv库函数ellipse()

opencv库函数ellipse()函数可以画扇形&#xff0c;也可以画椭圆。画扇形时只需要将椭圆的长短轴长度设为相同并给定扇形的圆心角即可。 # 参数 1.目标图片 2.椭圆圆心 3.长短轴长度 4.偏转角度 5.圆弧起始角度 6.终止角度 7.颜色 8.是否填充 cv2.ellipse(img_p, (500, 2…

[python] PyMouse、PyKeyboard用python操作鼠标和键盘

1、PyUserInput 简介 PyUserInput是一个使用python的跨平台的操作鼠标和键盘的模块&#xff0c;非常方便使用。支持的平台及依赖如下&#xff1a; Linux - XlibMac - Quartz, AppKitWindows - pywin32, pyHook 支持python版本&#xff1a;我用的是3.6.7 2、安装 直接源码安装…

越南猫年来袭!2023Lazada年货节热销品趋势

距离2023年春节倒计时23天&#xff01;大家是否对春节假期已经满怀期待了&#xff1f;越南人也和我们一样正期盼着新年到来&#xff0c;越南所有的传统节日都是按照农历来算的&#xff0c;其中春节也是越南重大的节日。春节将至&#xff0c;提前置办年货成了越南人和华人必不可…

MySQL 表的增删改查(进阶篇②)· 联合查询 内连接 外连接 · 自连接 · 子查询 exists · 合并查询 union

接进阶篇①&#xff0c;我们继续学习。 一、联合查询1.1 内连接1.2 外连接1.3 内连接和左右外连接的区别二、自连接三、子查询3.1 单行子查询3.2 多行子查询使用 in 范围匹配多行另一种写法 exists两种写法的区别3.3 在 from 子句中使用子查询四、合并查询unionunion all一、联…

随谈_前端与后端

文章目录一、前言二、前后端分别是什么&#xff1f;2.1. 前端&#xff08;front end&#xff09;2.2. 后端&#xff08;back end&#xff09;一、前言 最近在学习Vue&#xff0c;打算边学边用&#xff0c;开发一个网页系统。 Vue的话&#xff0c;网上介绍很多&#xff0c;简单…

容器安全的三大挑战

容器凭借其经济高效的优势改变了应用程序的交付方式&#xff0c;随着容器的普遍使用&#xff0c;管理应用程序基础设施的 IT 劳动力和资源也显著减少。然而&#xff0c;在保护容器和容器化生态系统时&#xff0c;软件团队遇到了许多障碍。尤其是习惯于更传统的网络安全流程和策…

MYSQL学习之路

MYSQL架构示意图 MYSQL8.0开始移除了查询缓存这个模块&#xff1b; 查询缓存&#xff1a;适合读多写少的任务&#xff1b; 建议&#xff1a;将 have_query_cache 设置为No&#xff0c;在需要使用查询缓存的语句上显式声明&#xff1b; select SQL_CACHE * from test;WAL(Write …

mysql sql优化、查看索引、创建索引

1.索引遵循原则 仅在被频繁检索的字段上创建索引。针对大数据量的表创建索引&#xff0c;而不是针对只有少量数据的表创建索引。通常来说&#xff0c;经常查询的记录数目少于表中总记录数据的 15% 时&#xff0c;可以创建索引。这个比例并不绝对&#xff0c;它与全表扫描速度成…

java:jackson 一:Jackson Annotation

java&#xff1a;jackson 一&#xff1a;Jackson Annotation 1 前言 参考文档地址&#xff1a; https://www.baeldung.com/jacksonhttps://www.baeldung.com/jackson-annotations2 使用 2.1 Jackson Serialization Annotations jackson 序列化注解 2.1.1 JsonAnyGetter T…

产业互联网是以大数据、云计算、AI等为代表的数字技术的出现为标志

事实上&#xff0c;以往&#xff0c;我们所经历的那个互联网玩家频出的年代&#xff0c;其实就是一个以互联网技术为主导的年代。在那样一个年代里&#xff0c;互联网技术几乎是解决一切痛点和难题的万能解药&#xff0c;几乎是破解一切行业痛点和难题的杀手锏。任何一个行业&a…

数据可视化③:大学生就业数据分析

大学生就业是和我们息息相关的话题&#xff0c;每一位大学生都关注着&#xff0c;我们常常在网络上看到有关大学生就业的话题&#xff0c;比如毕业季的一些讨论。在大一的创新创业课中&#xff0c;我们也了解到自己所学的专业和以后如何就业&#xff0c;往哪方面就业。但我们了…

深度学习目标检测_IOU、Precision、Recall、AP、mAP详解

文章目录背景IOU&#xff1a;Intersection Over Unionprecision&#xff08;精度&#xff09;和recall&#xff08;召回率&#xff09;TP、TN 、FP 、FNAP和mAP首先回顾两个概念PR曲线AP(Average Precision&#xff09;mAP(mean Average Precision)背景 目标检测的任务是找出图…

[oeasy]python0035_ 整合shell编程_循环_延迟_清屏

整合shell编程 回忆上次内容 用\r 可以让输出位置回到行首原位刷新时间 如果想要的是大字符效果 需要使用 figlet但同时还希望能刷新这可能吗&#xff1f;&#x1f914; 建立脚本 我们得熟悉一下shell 先新建一个test.sh vi test.sh python3 show_time.py python3 show_time.…

如何通过GB35114国密标准接入到LiveGBS GB28181/GB35114监控平台

1.1 安装LiveGBS GB28181/GB35114视频平台 1.2 获取设备端证书给平台 我们用LiveNVR做为设备端向LiveGBS注册&#xff0c;这里先将LiveNVR的证书导出&#xff0c;并给LiveGBS端。 本地自签名证书是LiveNVR自己给自己签发的证书。如果需要用第三方机构的证书&#xff0c;可点击…

【软件测试】资深测试的总结,有限时间找最有价值bug......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试团队的新同事&a…

Mybatis进阶之自定义TypeHandler

实际应用开发中的难免会有一些需求要自定义一个TypeHandler &#xff0c;比如这样一个需求&#xff1a;前端传来的性别是 男, 女&#xff0c;但是数据库定义的字段却是tinyint 类型&#xff08; 1:男 2:女&#xff09;。此时可以自定义一个年龄的类型处理器&#xff0c;进行转换…

Linux学习笔记——Linux实用操作(一)

04、Linux实用操作 4.1、各类小技巧&#xff08;快捷键&#xff09; 学习目标&#xff1a; 掌握各类实用小技巧 强制停止退出、登出历史命令搜索光标移动 1、Ctrlc强制停止 Linux某些程序的运行&#xff0c;如果想要强制停止它&#xff0c;可以使用快捷键Ctrlc 命令输入…

一个基于Vue+SpringBoot的个人博客项目,含数据库文件

blogSpringBoot 项目介绍 完整代码下载地址&#xff1a;一个基于VueSpringBoot的个人博客项目&#xff0c;含数据库文件 该项目是个人博客项目&#xff0c;采用Vue SpringBoot开发。 后台管理页面使用Vue编写&#xff0c;其他页面使用Thymeleaf模板。 项目演示地址&#…