您的位置:首页 > 编程语言 > Qt开发

转帖一个最近用到的东西:“在QT下为开发板的键盘编写输入插件”,加上部分自己的补充说明

2011-06-20 19:26 549 查看
网上也有相同的文章,但在 QtCreator下不知道如何跟着网上的介绍来操作,所以写了此篇文章,照着做,保证有效 ^_^

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

一个基于QObject和QWSKeyboardHandler派生的
键盘处理类(Handler)

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

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

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

OK,开始实施:

1.
创建一个动态库工程,并生成一个类,假设叫做:sbox4x4Handler,这个类就是我们的Handler类。
2.
实现Handler类。
修改sbox4x4handler.h,加入下面三个头文件:

#include <QObject>

#include <QtGui/QWSKeyboardHandler>

#include <QSocketNotifier>

将Sbox4x4修改成
QObject和QWSKeyboardHandler,并加入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 = Q: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);

}

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

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

假设取名为Sbox4x4Plugin,Base Class输入QKbdDriverPlugin:

在Sbox4x4Plugin类中,重点是重载QKbdDriverPlugin基类中的create和keys:
注意,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将被传递到Sbox4x4Plugin的create函数中,用于创建键盘处理对象。

//----------------------------------------------------------------------

如下内容为自己根据实际使用时遇到的问题添加 by tumblerman

//----------------------------------------------------------------------

1.QT4.5.3内核中有一个现成的模板linuxis可以参考的,但4.7以后这个好像没4.5.3的好理解。

2.运行程序之前加 export QT_DEBUG_PLUGINS=1 可以看到插件载入过程中的错误。

3.export QWS_KEYBOARD=sbox4x4:/dev/kbd

sbox4x4(是库名libsbox4x4的后面部分,还是 _EXPORT_PLUGIN2(sbox4x4, Sbox4x4Plugin);中导出的名字?!没有深究过,参考(1)认为是前者,有兴趣的兄弟可以研究一下,但我的两个名字取的同一个,避免了这个问题)。

4.QT_PLUGIN_PATH要正确的设置。

参考资料:

(1).http://www.mculee.cn/post/93.html (转帖内容即是该文章)

(2).http://wenku.baidu.com/view/0a85cd83e53a580216fcfe9e.html

(3).http://blog.csdn.net/iskemin/archive/2009/12/21/5050448.aspx

(4).http://cuteqt.org/bbs/viewthread.php?tid=509&extra=&ordertype=1&sid=JsajfA&styleid=1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐