Qt Embedded中如何实现自己的keyboard

最近的项目是基于Qt,既然是嵌入式设备,难免就要在根据自己的平台来实现键盘的驱动部分,当然是属于Qt一层,而不是更底层的字符设备驱动。

这里要讲的方法是在不重新编译Qt库的情况,把我们自己的键盘驱动作为一个Qt插件集成到我们的程序中。当然也可以把我们自己的键盘驱动部分直接编译到Qt库里面。

Qt中提供的插件机制(Plugin),可以使得我们很容易根据自己的硬件实现自己的键盘代码。


具体步骤:

1. 首先创建一个静态插件库(当然也可以是动态库),我们这边库名叫做optkeypad。
a. 创建一个键盘处理类 KeypadHandler, 多继承于QObject 和 QWSKeyboardHandler, 实现一个关键的函数readKpdData(),这个函数很关键,就是用来把我们的硬件值(hardcode)转换为Qt库中定义的键值。
b. 创建一个插件类 KeypadDriverPlugin, 继承于QKbdDriverPlugin, 这个类主要是创建一个我们自己的键盘处理类KeypadHandler,重新实现QKbdDriverPlugin的create()和keys()函数,这是两个虚函数,我们要在自己的类中重新实现这两个函数。
c. 我们做成一个静态插件类,所以.pro文件如下。
2. 那么如何使用这个插件类呢,
a. 在我们的应用程序中(一般在main.cpp中)添加宏 Q_IMPORT_PLUGIN(optkeypad)。optkeypad是库名,注意不包含linux中的前缀lib和扩展名.a。
b. 在应用程序的.pro文件中添加 QTPLUGIN += optkeypad, 并且要在链接中添加这个库 LIBS += -L(路径) -loptkeypad
c. 接下来要为程序添加环境变量 QWS_KEYBOARD, export QWS_KEYBOARD=OptimusKpdHandler:/dev/input/event1 (这个很重要)
注意这个OptimusKpdHandler是怎么来的, 我们的插件类KeypadDriverPlugin要根据这个名字来建立一个键盘处理类KeypadHandler,所以如果这个名字不匹配的话,处理类是不会被创建的。
3. 接下来我们的Qt应用程序中的键值,就是KeypadHandler类的readKpdData()处理后的值。

.pro文件


TEMPLATE = lib
CONFIG += static \
plugin \
release
TARGET = optkeypad
HEADERS += keypadhandler.h \
keypaddriverplugin.h
SOURCES += keypadhandler.cpp \
keypaddriverplugin.cpp

QMAKE_INCDIR += ../ClockCommon
QMAKE_LIBS += -lClockCommon


keypadDriverPlugin.h文件


class KeypadDriverPlugin : public QKbdDriverPlugin
{
Q_OBJECT
public:
KeypadDriverPlugin(QObject *parent = 0);
~KeypadDriverPlugin();

QWSKeyboardHandler *create(const QString &driver, const QString &device);
QWSKeyboardHandler *create(const QString &driver);
QStringList keys() const;
};


类的实现文件


KeypadDriverPlugin::KeypadDriverPlugin(QObject *parent)
{

}

KeypadDriverPlugin::~KeypadDriverPlugin()
{
}

QStringList KeypadDriverPlugin::keys() const
{
return QStringList() << "OptimusKpdHandler";
}

//
// The create() functions are responsible for returning an instance of
// the keypad driver. We do this only if the driver parameter matches our key.
//
QWSKeyboardHandler *KeypadDriverPlugin::create(const QString &driver, const QString &device)
{
PR("KeypadDriverPlugin::create###################################: %s\n", driver.toLocal8Bit().constData());
if (driver.toLower() == "optimuskpdhandler")
{
PR("Before creating KeypadHandler\n");
return new KeypadHandler(device);
}

return 0;
}

QWSKeyboardHandler *KeypadDriverPlugin::create(const QString &driver)
{
if (driver.toLower() == "optimuskpdhandler")
{
PR("Before creating KeypadHandler");
return new KeypadHandler();
}

return 0;
}


keypadHandler.h文件


class KeypadHandler : public QObject, public QWSKeyboardHandler
{
Q_OBJECT

public:
KeypadHandler(const QString &device = QString("/dev/input/event0"));
~KeypadHandler();

private:
QSocketNotifier *m_notifier;
int kbdFd;

private slots:
void readKpdData();
};


类的实现文件
struct InputData
{
unsigned int dummy1;
unsigned int dummy2;
unsigned short type;
unsigned short code;
unsigned int value;
unsigned int dummy3;
unsigned int dummy4;
unsigned int dummy5;
unsigned int dummy6;
};

KeypadHandler::KeypadHandler(const QString &device)
{
setObjectName("Optimus Keypad Handler");
this->kbdFd = ::open(device.toLocal8Bit().constData(), O_RDONLY, 0);

if (kbdFd > 0)
{
PR("%s opened as keyboard input.\n", device.toLocal8Bit().constData());
g_Log.Debugf(LOG_DETAIL_TRACE, 0, L"%s opened as keyboard input.", device.toLocal8Bit().constData());
this->m_notifier = new QSocketNotifier(kbdFd, QSocketNotifier::Read, this);
connect(this->m_notifier, SIGNAL(activated(int)), this, SLOT(readKpdData()));
}
else
{
PR("Cannot open %s for keyboard input. (%s)",
device.toLocal8Bit().constData(), strerror(errno));
g_Log.Errorf(LOG_DETAIL_IMPORTANT, 0, L"Cannot open %s for keyboard input. (%s)",
device.toLocal8Bit().constData(), strerror(errno));
return;
}
}

KeypadHandler::~KeypadHandler()
{
if (kbdFd > 0)
::close(kbdFd);
}


// Key function
void KeypadHandler::readKpdData()
{
InputData event;

int n = read(kbdFd, &event, sizeof(InputData));
if (n != sizeof(InputData))
{
PR("key pressed: n=%d\n", n);
g_Log.Debugf(LOG_DETAIL_TRACE, 0, L"key pressed: n=%d", n);
return;
}

PR("key pressed: type=%d, code=0x%x, value=%d, %s\n",
event.type, event.code, event.value, (event.value != 0)? "(Down)" : "(Up)");
g_Log.Debugf(LOG_DETAIL_TRACE, 0, L"key pressed: type=%d, code=%d, value=%d, %s",
event.type, event.code, event.value, (event.value != 0)? "(Down)" : "(Up)");

Qt::KeyboardModifiers modifiers = Qt::NoModifier;
int unicode = 0xffff;
int key_code = 0;

// 可以根据自己特定的硬件值来设定。
switch (event.code)
{
case 0x2:
key_code = Qt::Key_1;
unicode = '1';
break;
case 0x110:
key_code = Qt::Key_Context1;
unicode = 0xffff;
break;
case 0x100:
key_code = Qt::Key_Back;
unicode = 0xffff;
break;
default:

break;
}

this->processKeyEvent(unicode, key_code, modifiers, event.value != 0, false);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值