一、开发环境
PC机:QT5.6.2,XP系统,QT Creator4.1
嵌入式硬件平台:TQ210核心板,板载S5PV210芯片
嵌入式软件平台:Linux3.10.46内核,UBOOT移植的是2014.12版本
二、资源简介
Qt5取消了QInputContext类后,以前在QT4.8.5上用的软键盘代码不能用了,在网上找到了大神刘典武的软键盘核心代码,经过修改可以在QT5.6上用了,嵌入式ARM平台上也试验可用。
三、源码简介
头文件定义如下:
- #ifndef KEYBOARD_H
- #define KEYBOARD_H
- #include <QWidget>
- class QStackedWidget;
- class QLabel;
- class QLineEdit;
- class QPushButton;
- class QComboBox;
- // 按钮的边长,键盘总长度=14*BTN_SIZE,键盘总宽度=3*BTN_SIZE
- #define BTN_SIZE 40
- class keyBoard : public QWidget
- {
- Q_OBJECT
- public:
- explicit keyBoard(QWidget *parent = 0);
- ~keyBoard();
- protected:
- void mouseMoveEvent(QMouseEvent *e);
- void mousePressEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *);
- private slots:
- void focusChanged(QWidget *, QWidget *nowWidget);
- void slotBtnClicked(); // 按键处理
- private:
- int deskWidth; //桌面宽度
- int deskHeight; //桌面高度
- int frmWidth; //窗体宽度
- int frmHeight; //窗体高度
- QPoint mousePoint; //鼠标拖动自定义标题栏时的坐标
- bool mousePressed; //鼠标是否按下
- void InitWindow(); //初始化无边框窗体
- void InitForm(); //初始化窗体数据
- QLineEdit *currentLineEdit; //当前焦点的文本框
- QString currentType; //当前输入法类型
- void changeType(QString type); //改变输入法类型
- void changeLetter(bool isUpper);//改变字母大小写
- void changeStyle(int style); //切换样式处理
- void setStyle(QString topColor,QString bottomColor,QString borderColor,QString textColor);
- int currentStyle;
- QStackedWidget *keyWindow; // 键盘窗口,可以翻页显示
- QWidget *letterWindow; // 字母键盘
- QWidget *signWindow; // 字母键盘
- QLabel *infoLabel; // 显示键盘信息
- QPushButton *closeBtn;
- QPushButton *delBtn;
- QPushButton *typeBtn;
- QPushButton *styleBtn;
- QPushButton *btn0;
- ...
- QPushButton *btn9;
- QPushButton *btnA;
- ...
- QPushButton *btnZ;
- QPushButton *btnSign0;
- ...
- QPushButton *btnSign12;
- };
- #endif // KEYBOARD_H
还定义的所有的按钮:数字、字母、字符按钮
鼠标相关的操作函数,是为了实现键盘界面的拖动
最核心的代码是两个槽函数:focusChanged、slotBtnClicked(),分别是处理焦点和按钮事件
其中,BTN_SIZE是每个按钮的边长,在编译之前可以更改,默认是40
cpp文件核心代码如下:
1、构造函数
- keyBoard::keyBoard(QWidget *parent) :
- QWidget(parent)
- {
- this->InitWindow();
- this->InitForm();
- QDesktopWidget* w = QApplication::desktop();
- deskWidth = w->screenGeometry().width();
- deskHeight = w->screenGeometry().height();
- frmWidth = this->width();
- frmHeight = this->height();
- }
首先,调用了初始化界面布局和私有数据函数,然后获取显示设备的分辩率
2、初始化界面布局函数
- void keyBoard::InitWindow()
- {
- this->setProperty("Form", true);
- this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
- this->setFixedSize(14 * BTN_SIZE, 3 * BTN_SIZE);
- this->setFocusPolicy(Qt::NoFocus);
- keyWindow = new QStackedWidget(this);
- keyWindow->setFixedSize(13 * BTN_SIZE, 2 * BTN_SIZE);
- letterWindow = new QWidget;
- signWindow = new QWidget;
- // 填加功能按钮
- closeBtn = new QPushButton(this);
- closeBtn->setObjectName("closeBtn");
- closeBtn->setProperty("function", true);
- closeBtn->setText(tr("X"));
- closeBtn->setFixedSize(BTN_SIZE, BTN_SIZE);
- // 删除一个字符
- delBtn = new QPushButton(this);
- delBtn->setObjectName("delBtn");
- delBtn->setProperty("function", true);
- delBtn->setText(tr("D"));
- delBtn->setFixedSize(BTN_SIZE, BTN_SIZE);
- // 改变输法类型:大写,小写,字符
- typeBtn = new QPushButton(this);
- typeBtn->setObjectName("typeBtn");
- typeBtn->setProperty("function", true);
- typeBtn->setText(tr("小"));
- typeBtn->setFixedSize(BTN_SIZE, BTN_SIZE);
- // 换肤
- styleBtn = new QPushButton(this);
- styleBtn->setObjectName("styleBtn");
- styleBtn->setProperty("function", true);
- styleBtn->setText(tr("style"));
- styleBtn->setFixedSize(BTN_SIZE, BTN_SIZE);
- // 填加数字键盘
- btn1 = new QPushButton(this);
- btn1->setText(tr("1"));
- btn1->setProperty("num", true);
- btn1->setFixedSize(BTN_SIZE, BTN_SIZE);
- 。。。。。。
- layout->addWidget(delBtn, 0,11,1,1);
- layout->addWidget(closeBtn, 0,12,1,1);
- layout->addWidget(typeBtn, 1,13,1,1);
- layout->addWidget(styleBtn, 2,13,1,1);
- layout->addWidget(keyWindow,1,0,2,13);
- layout->setSpacing(0);
- layout->setContentsMargins(0, 0, 0, 0);
- this->setLayout(layout);
- }
首先,设定了键盘界面的尺寸,然后具体定义了所有控件,最后给界面布局。
3、初始化数据函数
- void keyBoard::InitForm()
- {
- currentStyle = 0;
- currentLineEdit = 0;
- mousePressed = false;
- currentType = "min";
- changeType("min");
- currentStyle = 0;
- changeStyle(currentStyle);
- QList<QPushButton *> btn = this->findChildren<QPushButton *>();
- foreach (QPushButton * b, btn) {
- connect(b, SIGNAL(clicked()), this, SLOT(slotBtnClicked()));
- }
- // 绑定全局改变焦点信号槽
- connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)),
- this, SLOT(focusChanged(QWidget *, QWidget *)));
- }
首先,初始化私有数据,然后把所有按钮都邦定按钮处理槽函数,最后绑定全局焦点改变时的处理函数,这个函数也是呼出键盘的核心。
4、焦点处理函数
- void keyBoard::focusChanged(QWidget *, QWidget *nowWidget)
- {
- if (nowWidget != 0 && !this->isAncestorOf(nowWidget))
- {
- if (nowWidget->inherits("QLineEdit"))
- {
- currentLineEdit = (QLineEdit *)nowWidget;
- QPoint movePoint;
- // 鼠标点击位置坐标
- if (QCursor::pos().y() > deskHeight / 2)
- {
- // 靠上居中显示
- movePoint = QPoint(deskWidth/2 - frmWidth/2, 0);
- }
- else
- {
- // 靠下居中显示
- movePoint = QPoint(deskWidth/2 - frmWidth/2, deskHeight - frmHeight);
- }
- this->move(movePoint);
- this->repaint();
- this->setVisible(true);
- }
- else
- {
- currentLineEdit = 0;
- //qDebug() << "BBB";
- this->setVisible(false);
- // 需要将输入法切换到最初的原始状态--小写
- currentType="min";
- changeType(currentType);
- currentStyle = 0;
- changeStyle(currentStyle);
- keyWindow->setCurrentIndex(0);
- }
- }
- }
5、按键处理函数
- void keyBoard::slotBtnClicked()
- {
- QPushButton *btn = (QPushButton *)sender();
- QString objectName = btn->objectName();
- if (objectName == "typeBtn")
- {
- if (currentType == "min")
- {
- currentType = "max";
- }
- else if (currentType == "max")
- {
- currentType = "sign";
- }
- else
- {
- currentType = "min";
- }
- changeType(currentType);
- }
- else if (objectName == "delBtn")
- 。。。。。。
- else
- {
- QString value = btn->text();
- // 如果是&按钮,因为对应&被过滤,所以真实的text为去除前面一个&字符
- if (value == "&&")
- {
- value = value.right(1);
- }
- // 当前不是中文模式,则单击按钮对应text为传递参数
- if (currentType != "chinese")
- {
- if (currentLineEdit != 0)
- {
- currentLineEdit->insert(value);
- }
- }
- }
- }
6、主函数调用方法
- #include "keyBoard.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- keyBoard keyBoard;
- keyBoard.hide();
- MainWindow w;
- w.show();
- return a.exec();
- }
只需填加头文件定义,然后在main函数里实例化就可以了。
四、效果
五、总结
程序是在QT5.6的环境下编写的,理论上来说,QT4也可以运行,但我没试验。在PC机和ARM嵌入式开发板都可以完美运行。
此虚拟键盘程序只包含两个文件,可以非常方便的加入到现有的工程当中。
程序完整源码见附件。
http://download.csdn.net/download/wzs250969969/10050991