週報——Qt自定鍵盤插件的製作和使用

將紅外遙控器製作成qt自定義鍵盤,

有兩種方法來處理qt自定義鍵盤。一種是直接編譯qt的源碼,另外一種是製作qt插件,通過加載插件來使用鍵盤。兩種方法各有不同,但實現的效果是一樣的。我使用的是插件法,因爲不需再編譯源碼,修改方便。

環境:ubuntu10.04+qtcreator2.5.2+QtEmbedded-4.5.3-arm

 

1、編寫紅外驅動

2、打開qtcreator2.5.2,創建一個動態庫工程,並生成一個類,庫名爲sbox4x4,類名爲sbox4x4Handler;

3、實現Handler類

修改sbox4x4handler.h,加入下面三個頭文件:

#include <QObject>
#include <QtGui/QWSKeyboardHandler>
#include <QSocketNotifier>

將Sbox4x4修改成 QObject和QWSKeyboardHandler,並加入Q_OBJECT聲明,並在類中添加一個void kbdReadyRead()的slot函數,用於將來當鍵盤設備可讀時讀取鍵值:

其中,QSocketNotifier 用於對鍵盤設備文件進行狀態檢測,kbdFd用於保存鍵盤設備文件打開之後的描述符。

#ifndef SBOX4X4HANDLER_H
#define SBOX4X4HANDLER_H

#include "sbox4x4_global.h"
#include <QObject>
#include <QtGui/QWSKeyboardHandler>
#include <QSocketNotifier>
class SBOX4X4SHARED_EXPORT sbox4x4Handler
            :public QObject, public QWSKeyboardHandler
{
    Q_OBJECT


public:
    sbox4x4Handler(const QString &device = QString("/dev/ir"), QObject *parent = 0);
    ~sbox4x4Handler();

private:
    int kbdFd;
    QSocketNotifier *notifier;

private slots:
    void kbdReadyRead();

};

#endif // SBOX4X4HANDLER_H

4、改sbox4x4handler.cpp文件,完成上述幾個函數:

#include "sbox4x4handler.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <QDebug>

//在構造函數中,完成對設備的打開操作,並創建QSocketNotifier對象,永遠檢測設備的讀狀態:
sbox4x4Handler::sbox4x4Handler(const QString &device, QObject *parent)
        :QObject(parent), QWSKeyboardHandler()
{
    setObjectName("SAPP 4x4 Keyboard Handler");
    this->kbdFd = ::open(device.toAscii().constData() , O_RDONLY);
    if(this->kbdFd < 0)
        return;
    this->notifier = new QSocketNotifier(this->kbdFd, QSocketNotifier::Read, this);
    connect(this->notifier, SIGNAL(activated(int)), this, SLOT(kbdReadyRead()));
}

//析構函數中,關閉設備文件
sbox4x4Handler::~sbox4x4Handler()
{
    if(this->kbdFd >= 0)
        ::close(this->kbdFd);
}

//在kbdReadyRead槽函數中,完成對設備文件的讀取和鍵值映射:
 void sbox4x4Handler::kbdReadyRead()
 {
     int key;
     if(read(this->kbdFd, &key, sizeof(key)) < 0) //   讀取設備文件      
           return;
     Qt::KeyboardModifiers modifiers = Qt::NoModifier;
     int unicode = 0x0000; //unicode  用於保存映射之後的字符
     int keycode = 0; //keycode用於保存映射之後的Qt::Key類型的鍵值
     switch(key)
     {
     case 0: keycode = Qt::Key_0; break; //可以選擇不同的鍵
     case 1: keycode = Qt::Key_1; break;
     case 2: keycode = Qt::Key_2; break;
     case 3: keycode = Qt::Key_3; break;
     case 4: keycode = Qt::Key_4; break;
     case 5: keycode = Qt::Key_5; break;
     case 6: keycode = Qt::Key_6; break;
     case 7: keycode = Qt::Key_7; break;
     case 8: keycode = Qt::Key_8; break;
     case 9: keycode = Qt::Key_9; break;
     case 10: keycode = Qt::Key_Up; break;
     case 11: keycode = Qt::Key_Down; break;
     case 12: keycode = Qt::Key_Left; break;
     case 13: keycode = Qt::Key_Right; break;
     case 14: keycode = Qt::Key_Enter; break;
     case 15: keycode = Qt::Key_Direction_L; break;
     case 16: keycode = Qt::Key_Tab; break;
     case 17: keycode = Qt::Key_VolumeDown; break;
     case 18: keycode = Qt::Key_VolumeUp; break;
     case 19: keycode = Qt::Key_Backspace; break;
     default:return;
     }
     this->processKeyEvent(unicode, keycode, modifiers, 1, false);
 }

5、QKbdDriverPlugin的派生類。

首先創建一個新的C++ Class:

取名爲Sbox4x4Plugin,Base Class輸入QKbdDriverPlugin:

在Sbox4x4Plugin類中,重點是重載QKbdDriverPlugin基類中的create和keys:

注意,Qt Creator自動生成的類定義中,包含的頭文件不正確,直接包含QKbdDriverPlugin會提示找不到,需要加上QtGui/QKbdDriverPlugin

#include <QtGui/QKbdDriverPlugin>

#ifndef SBOX4X4PLUGIN_H
#define SBOX4X4PLUGIN_H

//#include <QKbdDriverPlugin>
#include <QtGui/QKbdDriverPlugin>
class Sbox4x4Plugin : public QKbdDriverPlugin
{
    Q_OBJECT


public:
    Sbox4x4Plugin();
    QWSKeyboardHandler *create(const QString &driverName, const QString &deviceName = QString("/dev/ir"));
    QStringList keys() const;
};

#endif // SBOX4X4PLUGIN_H

6、.在sbox4x4plugin.cpp文件中,實現上述函數:

包含sbox4x4handler.h頭文件,因爲在Plugin中,需要創建Sbox4x4Handler的類的對象。

#include "sbox4x4plugin.h"
#include "sbox4x4handler.h"

Sbox4x4Plugin::Sbox4x4Plugin()
{
}
//在create中,重點是要創建一個自己的handler類對象,也就是sbox4x4的對象
QWSKeyboardHandler *Sbox4x4Plugin::create(const QString &driverName, const QString &deviceName)
{
     if(driverName.toLower() == "sbox4x4")
         return new sbox4x4Handler(deviceName);
     return NULL;
}
//在keys函數中,返回插件的名字即可
QStringList Sbox4x4Plugin::keys() const
{
    return QStringList() << "sbox4x4";
}

Q_EXPORT_PLUGIN2(sbox4x4, Sbox4x4Plugin);  //將sbox4x4這個庫中的Plugin類導出

7、編譯
        需要注意的是,在文件的最後有Q_EXPORT_PLUGIN2 (sbox4x4,Sbox4x4Plugin)一句,這個宏的第一個參數是目標庫名字去除前綴lib和版本號及擴展名之後的基本名,這個基本名要和.pro指定的TARGET項保持一致,並且和環境變量的driver內容一致;第二個參數是插件的類名。我們使用宏Q_EXPORT_PLUGIN2,輸出插件,讓插件變得可以被QT使用。

 

8、使用

使用方法:首先,將編譯出的libsbox4x4.so複製到qt安裝目錄下的plugins/kbddrivers/(沒有目錄則創建)然後,增加一個QWS_KEYBOARD環境變量:

export QWS_KEYBOARD=sbox4x4:/dev/ir ,bx4x4是庫的名字,冒號後面是輸入設備。將來,sbox4x4和/dev/kbd將被傳遞到Sbox4x4Plugin的create函數中,用於創建鍵盤處理對象。然後qt自定義的鍵盤就可以用了。

 

 

 

 

 

 

 

發佈了54 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章