网上也有相同的文章,但在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 = 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);
}
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函数中,用于创建键盘处理对象。