查看完整版本: [-- QT4QT5均可使用的虚拟键盘 --]

QTCN开发网 -> Qt代码秀 -> QT4QT5均可使用的虚拟键盘 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

seejv134 2019-03-07 12:43

QT4QT5均可使用的虚拟键盘

由于项目需要,网络上关于QT4的键盘又不好找,因此便自己造轮子,造了个虚拟键盘,先看效果图片:
[attachment=19977]

使用过程

  1. ui->setupUi(this);vb_=new VirtualKeyBoard(this);
    vb_->setGeometry(500,0,800,400);
    vb_->hide();
    vb_->setAutoShow(ui->lineEdit_2);//自定义的lineedit
    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)
    {
    //    QStringList chinese_list{};
        QMap<int, QStringList>list_map{};
        int page(0);
        int index(-1);//计数是否达到最大显示数


        if(cur_text.isEmpty())
            return list_map;
        if(QSqlDatabase::contains("my_sqlite"))
             *db_ = QSqlDatabase::database("my_sqlite");
         else
             *db_ = QSqlDatabase::addDatabase("QSQLITE", "my_sqlite");
        //打开数据库
        if(!db_->open())
        {
            qDebug()<<__func__<<db_->lastError();
            return list_map;
        }
        QString py(cur_text);
        QSqlQuery query(*db_);
        int count(0);
        if( cur_text.size()<last_py_text_.size() && !last_py_.isEmpty())//按了退格键
        {
            last_py_.remove(last_py_.size()-3,1);
        }


            while(1)//根据拼音获取对因汉字/词组
            {
                const QString command = "select PinYin, Chinese from WordAndGroup where PinYin like ""'"+py+"%;'";
                if(!query.exec(command))
                {
                    qDebug()<<__func__<<command<<db_->lastError();
                    goto error;
                }


                while(query.next())
                {
                    if(index++<MAX_VISIBLE-1)
                    {
                        list_map[page].append(query.value(1).toString());
                    }else
                    {
                        page++;
                        index = -1;
                    }
                }
                if(list_map[page].size()>0)
                {
                    last_py_=py+"%,";
                    break;
                }else
                {
                    QString str = last_py_;
                    str.remove(QRegExp("%,"));
                    if(++count==1)//当查询不匹配时,将新加入的词汇当作新词的开头(eg1:guoj--> guo%,j eg2:guoji -->guo%,j%,i)
                    {
                        py=last_py_+cur_text.mid(str.size());
                    }
                    else if(count==2)//若之前可以匹配现在不行,则将新加入的字母当作新词的一部分拼音(eg1:guoj-->guo%,j eg2:guoji -->guo%ji)
                    {
                        QString str2 = last_py_;
                        str2.remove(str2.lastIndexOf("%,"), 2);
                        py=str2+cur_text.mid(str.size());


                    }else if(count==3)//将"last_py_"最后3个字符替换成"%,",并补充当前拼音"arg1"尚未补充在"py"上的内容
                    {
                        QString str2 = last_py_;
                        str2.remove(str2.lastIndexOf("%,"), str2.size()-str2.lastIndexOf("%,"));
                        str2.insert(str2.size()-1, "%,");
                        py=str2+cur_text.mid(str.size());
                    }else
                    {
                        break;
                    }
                }
            }
    //        qDebug()<<chinese_list;
    error:
        db_->close();
        last_py_text_=cur_text;


        return list_map;
    }




如何让使用过程尽量简化

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










生成 拼音-汉字数据库


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



虚拟键盘程序:[attachment=19978]


cj123sn 2019-03-07 13:00
很棒!,MARK

liudianwu 2019-03-09 10:17
我也写了个类似的,用的是qt自带键盘virtualkeyboard例子里面剥离出来的谷歌内核输入法词库,这个更好一些,以前也是用数据库查询,效率太低了点。
[attachment=19981]

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


seejv134 2019-03-09 11:17
cj123sn:很棒!,MARK (2019-03-07 13:00) 

就是喜欢会留言的小伙伴。

宇后彩虹 2019-03-09 12:54
必须赞

ccazqyy 2019-03-12 09:46
            

solo_wang 2019-03-15 15:06
我用过这个虚拟键盘,大多数时候都能正常运行,但是还是有时候会影响其他输入法,不知道什么原因

futureq 2019-03-17 23:28
我刚刚也做了一个中文的,搞了两个星期,只把中文的搞得差不多了

drabel 2019-03-18 12:09
赞,点赞

xdh873939316 2019-03-19 11:20
非常感谢楼主,

seejv134 2019-03-22 11:31
solo_wang:我用过这个虚拟键盘,大多数时候都能正常运行,但是还是有时候会影响其他输入法,不知道什么原因 (2019-03-15 15:06) 

额,这个键盘是qwidget来着,都是用信号与槽来实现交互的,没办法影响到其它输入法才是。
你可以看下里面的信号传递,就明白了。

seejv134 2019-03-22 11:32
futureq:我刚刚也做了一个中文的,搞了两个星期,只把中文的搞得差不多了 (2019-03-17 23:28) 

嗯,可以的,当初我也是弄了好久的。

futureq 2019-03-24 19:16
seejv134:
嗯,可以的,当初我也是弄了好久的。

你看我的[attachment=20047]

lilqxy 2019-03-24 22:28
大佬 你这个能移植到应用程序中吧

heleuto 2019-04-12 11:53
   试用了一下,感觉还可以,对了,数据库怎么打包进so库??

heleuto 2019-04-12 13:25
楼主你qt4是什么版本的 qt4.8.6编译安装不支持c++11,你写的链表需要改

lyb_ab 2019-05-24 09:36

qxf19870915 2019-06-09 19:31
    

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

不知道大神的有分享吗?

jiandanai 2019-07-30 21:20
厉害

rotion 2019-08-05 19:03
以前做嵌入式时做的键盘,参考了几个大师的输入法例子

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

[attachment=20666]

yang77087 2019-08-08 16:43
heleuto:楼主你qt4是什么版本的 qt4.8.6编译安装不支持c++11,你写的链表需要改 (2019-04-12 13:25) 

我也是这样的情况。。。

once2333 2021-02-16 17:34
qt5.12可完美运行,赞,研究研究

jazzmax 2023-02-02 19:59
学习中,有个项目中正好用到。


查看完整版本: [-- QT4QT5均可使用的虚拟键盘 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled