• 7702阅读
  • 24回复

QT4QT5均可使用的虚拟键盘 [复制链接]

上一主题 下一主题
离线seejv134
 

只看楼主 倒序阅读 楼主  发表于: 2019-03-07
— 本帖被 20091001753 执行加亮操作(2019-05-24) —
由于项目需要,网络上关于QT4的键盘又不好找,因此便自己造轮子,造了个虚拟键盘,先看效果图片


使用过程

  1. ui->setupUi(this);vb_=new VirtualKeyBoard(this);
  2. vb_->setGeometry(500,0,800,400);
  3. vb_->hide();
  4. vb_->setAutoShow(ui->lineEdit_2);//自定义的lineedit
  5. vb_->setAutoShow(ui->textEdit);//自定义的textEdit




构成介绍

1、使用 sqlite3 数据
2、UI设计使用的 ui设计大师
3、keyboard.qss
4、拼音-汉字数据库



期间遇到的难点



如何输入拼音,然后得到中文词汇?

这个问题后来经高人指点,决定使用sqlite3 数据的模糊查找,后来经过自己测试,发现这个也可以实现中文词组的查找,实现了输入法的 中文联想 功能。主要实现代码如下:
  1. QMap<int, QStringList> VirtualKeyBoard::getChineseListMap(const QString &cur_text)
  2. {
  3. //    QStringList chinese_list{};
  4.     QMap<int, QStringList>list_map{};
  5.     int page(0);
  6.     int index(-1);//计数是否达到最大显示数
  7.     if(cur_text.isEmpty())
  8.         return list_map;
  9.     if(QSqlDatabase::contains("my_sqlite"))
  10.          *db_ = QSqlDatabase::database("my_sqlite");
  11.      else
  12.          *db_ = QSqlDatabase::addDatabase("QSQLITE", "my_sqlite");
  13.     //打开数据库
  14.     if(!db_->open())
  15.     {
  16.         qDebug()<<__func__<<db_->lastError();
  17.         return list_map;
  18.     }
  19.     QString py(cur_text);
  20.     QSqlQuery query(*db_);
  21.     int count(0);
  22.     if( cur_text.size()<last_py_text_.size() && !last_py_.isEmpty())//按了退格键
  23.     {
  24.         last_py_.remove(last_py_.size()-3,1);
  25.     }
  26.         while(1)//根据拼音获取对因汉字/词组
  27.         {
  28.             const QString command = "select PinYin, Chinese from WordAndGroup where PinYin like ""'"+py+"%;'";
  29.             if(!query.exec(command))
  30.             {
  31.                 qDebug()<<__func__<<command<<db_->lastError();
  32.                 goto error;
  33.             }
  34.             while(query.next())
  35.             {
  36.                 if(index++<MAX_VISIBLE-1)
  37.                 {
  38.                     list_map[page].append(query.value(1).toString());
  39.                 }else
  40.                 {
  41.                     page++;
  42.                     index = -1;
  43.                 }
  44.             }
  45.             if(list_map[page].size()>0)
  46.             {
  47.                 last_py_=py+"%,";
  48.                 break;
  49.             }else
  50.             {
  51.                 QString str = last_py_;
  52.                 str.remove(QRegExp("%,"));
  53.                 if(++count==1)//当查询不匹配时,将新加入的词汇当作新词的开头(eg1:guoj--> guo%,j eg2:guoji -->guo%,j%,i)
  54.                 {
  55.                     py=last_py_+cur_text.mid(str.size());
  56.                 }
  57.                 else if(count==2)//若之前可以匹配现在不行,则将新加入的字母当作新词的一部分拼音(eg1:guoj-->guo%,j eg2:guoji -->guo%ji)
  58.                 {
  59.                     QString str2 = last_py_;
  60.                     str2.remove(str2.lastIndexOf("%,"), 2);
  61.                     py=str2+cur_text.mid(str.size());
  62.                 }else if(count==3)//将"last_py_"最后3个字符替换成"%,",并补充当前拼音"arg1"尚未补充在"py"上的内容
  63.                 {
  64.                     QString str2 = last_py_;
  65.                     str2.remove(str2.lastIndexOf("%,"), str2.size()-str2.lastIndexOf("%,"));
  66.                     str2.insert(str2.size()-1, "%,");
  67.                     py=str2+cur_text.mid(str.size());
  68.                 }else
  69.                 {
  70.                     break;
  71.                 }
  72.             }
  73.         }
  74. //        qDebug()<<chinese_list;
  75. error:
  76.     db_->close();
  77.     last_py_text_=cur_text;
  78.     return list_map;
  79. }




如何让使用过程尽量简化

这个我决定在每个需要使用到键盘的控件自定义两个信号,只需要信号连接完毕,就可以实现自动弹出键盘的功能了。
例如上面的调用过程中, ui->lineEdit_2 就需要添加以下自定义内容:










生成 拼音-汉字数据库


这个经过在网上翻江倒海,找到了语料库,来获得常用汉字、汉字词组,
再用QQ词库来补充部分常用词组



虚拟键盘程序:虚拟键盘,QT4.8,QT5.10测试通过 TestVirtualBoard.zip (3051 K) 下载次数:535

一名C/C++工程师,热爱编程,目前从事QT工作,以后请各位大佬多多指教。
离线cj123sn

只看该作者 1楼 发表于: 2019-03-07
很棒!,MARK
离线liudianwu

只看该作者 2楼 发表于: 2019-03-09
我也写了个类似的,用的是qt自带键盘virtualkeyboard例子里面剥离出来的谷歌内核输入法词库,这个更好一些,以前也是用数据库查询,效率太低了点。
欢迎关注微信公众号:Qt实战/Qt入门和进阶(各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发) QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线seejv134

只看该作者 3楼 发表于: 2019-03-09
效率问题,由于汉字数据库是自己生成的,在满足大部分情况下,数据库大小为1M,只要查询的数据量不是特别多,查询汉字的接口加上一些判断,还是可以让其快速响应的。实际上使用起来,可能会不如 使用谷歌拼音库 的程序(主要还是看算法),但是这应该不会影响UI交互,毕竟实际使用时并没有感到延时。
至于谷歌拼音库,还望大佬多多赐教了。

一名C/C++工程师,热爱编程,目前从事QT工作,以后请各位大佬多多指教。
离线seejv134

只看该作者 4楼 发表于: 2019-03-09
回 cj123sn 的帖子
cj123sn:很棒!,MARK (2019-03-07 13:00) 

就是喜欢会留言的小伙伴。
一名C/C++工程师,热爱编程,目前从事QT工作,以后请各位大佬多多指教。
离线宇后彩虹

只看该作者 5楼 发表于: 2019-03-09
必须赞
离线ccazqyy

只看该作者 6楼 发表于: 2019-03-12
            
离线solo_wang

只看该作者 7楼 发表于: 2019-03-15
我用过这个虚拟键盘,大多数时候都能正常运行,但是还是有时候会影响其他输入法,不知道什么原因
离线futureq

只看该作者 8楼 发表于: 2019-03-17
我刚刚也做了一个中文的,搞了两个星期,只把中文的搞得差不多了
离线drabel

只看该作者 9楼 发表于: 2019-03-18
赞,点赞
LibQQt
致力于多环境开源Application Framework,为业务层App和Library保驾护航。
工程链接:https://gitee.com/drabel/LibQQt
工程链接:https://gitee.com/drabel/multi-link

Multi-environ
致力于多操作系统多环境便捷命令运行,基于Python的多环境命令执行工具。
工程链接:https://gitee.com/drabel/PyMake

Multi-building
致力于多环境多工程视窗化命令执行,基于PyQt5的多工程视窗化命令执行工具。
工程链接:https://gitee.com/drabel/PyAutoMake

联系我
QQ: 2657635903
mail: tianduanrui@163.com
离线xdh873939316

只看该作者 10楼 发表于: 2019-03-19
非常感谢楼主,
离线seejv134

只看该作者 11楼 发表于: 2019-03-22
回 solo_wang 的帖子
solo_wang:我用过这个虚拟键盘,大多数时候都能正常运行,但是还是有时候会影响其他输入法,不知道什么原因 (2019-03-15 15:06) 

额,这个键盘是qwidget来着,都是用信号与槽来实现交互的,没办法影响到其它输入法才是。
你可以看下里面的信号传递,就明白了。
一名C/C++工程师,热爱编程,目前从事QT工作,以后请各位大佬多多指教。
离线seejv134

只看该作者 12楼 发表于: 2019-03-22
回 futureq 的帖子
futureq:我刚刚也做了一个中文的,搞了两个星期,只把中文的搞得差不多了 (2019-03-17 23:28) 

嗯,可以的,当初我也是弄了好久的。
一名C/C++工程师,热爱编程,目前从事QT工作,以后请各位大佬多多指教。
离线futureq

只看该作者 13楼 发表于: 2019-03-24
回 seejv134 的帖子
seejv134:
嗯,可以的,当初我也是弄了好久的。

你看我的
离线lilqxy

只看该作者 14楼 发表于: 2019-03-24
大佬 你这个能移植到应用程序中吧
离线heleuto

只看该作者 15楼 发表于: 2019-04-12
   试用了一下,感觉还可以,对了,数据库怎么打包进so库??
离线heleuto

只看该作者 16楼 发表于: 2019-04-12
楼主你qt4是什么版本的 qt4.8.6编译安装不支持c++11,你写的链表需要改
离线lyb_ab

只看该作者 17楼 发表于: 2019-05-24
离线qxf19870915

只看该作者 18楼 发表于: 2019-06-09
    
离线zxjrainbow

只看该作者 19楼 发表于: 2019-07-10
回 liudianwu 的帖子
liudianwu:我也写了个类似的,用的是qt自带键盘virtualkeyboard例子里面剥离出来的谷歌内核输入法词库,这个更好一些,以前也是用数据库查询,效率太低了点。
[图片] (2019-03-09 10:17) 

不知道大神的有分享吗?
离线jiandanai

只看该作者 20楼 发表于: 2019-07-30
厉害
离线rotion

只看该作者 21楼 发表于: 2019-08-05
以前做嵌入式时做的键盘,参考了几个大师的输入法例子

楼上的那个问题 资源文件需要使用Q_INIT_RESOURCE宏打包进库里

离线yang77087

只看该作者 22楼 发表于: 2019-08-08
回 heleuto 的帖子
heleuto:楼主你qt4是什么版本的 qt4.8.6编译安装不支持c++11,你写的链表需要改 (2019-04-12 13:25) 

我也是这样的情况。。。
离线once2333

只看该作者 23楼 发表于: 2021-02-16
qt5.12可完美运行,赞,研究研究
离线jazzmax

只看该作者 24楼 发表于: 2023-02-02
学习中,有个项目中正好用到。
快速回复
限100 字节
 
上一个 下一个