Qt编写可换肤的中文双拼汉字输入法
时间过得真快,不知不觉已到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 != 0 && !this->isAncestorOf(nowWidget)) {
if (nowWidget->inherits("QLineEdit")) {
currentLineEdit = (QLineEdit *)nowWidget;
this->setVisible(true);
} else {
currentLineEdit = 0;
this->setVisible(false);
//需要将输入法切换到最初的原始状态--小写
currentType="min";
changeType(currentType);
}
}
}
2:小写、大写、中文三种模式切换。
{
if (type == "max") {
changeLetter(true);
ui->btnType->setText("大写");
ui->widgetTop->setVisible(false);
this->setGeometry(this->geometry().x(), this->geometry().y(), 550, 160);
} else if (type == "min") {
changeLetter(false);
ui->btnType->setText("小写");
ui->widgetTop->setVisible(false);
this->setGeometry(this->geometry().x(), this->geometry().y(), 550, 160);
} else {
changeLetter(false);
ui->btnType->setText("中文");
ui->widgetTop->setVisible(true);
this->setGeometry(this->geometry().x(), this->geometry().y(), 550, 215);
//每次切换到中文显示,都要执行清空之前中文模式下的信息
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:软键盘按钮单击事件处理。
{
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 > 0) {
ui->labPY->setText(txt.left(len - 1));
selectChinese();
} else {
if (currentLineEdit != 0) {
currentLineEdit->backspace();
}
}
} else {
if (currentLineEdit != 0) {
currentLineEdit->backspace();
}
}
} else if (objectName == "btnPre") {
if (currentPY_index >= 20) {
if (currentPY_index % 10 == 0) {
currentPY_index -= 20;
} else {
currentPY_index = currentPY_count - (currentPY_count % 10) - 10;
}
} else {
currentPY_index = 0;
}
showChinese();
} else if (objectName == "btnNext") {
if (currentPY_index < currentPY_count - 1) {
showChinese();
}
} else {
QString value = btn->text();
//如果是&按钮,因为对应&被过滤,所以真实的text为去除前面一个&字符
if (objectName == "btnOther7") {
value = value.right(1);
}
//当前不是中文模式,则单击按钮对应text为传递参数
if (currentType != "chinese") {
if (currentLineEdit != 0) {
currentLineEdit->insert(value);
}
} else {
if (currentLineEdit != 0) {
//中文模式下,不允许输入特殊字符,单击对应数字按键取得当前索引的汉字
if (btn->property("btnOther").toBool()) {
if (ui->labPY->text().length() == 0) {
currentLineEdit->insert(value);
}
} else if (btn->property("btnNum").toBool()) {
if (ui->labPY->text().length() == 0) {
currentLineEdit->insert(value);
} else if (objectName == "btn0") {
setChinese(0);
} else if (objectName == "btn1") {
setChinese(1);
} else if (objectName == "btn2") {
setChinese(2);
} else if (objectName == "btn3") {
setChinese(3);
} else if (objectName == "btn4") {
setChinese(4);
} else if (objectName == "btn5") {
setChinese(5);
} else if (objectName == "btn6") {
setChinese(6);
} else if (objectName == "btn7") {
setChinese(7);
} else if (objectName == "btn8") {
setChinese(8);
} else if (objectName == "btn9") {
setChinese(9);
}
} 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(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);
}
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:汉字智能分页算法。
{
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(0).toString();
if (App::PYType == "danpin") {
allPY.append(result);
currentPY_count++;
} else {
QStringList text = result.split(" ");
foreach (QString txt, text) {
if (txt.length() > 0) {
allPY.append(txt);
currentPY_count++;
}
}
}
}
showChinese();
}
void frmInput::showChinese()
{
//每个版面最多显示10个汉字
int count = 0;
currentPY.clear();
for (int i = 0; i < 10; i++) {
labCh[i]->setText("");
}
for (int i = currentPY_index; i < currentPY_count; i++) {
if (count == 10) {
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编写可换肤的中文双拼汉字输入法相关推荐
- QT自定义精美换肤界面
QT自定义精美换肤界面 陆陆续续用QT开发过很多项目,也用QT写过不少私活项目,也写过N个工具,一直梦寐以求能像VC一样可以很方便的有个自定义的界面,QSS的强大让我看到了很好的希望,辗转百度谷歌无数 ...
- Qt之界面换肤的两种方式
概述 像现在市面上有很多软件都有换肤功能,例如:QQ.360.迅雷等.换肤其实很简单,并没有想象中那么难,下面介绍两种实现换肤的方式,仅供参考! 方式一 1. 实现原理 创建多个QSS文件 首先,根据 ...
- Qt之界面换肤【转】
简述 实现原理 效果 新建QSS文件 编写QSS代码 加载QSS 更多参考 简述 常用的软件基本都有换肤功能,例如:QQ.360.迅雷等.换肤其实很简单,并没有想象中那么难,利用前面分享过的QSS系列 ...
- Qt在linux下无法输入中文,Ubuntu使用集成开发环境QT无法输入中文的解决方法
QT Creator是轻量级集成开发环境,在Ubuntu系统操作中,使用QT时无法输入中文,遇到这种情况要如何处理呢?下面小编就给大家介绍下Ubuntu如何解决QT无法输入中文问题. 1 安装搜狗输入 ...
- Qt编写安防视频监控系统11-动态换肤
一.前言 Qt中的动态换肤技术是非常一流的,直接调用qApp->setStyleSheet(qss);就可以对整个应用程序进行换肤,如果样式表内容不多,或者对应的贴图不对,效率还是蛮好的,不过据 ...
- qt编写网易云界面(13)----一键换肤模块
有关一键换肤,我们可以加载不同的qss文件对应其经行改变,这里模仿网易云,一键换肤的功能,直接看写过的部分. 代码这周就上传了,想要代码的朋友,记得关注与点赞,让我们共同进步. 这里我放入了6个模块颜 ...
- c语言中用qt写换肤,让Qt应用程序支持换肤(Skin)功能
Qt程序一直给人的印象是正规的GUI程序的模样.在嵌入式Linux下,Qtopia的桌面看起来跟WinCE桌面没有什么两样.相对IPHONE那样的漂亮界面.实在没有什么吸引力. 因此很多嵌入式开发人员 ...
- Qt换肤之一:基于QSS
一.效果 二.原理 1.新建多个QSS文件 2.为各个QSS文件编写对应的样式代码 3.换肤时,进行全局切换 这种方法只需熟悉QSS文件的写法,好在Qt帮助文档例子很多,要写出好看有个性的效果还得自己 ...
- 【QT学习】QSS样式表实现界面换肤(图文详解+源码)
文章目录 前言 一.实现效果 二.QSS简介及用法 1.什么是QSS? 2.怎么使用QSS? 三.QSS用法一:单个控件调用setStyleSheet函数 四.QSS用法二:编写单个界面.qss文件的 ...
最新文章
- Java中float类型精度问题
- 2.Liunx 系统设置
- 服务器和运行内存,服务器运行内存不够的解决方法
- 360浏览器打不开微信的连接服务器,上午还能打开,下午360浏览器打不开微信公 – 手机爱问...
- 基于Quartz.net 的开源任务管理平台
- 数据结构与算法 —— 链表linked list(01)
- 计算机辅助设计教案板书,计算机辅助设计教案计机辅助设计教案.doc
- redis概念、做什么及其应用场景
- 如何导出共享文件夹的权限或转移
- wps word与office word相比的优缺点
- 这些题你hold住吗?
- 如何提高学习效率,三大法则,五大步骤
- UVa 1586 Molar mass(模拟)
- win7下pytorch-gpu安装
- win7磁盘管理分区,改变页面文件卷,删除卷就由灰变黑了!
- Excel 下拉多选的设置
- clickonce程序部署后,启动不成功的问题
- DNS域名解析自制笔记
- Windows 10, version 22H2 (updated March 2023) 简体中文版、英文版下载
- 计算机初二说课稿,初二数学说课稿