qt和linux下的input设备

        在嵌入式开发中,qt的键盘往往都是特制的,如何让特制的键盘被qt用起来,需要对linux的input子系统有一定了解,并且特别要追一下qt对外界输入时间的处理方式。应用层和驱动层相互关联,在此仅先粗略分析下qt这部分:

    在qt的源码中grep下/dev/input/event之类的,就可以顺藤摸瓜了

对于qtembedded版本,第一个运行的QApp当作server,后起来的QApps当作client。在QApplication的构造函数中:

Q_D(QApplication);d->construct();

construct()中调用

      qt_init(this, qt_appType

#ifdef Q_WS_X11

       , dpy, visual, cmap

#endif

      );

qt_init函数中有QWSServer::startup(flags);

startup中有(void)new QWSServer(flags);

 QWSServer的构造函数中有

      Q_D(QWSServer);

      d->initServer(flags)

initServer中有

#ifndef QT_NO_QWS_KEYBOARD

      if(!(flags&QWSServer::DisableKeyboard)){

       q->openKeyboard();

      }

#endif

openKeyboard中创立一个handler

QWSKeyboardHandler *handler = QkbdDriverFactory::create(type, device);

 

create中,有

QWSKeyboardHandler *QKbdDriverFactory::create(const QString& key, const QString& device)

{

    QString driver = key.toLower();

#ifndef QT_NO_QWS_KBD_SL5000

    if (driver == QLatin1String("sl5000") || driver.isEmpty())

        return new QWSSL5000KeyboardHandler(device);

#endif

#ifndef QT_NO_QWS_KBD_YOPY

    if (driver == QLatin1String("yopy") || driver.isEmpty())

        return new QWSYopyKeyboardHandler(device);

#endif

#ifndef QT_NO_QWS_KBD_VR41XX

    if (driver == QLatin1String("vr41xx") || driver.isEmpty())

        return new QWSVr41xxKeyboardHandler(device);

#endif

#ifndef QT_NO_QWS_KEYBOARD

# ifndef QT_NO_QWS_KBD_TTY

    if (driver == QLatin1String("tty") || driver.isEmpty())

        return new QWSTtyKeyboardHandler(device);

# endif

# ifndef QT_NO_QWS_KBD_USB

    if (driver == QLatin1String("usb"))

        return new QWSUsbKeyboardHandler(device);

# endif

# ifndef QT_NO_QWS_KBD_UM

    if (driver == QLatin1String("um") || driver == QLatin1String("qvfbkeyboard"))

        return new QWSUmKeyboardHandler(device);

# endif

# ifndef QT_NO_QWS_KBD_QVFB

    if (driver == QLatin1String("qvfbkbd")

        || driver == QLatin1String("qvfbkeyboard")

        || driver == QLatin1String("qvfb"))

        return new QVFbKeyboardHandler(device);

# endif

#endif

 

#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)

#ifndef QT_NO_LIBRARY

    if (QWSKeyboardHandlerFactoryInterface *factory = qobject_cast(loader()->instance(driver)))

        return factory->create(driver, device);

#endif

#endif

    return 0;

}

 

根据不同的keyboard类型进行创建,这里挑usb类型的看一下

# ifndef QT_NO_QWS_KBD_USB

    if (driver == QLatin1String("usb"))

        return new QWSUsbKeyboardHandler(device);

# endif

 

QWSUsbKeyboardHandler::QWSUsbKeyboardHandler(const QString &device)

    : QWSPC101KeyboardHandler(device)

{

    d = new QWSUsbKbPrivate(this, device);

}

 

QWSUsbKbPrivate::QWSUsbKbPrivate(QWSPC101KeyboardHandler *h, const QString &device) : handler(h)

{

#ifdef QT_QWS_ZYLONITE

    shift = FALSE;

#endif   

    fd = ::open(device.isEmpty()?"/dev/input/event1":device.toLocal8Bit(),O_RDONLY, 0);

    if (fd >= 0) {

        QSocketNotifier *notifier;

        notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);

        connect(notifier, SIGNAL(activated(int)),this,

                 SLOT(readKeyboardData()));

    }

}

 

这里就用的linux设备中的input子设备,监听该fd,如果有数据了,就 readKeyboardData.

这里监听的方法是Qt自己的类 QsocketNotifier,但效果和selectpoll等是一样的。

readKeyboardData函数首先从fd中读取标准的input_event结构体。根据这个结构体的内容转换为内部的标识。最后调用    handler->processKeyEvent(unicode, key_code, (Qt::KeyboardModifiers)modifiers, event.value!=0, false);进行处理。

 

 

按照这个流程下来,我们可以很清楚的知晓如何在Qt下添加键盘。

qkbddriverfactory_qws.cpp中的create函数中新建自己的handler。仿照qkbdusb_qws.cpp建立自己的处理方式就可以了.

 

Qt里边的修改的大概过程就是如此,那么对于特定的嵌入式系统,如何将设备融入到input子系统呢。如果按照这种方式,需要对input子系统比较熟悉才能将硬件抽象为input设备。

其实,还有一个比较简单的方式,使用pipe。比如按键的面板是一个51单片机控制的,单片机和arm通过串口通信,那么可以将串口的数据转换为标准的input_event结构体,然后将其写入到pipe中。而qt中就监听类似于/dev/input/keybdpipe之类的文件就行了.

 

 

你可能感兴趣的:(qt和linux下的input设备)