一、開發環境
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
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); }
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 *))); }
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); } } }
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