C0EEBDA1

在梦中,我是有超能力的。。。

« 在arm-linux-gcc 3.4.1下编译 qt-embedded-4.6.2freetype在Non-OS平台下的使用(以SPCE3200为例) »

在QT下为开发板的键盘编写输入插件

网上也有相同的文章,但在QtCreator下不知道如何跟着网上的介绍来操作,所以写了此篇文章,照着做,保证有效 ^_^

 

创建Qt的键盘插件,重点是创建两个类:

 

一个基于QObjectQWSKeyboardHandler派生的 键盘处理类(Handler

 

一个基于QKbdDriverPlugin派生的 键盘插件类(Plugin

 

 

Handler类的主要作用是完成对底层键盘设备的打开、读取等操作,并将读取到的键值映射为Qt支持的键值。

 

Plugin类的主要作用是与外部接口(因为在一个动态链接库中,Plugin类是导出的),在该类中,去创建Handler类的对象。

 

 

OK,开始实施:

 

 

1. 创建一个动态库工程,并生成一个类,假设叫做:sbox4x4Handler,这个类就是我们的Handler类。

 

 

clip_image002

 

clip_image004

 

clip_image006

 

clip_image008

 

 

2. 实现Handler类。

 

修改sbox4x4handler.h加入下面三个头文件

 

#include <QObject>

 

#include <QtGui/QWSKeyboardHandler>

 

#include <QSocketNotifier>

 

 

Sbox4x4修改成 QObjectQWSKeyboardHandler并加入Q_OBJECT声明

 

并在类中添加一个void kbdReadyRead()slot函数用于将来当键盘设备可读时读取键值

 

 

class SBOX4X4SHARED_EXPORT Sbox4x4Handler

 

    :public QObject, public QWSKeyboardHandler

 

{

 

    Q_OBJECT

 

   

 

public:

 

    Sbox4x4Handler(const QString &device = QString("/dev/kbd"), QObject *parent = 0);

 

    ~Sbox4x4Handler();

 

   

 

private:

 

    int kbdFd;

 

    QSocketNotifier *notifier;

 

   

 

private slots:

 

    void kbdReadyRead();

 

};

 

 

其中QSocketNotifier 用于对键盘设备文件进行状态检测kbdFd用于保存键盘设备文件打开之后的描述符。

 

 

 

接下来

 

修改sbox4x4handler.cpp文件完成上述几个函数

 

 

首先包含必要的头文件

 

#include <stdio.h>

 

#include <stdlib.h>

 

#include <unistd.h>

 

#include <fcntl.h>

 

#include <errno.h>

 

在构造函数中完成对设备的打开操作并创建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()

 

{

 

    char key;

 

    // 读取设备文件

 

    if(read(this->kbdFd, &key, sizeof(key)) != sizeof(key))

 

        return;

 

    Qt::KeyboardModifiers modifiers = Qt::NoModifier;

 

    // unicode用于保存映射之后的字符

 

    int unicode = 0x0000;

 

    // keycode用于保存映射之后的Qt::Key类型的键值

 

    int keycode = 0;

 

    switch(key)

 

    {

 

    case 0:

 

        keycode = Qt::Key_0;

 

        unicode = '0';

 

        break;

 

    case 1:

 

        keycode = Qt::Key_1;

 

        unicode = '1';

 

        break;

 

    case 2:

 

        keycode = Qt::Key_2;

 

        unicode = '2';

 

        break;

 

    case 3:

 

        keycode = Qt::Key_3;

 

        unicode = '3';

 

        break;

 

    case 4:

 

        keycode = Qt::Key_4;

 

        unicode = '4';

 

        break;

 

    case 5:

 

        keycode = Qt::Key_5;

 

        unicode = '5';

 

        break;

 

    case 6:

 

        keycode = Qt::Key_6;

 

        unicode = '6';

 

        break;

 

    case 7:

 

        keycode = Qt::Key_7;

 

        unicode = '7';

 

        break;

 

    case 8:

 

        keycode = Qt::Key_8;

 

        unicode = '8';

 

        break;

 

    case 9:

 

        keycode = Qt::Key_9;

 

        unicode = '9';

 

        break;

 

    case 10:

 

        keycode = Qt::Key_A;

 

        unicode = 'A';

 

        break;

 

    case 11:

 

        keycode = Qt::Key_B;

 

        unicode = 'B';

 

        break;

 

    case 12:

 

        keycode = Qt::Key_C;

 

        unicode = 'C';

 

        break;

 

    case 13:

 

        keycode = Qt::Key_D;

 

        unicode = 'D';

 

        break;

 

    case 14:

 

        keycode = Qt::Key_E;

 

        unicode = 'E';

 

        break;

 

    case 15:

 

        keycode = Qt::Key_F;

 

        unicode = 'F';

 

        break;

 

    default:

 

        return;

 

    }

 

    this->processKeyEvent(unicode, keycode, modifiers, 1, false);

 

}

 

 

OKQWSKeyboardHandler的派生类处理完毕。接下来需要创建QKbdDriverPlugin的派生类。

 

首先创建一个新的C++ Class

 

clip_image010

 

假设取名为Sbox4x4PluginBase Class输入QKbdDriverPlugin

 

clip_image012

 

 

Sbox4x4Plugin类中重点是重载QKbdDriverPlugin基类中的createkeys

 

 

注意Qt Creator 自动生成的类定义中包含的头文件不正确直接包含QKbdDriverPlugin会提示找不到需要加上QtGui/QKbdDriverPlugin

 

#include <QtGui/QKbdDriverPlugin>

 

class Sbox4x4Plugin : public QKbdDriverPlugin

 

{

 

    Q_OBJECT

 

 

public:

 

    Sbox4x4Plugin();

 

 

    QWSKeyboardHandler *create(const QString &driverName, const QString &deviceName = QString("/dev/kbd"));

 

    QStringList keys() const;

 

 

};

 

 

sbox4x4plugin.cpp文件中实现上述函数

 

不要忘记包含sbox4x4handler.h头文件因为在Plugin需要创建Sbox4x4Handler的类的对象。

 

#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";

 

}

 

 

最后,不要忘记将sbox4x4这个库中的Plugin类导出

 

Q_EXPORT_PLUGIN2(sbox4x4, Sbox4x4Plugin);

 

 

OK,编译,大功告成。

 

 

使用:

 

 

使用方法很简单,

 

 

首先,将编译出的libsbox4x4.so复制到/usr/local/Trolltech/QtEmbedded-4.6.2-arm/plugins/kbddrivers目录下(没有目录则创建)

 

然后,增加一个QWS_KEYBOARD环境变量:

 

export QWS_KEYBOARD=sbox4x4:/dev/kbd

 

 

sbx4x4是库的名字,冒号后面是输入设备。

 

将来,sbox4x4/dev/kbd将被传递到Sbox4x4Plugincreate函数中,用于创建键盘处理对象。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • quote 2.ASKA
  • Hi,感謝你的分享,冒昧請教,在主程序那邊要怎麼調用這個插件呢?
    謝謝^^
  • 2011-2-9 13:24:47 回复该留言

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Spirit Build 80722 Code detection by Codefense  theme by BokeZhuti

Copyright 2008-2009 C0EEBDA1. Some Rights Reserved. 备案号:京ICP备09020681号