新版输入法V2018+V2019请移步这里:https://www.cnblogs.com/feiyangqingyun/p/9690175.html  和 https://www.cnblogs.com/feiyangqingyun/p/10433663.html

时间过得真快,不知不觉已到2015年,农历春节一眨眼就过去了,端正状态收拾心情整装待发出发。

曾经有段时间,我有一个很执着的梦想,我要导演出一部空前绝后的巨幕。不过现实无情地碾碎我的梦想,也同时将我推进了人生的低谷。

我开始思考,思想很多很多我以前总是回避的问题,在一次次思考中,我能感觉到我正在向一个陌生的地方走去,前途是光是暗也无法推测,我发现我在赌,赌注是一辈子的懊悔或是郁郁终生。

但当我看到阳光弥漫在我身边时,才发现以前的我是那么幼稚,我始终在找借口或不是借口的借口推卸掉与生俱来的责任,在光怪陆离的现实中找个僻静的地方希望过云淡风轻的日子。我错了,我拥有足够的能力却不敢恣意妄为,我拥有惊人的天赋却畏惧这只是南柯一梦,或者这本来就是梦,醒来时却是了无痕迹和无休止的眷恋。

从前有个同学问我是不是幻想过一些特别的经历会降临到自己身上,当时我只笑了笑,却不知道该怎么回答。

我想我是矛盾的,我认为我的存在与否关系到世间的万事万物,但我找不到足够的证据来证明我具有救世主的身份。因此我一度怀疑过我是不是生不逢时,或是天妒英才。

我在一次次轮回中等待着一个机会,也许是乱世,也许是太平,我没有所谓的一技之长,只有飞扬跋扈的骄傲和潮洗潮卷的胸怀。只有一笑置之的孤傲和白云苍狗的方式。我想我不该妄自菲薄,甚至这是理所当然的不加半点修饰的顺其自然。

我很喜欢这样一句话:如果我将庸碌一生的话,地球将停止转动,地球停止转动了吗?没有,那我将不会庸碌一生。

在特定的时间,特定的环境,特定的地点,有个特定的人将主宰万事万物!天生我才必有用!经典的心照不宣,只可惜他的傲慢却没有足够的能力做基垫。

我想我是对的,注定的便是永远无法改变的,过去的只是匆匆一瞥,将来的只是白驹过隙,一次次的轮回换来的是麻木的循规蹈矩,所以世界需要那么一个人----改变。

分割线-----------------------------------------------------------------------

高中和大学很喜欢文学,特别是在大学期间,在任何填写个人资料兴趣爱好一栏中填写的都是文学和编程,这就好比我的左手和右手,缺一不可。

好了言归正传,来说说Qt编写可换肤的中文拼音输入法。在ARM上,如果采用QT开发应用程序,基本上都会遇到一个问题,需要在应用程序中输入汉字,这个就比较麻烦,就算接了实体键盘,也只能输入字母和数字的,对中文无可奈何,为此就需要用QT自己来实现一个。

百度一搜索,有很多前辈都写过类似的输入法,但是基本上都是用QWSInputMethod相关的机制,我觉得这样有点不妥,绝大部分界面丑陋,只支持单个汉字输入,而且基本上不支持实体键盘和虚拟键盘同步输入。

运行截图:

特点:

1:各Qt版本(Qt4.6-Qt5.4)、各操作系统(windows、linux、嵌入式linux-ARM)全编译运行通过,界面一致。

2:支持小写、大写、中文三种模式输入,自由切换。

3:支持单拼双拼词组输入,网上大部分只支持单个汉字输入。

4:智能分页算法,可任意翻页查看汉字词组。

5:除了支持鼠标单击软键盘输入外,还支持实体键盘同步输入,代码中有映射处理,对应实体键盘的按键会反应到软键盘处理。

6:七套精美皮肤样式选择,鼠标右键任意换肤。

7:代码优化到极致,包括注释和所有完善性代码处理总共不到500行。

8:除了可以单击软键盘和实体键盘上的数字来选择对应的汉字外,还支持鼠标单击汉字显示处来选择汉字。

9:无边框窗体,可拖动移动。

10:sqlite数据库存储汉字字库,可自由添加自定义的词组。

11:参考实体键盘布局,更逼真。

12:界面布局、字库算法、界面切换100%首创处理,与任何网上的Qt输入法处理方式和布局截然不同。

核心方法:

1:获取当前焦点控件。

Qt封装了一个focusChanged信号,提供两个参数QWidget *oldWidget, QWidget *nowWidget,这样就给输入法的处理带来了极大的方便。

//绑定全局改变焦点信号槽
connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)),
            this, SLOT(focusChanged(QWidget *, QWidget *)));
void frmInput::focusChanged(QWidget *oldWidget, QWidget *nowWidget)
{
    //qDebug() << "oldWidget:" << oldWidget << "nowWidget:" << nowWidget;
    if (nowWidget !=  && !this->isAncestorOf(nowWidget)) {
        if (nowWidget->inherits("QLineEdit")) {
            currentLineEdit = (QLineEdit *)nowWidget;
            this->setVisible(true);
        } else {
            currentLineEdit = ;
            this->setVisible(false);
            //需要将输入法切换到最初的原始状态--小写
            currentType="min";
            changeType(currentType);
        }
    }
}

2:小写、大写、中文三种模式切换。

void frmInput::changeType(QString type)
{
    if (type == "max") {
        changeLetter(true);
        ui->btnType->setText("大写");
        ui->widgetTop->setVisible(false);
        this->setGeometry(this->geometry().x(), this->geometry().y(), , );
    } else if (type == "min") {
        changeLetter(false);
        ui->btnType->setText("小写");
        ui->widgetTop->setVisible(false);
        this->setGeometry(this->geometry().x(), this->geometry().y(), , );
    } else {
        changeLetter(false);
        ui->btnType->setText("中文");
        ui->widgetTop->setVisible(true);
        this->setGeometry(this->geometry().x(), this->geometry().y(), , );
        //每次切换到中文显示,都要执行清空之前中文模式下的信息
        clearChinese();
        ui->labPY->setText("");
    }
}
void frmInput::changeLetter(bool isUpper)
{
    QList<QPushButton *> btn = this->findChildren<QPushButton *>();
    foreach (QPushButton * b, btn) {
        if (b->property("btnLetter").toBool()) {
            if (isUpper) {
                b->setText(b->text().toUpper());
            } else {
                b->setText(b->text().toLower());
            }
        }
    }
}

3:软键盘按钮单击事件处理。

void frmInput::btn_clicked()
{
    QPushButton *btn = (QPushButton *)sender();
    QString objectName = btn->objectName();
    if (objectName == "btnType") {
        if (currentType == "min") {
            currentType = "max";
        } else if (currentType == "max") {
            currentType = "chinese";
        } else if (currentType == "chinese") {
            currentType = "min";
        }
        changeType(currentType);
    } else if (objectName == "btnDelete" || objectName == "btnDeleteMin") {
        //如果当前是中文模式,则删除对应拼音,删除完拼音之后再删除对应文本输入框的内容
        if (currentType == "chinese") {
            QString txt = ui->labPY->text();
            int len = txt.length();
            if (len > ) {
                ui->labPY->setText(txt.left(len - ));
                selectChinese();
            } else {
                if (currentLineEdit != ) {
                    currentLineEdit->backspace();
                }
            }
        } else {
            if (currentLineEdit != ) {
                currentLineEdit->backspace();
            }
        }
    } else if (objectName == "btnPre") {
        if (currentPY_index >= ) {
            if (currentPY_index %  == ) {
                currentPY_index -= ;
            } else {
                currentPY_index = currentPY_count - (currentPY_count % ) - ;
            }
        } else {
            currentPY_index = ;
        }
        showChinese();
    } else if (objectName == "btnNext") {
        if (currentPY_index < currentPY_count - ) {
            showChinese();
        }
    } else {
        QString value = btn->text();
        //如果是&按钮,因为对应&被过滤,所以真实的text为去除前面一个&字符
        if (objectName == "btnOther7") {
            value = value.right();
        }
        //当前不是中文模式,则单击按钮对应text为传递参数
        if (currentType != "chinese") {
            if (currentLineEdit != ) {
                currentLineEdit->insert(value);
            }
        } else {
            if (currentLineEdit != ) {
                //中文模式下,不允许输入特殊字符,单击对应数字按键取得当前索引的汉字
                if (btn->property("btnOther").toBool()) {
                    if (ui->labPY->text().length() == ) {
                        currentLineEdit->insert(value);
                    }
                } else if (btn->property("btnNum").toBool()) {
                    if (ui->labPY->text().length() == ) {
                        currentLineEdit->insert(value);
                    } else if (objectName == "btn0") {
                        setChinese();
                    } else if (objectName == "btn1") {
                        setChinese();
                    } else if (objectName == "btn2") {
                        setChinese();
                    } else if (objectName == "btn3") {
                        setChinese();
                    } else if (objectName == "btn4") {
                        setChinese();
                    } else if (objectName == "btn5") {
                        setChinese();
                    } else if (objectName == "btn6") {
                        setChinese();
                    } else if (objectName == "btn7") {
                        setChinese();
                    } else if (objectName == "btn8") {
                        setChinese();
                    } else if (objectName == "btn9") {
                        setChinese();
                    }
                } else if (btn->property("btnLetter").toBool()) {
                    ui->labPY->setText(ui->labPY->text() + value);
                    selectChinese();
                }
            }
        }
    }
}

4:汉字列表单击选择。

//事件过滤器,用于识别鼠标单击汉字标签处获取对应汉字
bool frmInput::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress) {
        if (obj == ui->labCh0) {
            setChinese();
        } else if (obj == ui->labCh1) {
            setChinese();
        } else if (obj == ui->labCh2) {
            setChinese();
        } else if (obj == ui->labCh3) {
            setChinese();
        } else if (obj == ui->labCh4) {
            setChinese();
        } else if (obj == ui->labCh5) {
            setChinese();
        } else if (obj == ui->labCh6) {
            setChinese();
        } else if (obj == ui->labCh7) {
            setChinese();
        } else if (obj == ui->labCh8) {
            setChinese();
        } else if (obj == ui->labCh9) {
            setChinese();
        }
        return false;
    } else if (event->type() == QEvent::KeyPress) {
        //如果处于中文模式,需要将当前按键对应反应到输入法界面上
        if (currentType == "chinese") {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
            if (keyEvent->key() == Qt::Key_Backspace) {
                ui->btnDelete->click();
            } else {
                QString key = keyEvent->text();
                QList<QPushButton *> btn = this->findChildren<QPushButton *>();
                foreach (QPushButton * b, btn) {
                    if (b->text() == key) {
                        b->click();
                        break;
                    }
                }
            }
            return true;
        }
        return false;
    }
    return QObject::eventFilter(obj, event);
}

5:汉字智能分页算法。

void frmInput::selectChinese()
{
    clearChinese();
    QSqlQuery query;
    QString currentPY = ui->labPY->text();
    QString sql = "select [word] from [pinyin] where [pinyin]='" + currentPY + "';";
    query.exec(sql);
    //逐个将查询到的字词加入汉字队列
    while(query.next()) {
        QString result = query.value().toString();
        if (App::PYType == "danpin") {
            allPY.append(result);
            currentPY_count++;
        } else {
            QStringList text = result.split(" ");
            foreach (QString txt, text) {
                if (txt.length() > ) {
                    allPY.append(txt);
                    currentPY_count++;
                }
            }
        }
    }
    showChinese();
}
void frmInput::showChinese()
{
    //每个版面最多显示10个汉字
    int count = ;
    currentPY.clear();
    for (int i = ; i < ; i++) {
        labCh[i]->setText("");
    }
 
    for (int i = currentPY_index; i < currentPY_count; i++) {
        if (count == ) {
            break;
        }
        QString txt = QString("%1.%2").arg(count).arg(allPY[currentPY_index]);
        currentPY.append(allPY[currentPY_index]);
        labCh[count]->setText(txt);
        count++;
        currentPY_index++;
    }
    //qDebug() << "currentPY_index:" << currentPY_index << "currentPY_count:" << currentPY_count;
}

可定制皮肤样式和输入法布局,联系QQ:517216493

可执行文件下载地址:http://pan.baidu.com/s/1sjHPM8l

核心代码下载地址:http://pan.baidu.com/s/1hqu16M4

备注:

核心代码开源,希望大家嘴下留情,10元出售完整工程,欢迎大家多多提建议!

谢谢!

编译完成后将源码下的file目录中的两个数据库文件复制到bin目录即可。

Qt编写可换肤的中文双拼汉字输入法的更多相关文章

  1. QT自定义精美换肤界面

    陆陆续续用QT开发过很多项目,也用QT写过不少私活项目,也写过N个工具,一直梦寐以求能像VC一样可以很方便的有个自定义的界面,QSS的强大让我看到了很好的希望,辗转百度谷歌无数次,一直搜索QT相关的换 ...

  2. Qt之界面换肤

    简述 常用的软件基本都有换肤功能,例如:QQ.360.迅雷等.换肤其实很简单,并没有想象中那么难,利用前面分享过的QSS系列文章,沃我们完全可以实现各种样式的定制! 简述 实现原理 效果 新建QSS文 ...

  3. qt之窗口换肤(一个qss的坑:当类属性发现变化时需要重置qss,使用rcc资源文件)

    1.相关文章 Qt 资源系统qt的moc,uic,rcc命令的使用 2.概要    毕业两年了,一直使用的是qt界面库来开发程序,使用过vs08.10.13等开发工具,并安装了qt的插件,最近在做客户 ...

  4. qt之窗口换肤

    1.相关文章 Qt 资源系统qt的moc,uic,rcc命令的使用 2.概要    毕业两年了,一直使用的是qt界面库来开发程序,使用过vs08.10.13等开发工具,并安装了qt的插件,最近在做客户 ...

  5. Qt编写安防视频监控系统11-动态换肤

    一.前言 Qt中的动态换肤技术是非常一流的,直接调用qApp->setStyleSheet(qss);就可以对整个应用程序进行换肤,如果样式表内容不多,或者对应的贴图不对,效率还是蛮好的,不过据 ...

  6. Qt编写控件属性设计器5-属性中文

    一.前言 在上一篇文章中就提到过,使用qtpropertybrowser来加载属性,对应加载到的属性是英文的,也就是控件类中Q_PROPERTY描述的变量名称,如何变成中文或者其他语言显示呢?这个就需 ...

  7. 基于QT的换肤整体解决方案(QSkinStyle)(提供Linux的XP风格)

    基于QT的换肤整体解决方案(QSkinStyle) 对QT这个成功的跨平台GUI库,本身内置了对换肤功能的实现,比如cleanlooks.plastique等跨平台风格:还有一些是和平台相关的风格,比 ...

  8. Qt编写自定义控件10-云台仪表盘

    前言 做过安防视频监控的同学都清楚,在视频监控系统软件上都可以看到一个云台控制区域,可以对球机进行下下左右等八个方位的运动控制,还可以进行复位,一般都是美工作图好,然后贴图的形式加入到软件中,好处是程 ...

  9. Qt编写安防视频监控系统(界面很漂亮)

    一.前言 视频监控系统在整个安防领域,已经做到了烂大街的程序,全国起码几百家公司做过类似的系统,当然这一方面的需求量也是非常旺盛的,各种定制化的需求越来越多,尤其是这几年借着人脸识别的东风,发展更加迅 ...

随机推荐

  1. [WinAPI] 串口1-创建[包括: 打不开串口]

    本来是用一个USB扩展把一个USB括成4个,然后把USB转串口连接上,虽然设备管理器可以找到用SSCOM也能找到,但是用API就是打不开,最后把USB转串插在电脑的一个USB上就可以啦! #inclu ...

  2. JQuery以JSON方式提交数据到服务端

    JQuery将Ajax数据请求进行了封装,从而使得该操作实现起来容易许多.以往我们要写很多的代码来实现该功能,现在只需要调用$.ajax()方法,并指明请求的方式.地址.数据类型,以及回调方法等.下面 ...

  3. C#与数据库访问技术总结(十七)

    使用DataSet对象访问数据库 当对DataSet对象进行操作时,DataSet对象会产生副本,所以对DataSet里的数据进行编辑操作不会直接对数据库产生影响,而是将DataRow的状态设置为ad ...

  4. Java程序员的日常 —— 工作一天的收获

    看题目可能是扯皮,其实还是有很多专业知识的.从最开始没有注意到设计原则,到后面的jquery实战技巧,都是今天一天碰到的问题. 每天整理一点点,每天收获一点点. 关于软件设计 在设计系统结构的时候,一 ...

  5. paip.突破 网站 手机 验证码 的 破解 总结

    paip.突破 网站 手机 验证码 的 破解 总结  作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn ...

  6. Mac OS X 系统12个常用的文本编辑快捷键(移动、选中)

    经常和文字处理打交道?如果多多使用下面这 12 个快捷键,在移动.选择.复制等操作文字时效率会大大提升. 6 个移动光标的快捷键第一组快捷键可以用来在文本中快速移动光标: 跳到本行开头 – Comma ...

  7. 支付宝Wap支付你了解多少?

    上几篇文章详细介绍了支付宝APP支付.微信APP支付 此文章来介绍下支付宝Wap支付(也叫作手机网站支付) 目录 1.创建应用并获取APPID 2.配置应用环境 3.配置沙箱环境 4.服务端实现(Ma ...

  8. ZookeeperNet太难用,写了个RetryHelper来进行配套使用

    普通的zk用法,如下写法: zk.Exists("/aaa", true); zk.Create(...); 但是由于这些API会抛Zookeeper的Exception,比如Co ...

  9. 第六章 - 图像变换 - 图像拉伸、收缩、扭曲、旋转[1] - 仿射变换(cvWarpAffine)

    拉伸.收缩.扭曲.旋转是图像的几何变换,在三维视觉技术中大量应用到这些变换,又分为仿射变换和透视变换.仿射变换通常用单应性建模,利用cvWarpAffine解决密集映射,用cvTransform解决稀 ...

  10. Hadoop jar配置使用JMX进行远程JVM监控

    背景:  编写了一个MapReduce程序,发现该程序内存占用非常多,需要有一种方法来分析内存详细的占用情况. 可以使用linux上的pmap –d <PID>来看进程逻辑地址空间使用情况 ...