周报——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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章