Qt全平台虛擬鍵盤


    一、開發環境


    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);
        }
    }
}
首先,判斷當前焦點是否在QLineEdit控件中,然后根據焦點的坐標,顯示鍵盤的位置。
 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);
            }
        }
    }
}

根據按鍵的objectName區分不同的按鍵,進行相應的處理。

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
————————————————
版權聲明:本文為CSDN博主「急行的小船」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/wzs250969969/article/details/78418725

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM