Qt软键盘——解决Qt例子输入失败的问题
2016-11-14 22:10
555 查看
最近做嵌入式UI,在触摸屏上输入时需要一个软键盘,去找Qt示例时,发现有一个例子example/tools/inputpanel,我安装的版本没有这个例子,于是我就以“example/tools/inputpanel”为关键词搜索了一下,发现了在这个地方有:http://doc.qt.io/qt-4.8/qt-tools-inputpanel-example.html
在这个网页的下面,有8个文件,似乎无法直接下载,但可以看到源码,于是我是通过复制/粘贴的方式保存了这8个文件。我将代码复制过来,放到ubuntu虚拟机上,编译运行后,发现当鼠标点击一个输入框QLineEdit时,数字键盘的确能弹出来(如下图)
但是,无论怎么点击数字键,输入框中总不出现数字或符号,试了多次都是这样,接下来我开始找原因。
MyInputPanel::buttonClicked(QWidget*w)
负责响应Input
Panel中所有输入键被按下时所产生的信号(SIGNAL),函数的内容为:
显然当键被按下时,相应的"buttonValue"(动态属性)值通过信号(characterGenerated(QChar))被传递,在发射(emit)之前,我加了一句
即每输入一个字符,打印一下传递的字符,发现打印正常。
而信号(SIGNAL)characterGenerated(chr)的槽为myinputpanelcontext.cpp中的函数:
在这个函数里通过qWarning添加打印信息,发现函数每次都从第一个return那里结束,说明w为空。
上面的lastFocusedWidget是在myinputpanel.cpp的
中定义的。
同样地,将槽也这样修改
【注意】修改函数时,记得还要修改它的定义和声明,同时还要修改连接SIGNAL和SLOT的connect函数。
QWidget *w1)中这样修改即可:
(2)在原项目的.pro文件中添加软键盘所用到的文件(.cpp、.h、.ui文件等);
(3)在原项目的main.cpp文件中添加代码:
【注意】根据实际情况,不一定是app. setInputContext(ic),要看QApplication的对象名。
如果需要源码,可以给我发邮件:fengyuyixin@qq.com
在这个网页的下面,有8个文件,似乎无法直接下载,但可以看到源码,于是我是通过复制/粘贴的方式保存了这8个文件。我将代码复制过来,放到ubuntu虚拟机上,编译运行后,发现当鼠标点击一个输入框QLineEdit时,数字键盘的确能弹出来(如下图)
但是,无论怎么点击数字键,输入框中总不出现数字或符号,试了多次都是这样,接下来我开始找原因。
1.按下数字键,是否有事件响应呢?
在myinputpanel.cpp中,函数(SLOT)voidMyInputPanel::buttonClicked(QWidget*w)
负责响应Input
Panel中所有输入键被按下时所产生的信号(SIGNAL),函数的内容为:
void MyInputPanel::buttonClicked(QWidget *w) { QChar chr = qvariant_cast<QChar>(w->property("buttonValue")); emit characterGenerated(chr); }
显然当键被按下时,相应的"buttonValue"(动态属性)值通过信号(characterGenerated(QChar))被传递,在发射(emit)之前,我加了一句
qWarning(QString(chr).toStdString().c_str());
即每输入一个字符,打印一下传递的字符,发现打印正常。
而信号(SIGNAL)characterGenerated(chr)的槽为myinputpanelcontext.cpp中的函数:
void MyInputPanelContext::sendCharacter(QChar character) { QPointer<QWidget> w = focusWidget(); if (!w) return; //从这里返回 QKeyEvent keyPress(QEvent::KeyPress, character.unicode(), Qt::NoModifier, QString(character)); QApplication::sendEvent(w, &keyPress); if (!w) return; QKeyEvent keyRelease(QEvent::KeyPress, character.unicode(), Qt::NoModifier, QString()); QApplication::sendEvent(w, &keyRelease); }
在这个函数里通过qWarning添加打印信息,发现函数每次都从第一个return那里结束,说明w为空。
2.为什么输入不成功?
为什么w为空呢?思考后得出结论:这个函数的做法是获取原窗口中焦点控件,然后将键盘上的输入值传递给它。而当我们在软键盘上输入时,焦点控件会变为我们刚点击的输入键QPushButton,而不是我们之前选择的QLineEdit。3.这个问题怎么解决?
我的解决办法是,信号(SIGNAL)characterGenerated(chr)发射时将上一个焦点传递过去,即把characterGenerated(chr)改为void characterGenerated(QChar character, QWidget *w) { QChar chr = qvariant_cast<QChar>(w->property("buttonValue")); emit characterGenerated(chr,lastFocusedWidget); }
上面的lastFocusedWidget是在myinputpanel.cpp的
void MyInputPanel::saveFocusWidget(QWidget * /*oldFocus*/, QWidget*newFocus) { if (newFocus != 0 && !this->isAncestorOf(newFocus)) { lastFocusedWidget = newFocus; } }
中定义的。
同样地,将槽也这样修改
void MyInputPanelContext::sendCharacter(QChar character, QWidget *w1) { QPointer<QWidget> w = w1; if (!w) return; QKeyEvent keyPress(QEvent::KeyPress, character.unicode(), Qt::NoModifier, QString(character)); QApplication::sendEvent(w, &keyPress); if (!w) return; QKeyEvent keyRelease(QEvent::KeyPress, character.unicode(), Qt::NoModifier, QString()); QApplication::sendEvent(w, &keyRelease); }
【注意】修改函数时,记得还要修改它的定义和声明,同时还要修改连接SIGNAL和SLOT的connect函数。
4.如何实现删除功能?
其实很简单,我只不过将原图中的#变成了←,其实传递的"buttonValue"还是为#,所以只需在sendCharacter(QCharcharacter,QWidget *w1)中这样修改即可:
void MyInputPanelContext::sendCharacter(QChar character, QWidget *w1) { QPointer<QWidget> w = w1; if (!w) return; if(character.unicode() == '#') { QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier); QApplication::sendEvent(w, &keyPress); } else { QKeyEvent keyPress(QEvent::KeyPress, character.unicode(), Qt::NoModifier, QString(character)); QApplication::sendEvent(w, &keyPress); } if (!w) return; QKeyEvent keyRelease(QEvent::KeyPress, character.unicode(), Qt::NoModifier, QString()); QApplication::sendEvent(w, &keyRelease); }
5.如何将这个功能移植到其他项目中?
(1)将这些文件与原项目文件放在一起(不包括.pro文件和main.cpp);(2)在原项目的.pro文件中添加软键盘所用到的文件(.cpp、.h、.ui文件等);
(3)在原项目的main.cpp文件中添加代码:
MyInputPanelContext*ic = new MyInputPanelContext; app.setInputContext(ic);
【注意】根据实际情况,不一定是app. setInputContext(ic),要看QApplication的对象名。
6.下面是效果图
如果需要源码,可以给我发邮件:fengyuyixin@qq.com
相关文章推荐
- Qt中关于无法定位程序输入点的一种问题解决方式
- Qt使用第三方类打开串口号10以上的失败问题解决方法
- unbuntu中改变shell时,输入chsh,在输入密码,提示PAM的验证失败问题的解决
- 解决Ubuntu环境下vim和QT中文输入问题
- 解决QtCreator4.0.2(Qt5.7.0)输入中文输出乱码的问题 //QtCreator4.4.1 (Qt5.9.2也适用)
- QT工程看不到头文件和源文件qmake失败stat(".")failed问题解决
- 编译qt例子工程animatedtiles遇到问题 及解决办法
- Qt无法输入中文问题解决
- Qt下无法输入中文问题的解决
- QT5.3 error: LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 问题解决
- 解决QT无法切换fcitx中文输入的时make编译出现的问题
- 解决 Ubuntu 14.04 下 Qt5 中文显示和中文输入法问题
- 扩展显示器失败:“显示信号输入超出范围“问题解决方案
- 解决Qt 5.7自带Creator在Ubuntu 16.04下不能输入中文的问题(fcitx输入框架)
- 关于Qt 程序Release后不能找到输入点的问题解决
- Ubuntu Kylin中解决qt加载mysql数据库失败的问题
- 关于解决sql server 2000安装失败的问题
- 彻底解决 CrystalReports 登录失败问题
- oracle中解决汉字无法显示、输入问题
- 解决某些qt软件的乱码问题