转:移植qt/e3.3.5到mini2440(加入键盘接口)

 
 
 文章原地址:
自己还是个菜鸟,发现网上讲qt/e键盘接口的不多,到网上找到好多资料,终于发现二篇,网址是:
   http://chgw.blog.hexun.com/11648808_d.html
   http://blog.mcuol.com/User/lyusheng/Article/4686_1.htm
   于是参照着做了个,主要是给像我一样刚入门同志们一个参考,免得大家走弯路,我的开发环境是 HOST:RedHat9.0, arm-linux-gcc3.4.1, TARGET:mini2440,内核2.6.24,注意RedHat最好完全安装,否则容易出一些问题。
   下面开始讲步聚:
一:修改qte源代码:
    源代码下载地址:
     ftp://ftp.trolltech.com/qt/source/
    用到的源码有: qt-embdedded-free-3.3.5 -free. tar.gz, qt-x11-free-3.3.5.tar.gz
    Qt/E主要的输入设备是鼠标和键盘,鼠标一般用触摸屏代替,我这这里只讲按键接口移植,先解压代码:
    tar zxvf  
qt-embdedded-free-3.3.5 .tar.gz
     mv   qt-embdedded-free-3.3.5 qt-arm (改名,只为方便)
    tar zxvf   qt-embdedded-free-3.3.5 .tar.gz
    mv   qt-embdedded-free-3.3.5 qt-x86  (改名,只为方便)
    这里解压了两份代码,后面会有介绍,不过从我取的名字上应该可以看出,一份代码是编译给arm用的,另一份代码是编译给PC机用的。我们只修改给arm用的代码, 即qt-arm 目录下的代码 
    mini2440提供了6个按键,可以用这6个按键实现上下左右确定等功能,要qt识别我们的按键,得自己写相应的按键接口,下面就开始吧。需要改动的地方有4个,在 qt-arm /src/embedded 目录下
1.增加一个mykbd_qws.h,内容如下:
#ifndef MYKBD_QWS_H
#define MYKBD_QWS_H
 
#include "qkbd_qws.h"  //QT定义抽象基类QWSKeyboardHandler

 
#ifndef QT_NO_MYKBD   //编译时可以通过定义这个变量从而不编译这个模块
 
class MyKbdPrivate;   //我们的键盘设备私有类,实现具体的键盘设备操作,如打开键盘、读键盘数据,解析按键等等。

 
class MyKbdHandler : public QWSKeyboardHandler //供系统调用的键盘句柄
{
public:
    MyKbdHandler(const QString&);
    virtual ~MyKbdHandler();
private:
    MyKbdPrivate *d;
};
 
#endif // QT_NO_MYKBD 
#endif // MYKBD_QWS_H

2.增加一个mykbd_qws.cpp,内容如下:
#include "mykbd_qws.h"
#ifndef QT_NO_MYKBD
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <qsocketnotifier.h>

class MyKbdPrivate : public QObject
{
    Q_OBJECT
public:
    MyKbdPrivate( MyKbdHandler *h, const QString& );
    virtual ~MyKbdPrivate();
 
    bool isOpen() { return buttonFD > 0; }
 
private slots:
    void readKeyboardData();

private:
    QString terminalName;
    int buttonFD;
    int kbdIdx;
   // int kbdBufferLen;
    unsigned char kbdBuffer;
    QSocketNotifier *notifier;
    MyKbdHandler *handler;
};
 
MyKbdPrivate::MyKbdPrivate(MyKbdHandler *h, const QString &device ) : handler(h)
{
    terminalName = device.isEmpty()?"/dev/mykeyboard":device.latin1();
    buttonFD = -1;
    notifier = 0;
    if ((buttonFD = open(terminalName, O_RDWR | O_NDELAY, 0)) < 0)
    {
        qWarning("Cannot open %s/n", terminalName.latin1());
    }
    if ( buttonFD >= 0 ) {
        notifier = new QSocketNotifier( buttonFD, QSocketNotifier::Read, this );
        connect( notifier, SIGNAL(activated(int)),this,
           SLOT(readKeyboardData()) );
    }
    //kbdBufferLen = 80;
    //kbdBuffer = new unsigned char [kbdBufferLen];
    kbdIdx = 0;
}
 
MyKbdPrivate::~ MyKbdPrivate()
{
    if ( buttonFD > 0 ) {
        ::close( buttonFD );
        buttonFD = -1;
    }
    delete notifier;
    notifier = 0;
    //delete [] kbdBuffer;

void MyKbdPrivate::readKeyboardData()
{
int n = 0;
int idx = 0;
    n  = read(buttonFD, &kbdBuffer, sizeof(kbdBuffer));
    if(n!=1)
    return;
    int keycode = Qt::Key_unknown;
 
    switch ( (kbdBuffer) & 0xff ) {
        case 1:
        keycode = Qt::Key_Left;
        break;

        case 2:
        keycode = Qt::Key_Right;
        break;

        case 3:
        keycode = Qt::Key_Tab;
        break;

        case 4:
        keycode = Qt::Key_Backtab;
        break;

        case 5:
        keycode = Qt::Key_Enter;
        break;

    case 6:
        keycode = Qt::Key_Return;

        break;
 
        default:
qDebug("Unrecognised key code %d", kbdBuffer );
    }
 
        handler->processKeyEvent( 0, keycode, 0, TRUE, FALSE );
          
}
 
MyKbdHandler::MyKbdHandler(const QString &device)
{
    d = new MyKbdPrivate( this, device );
}
 
MyKbdHandler::~MyKbdHandler()
{
    delete d;
}
 
#include "mykbd_qws.moc"
 
#endif // QT_NO_MYKBD


    kbdBuffer的大小和switch()语句大家可以根据自己的驱动程序作调整
注意:
n=read(buttonFD, &kbdBuffer, sizeof(kbdBuffer));这里我的 kbdBuffer是一个char型,这里的read每次读回一个char型,所以我的驱动程序里read函数也要每次返回一个char字符,6个按键返回的值分别是1,2,3,4,5,6,对应的键为: Qt::Key_Left, Qt::Key_Right, Qt::Key_Tab, Qt::Key_Backtab, Qt::Key_Enter, Qt::Key_Return。


3.
修改qkbddriverfactory_qws.cpp中的QWSKeyboardHandler *QKbdDriverFactory::create(),添加自己的定义的接口
其中qkbddriverfactory_qws.cpp如下:注有//mykeyboard 表示是我添加的语句

QWSKeyboardHandler *QKbdDriverFactory::create( const QString& key, const QString& device )
{
    QString driver = key.lower();

#ifndef QT_NO_MYKBD   
//mykeyboard           
      if ( driver == "mykbd" || driver.isEmpty() )
            return new MyKbdHandler( device );
#endif


#ifdef Q_OS_QNX6
    if ( driver == "qnx" || driver.isEmpty() )
    return new QWSQnxKeyboardHandler( device );
#endif
      ...

    return 0;
}


QStringList QKbdDriverFactory::keys()
{
    QStringList list;

#ifdef Q_OS_QNX6
    if ( !list.contains( "Qnx" ) )
    list << "Qnx";
#endif
#ifndef QT_NO_MYKBD    
//mykeyboard
    if ( !list.contains( "MYKBD" ) )
    list << "MYKBD";
#endif
#ifndef QT_NO_QWS_KBD_SL5000
    if ( !list.contains( "SL5000" ) )
    list << "SL5000";
#endif
     ...

#endif

..........................................

4.最后就是修改qt_embedded.pri使得QT/Embedded在编译时会加上你自己定义的接口实现
#
# Keyboard drivers
#

    ...

    contains( kbd-drivers, vr41xx ) {
        HEADERS +=$$EMBEDDED_H/qkbdvr41xx_qws.h
        SOURCES +=$$EMBEDDED_CPP/qkbdvr41xx_qws.cpp
    }
    else:DEFINES += QT_NO_QWS_KBD_VR41

    contains( kbd-drivers, mykbd ) {
        HEADERS +=$$EMBEDDED_H/mykbd_qws.h
        SOURCES +=$$EMBEDDED_CPP/mykbd_qws.cpp
    }
    else:DEFINES += QT_NO_QWS_KBD_MYKBD


二.移植 Qt/E3.3.5
   第1步是安装qt/e for X86,主要用来模拟开发板上qte程序的执行,这一步可要可不要。
   第2步是安装qt-x11 for x86 这一步主要是得到moc和qvfb工具,这一步是必须的。
   第3步主要是为了得到开发板了qte程序运行的序文件,也就是 libqte-mt.so,libqte-mt.so.3,libqte-mt.so.3.3,libqte-mt.so.3.3.5这四个文件,是必须的。

1. 安装qt-embdedded-free-3.3.5 for x86


cd qt-x86

export QTDIR=$PWD

./configure qvfb-thread

make


2.  安装qt-x11--free-3.3.5:(为了获得uic工具)

   cd ../

tar zxvf qt-x11-free-3.3.5.tar.gz

mv qt-x11-free-3.3.5 qt-x11 (改名字,为了方便,不改无所谓)

cd qt-x11

export QTDIR=$PWD

./configure -thread

make

make –C tools/qvfb

cp tools/qvfb/qvfb bin/

cp tools/qvfb/qvfb ../qt-x86/bin

3.   安装qt-embdedded-free-3.3.5 for arm


cd  ../qt-arm

cp /usr/local/arm/3.4.1/bin/arm-linux-g++ /bin (这一步好像不要也行,还是加上吧)

cp ../qt-x11/bin/moc bin/

export QTDIR=$PWD

export QTEDIR=$QTDIR
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QWS_KEYBOARD=MKBD:/dev/mykeyboard

./configure -embedded arm -qt-gfx-qvfb -qt-kbd-mykbd -depths 4,8,16,32 -thread -no-cups

gmake  这里提示用gmake,我试过,用make也是可以的


编译成功后就可以在lib目录下发现我们要的四个库文件啦。



三.接下来的工作到开发板上了

    我的驱动程序见附件,主要注意的地方是返回值要是char型,当然也可以是其他类型,你qt/e源码里的read()函数作相应的修改就行了,第二是要实现poll()函数,这里qt/e的工作原理有关,具体请参考倪继利的<<Qt及Linux操作系统窗口设计>>。

    这里假设你的驱动程序已经移植好了,名字为mini2440_key.ko,那就赶快进加裁它吧。

    insmod  mini2440_key.ko

    mknod /dev/mykeyboard c XX XX

    注意这里名字必须为mykeyboard,原因相信你看了qt/e源码修改的部分就知道了,当然你也可以另取名字,不过qt/e源码部分也要作出相应的修改。



四.arm 上qte程序的运行:

先给出一个测试程序吧:

#include "form.h"
#include <qapplication.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qnamespace.h>
#include <qlayout.h>
MainForm::MainForm(QWidget *parent, const char *name): QWidget(parent, name)
{
        setFocusPolicy(QWidget::StrongFocus);//设置可以获得键盘输入
        label = new QLabel("wait for key", this);
        button1 = new QPushButton("ok", this);
        button2 = new QPushButton("exit", this);
        button3 = new QPushButton("hello", this);
        button4 = new QPushButton("goobye", this);
        QGridLayout *mainLayout = new QGridLayout(this);
        button1->setFocus();
        button2->installEventFilter(this);
        mainLayout->addMultiCellWidget(label, 0, 0, 0, 1);
        mainLayout->addWidget(button1, 1, 0);
        mainLayout->addWidget(button2, 1, 1);
        mainLayout->addWidget(button3, 2, 0);
        mainLayout->addWidget(button4, 2, 1);
        //connect(button2, SIGNAL(clicked()), qApp, SLOT(quit()));
    

}

bool MainForm :: eventFilter(QObject *target, QEvent *event)
    {
        if (target == button2)
        {
            if(event->type() == QEvent::KeyPress)
                {
                    QKeyEvent *keyEvent =(QKeyEvent *)event;
                    if(keyEvent->key() == Qt::Key_Enter)
                        {
                            qApp->quit();
                            return true;
                        }
                    
                }
        }
        return QWidget::eventFilter(target, event);
        
    }
void MainForm :: keyPressEvent(QKeyEvent *k)
{

    int keycode = k->key();
    qDebug("keyPressEvent keycode = 0x%x/n, the key is :",keycode);
    switch(keycode)
    {
        case Qt::Key_Tab:
        qDebug("TAB/n");
        label->setText("tab is pressed");
        break;
        
        case Qt::Key_BackTab:
        qDebug("BackTAB/n");
        label->setText("backtab is pressed");
        break;
        
        case Qt::Key_Enter:
        qDebug("Enter/n");
        label->setText("Enter is pressed");
        break;
        
      case Qt::Key_Return:
        qDebug("Return/n");
        label->setText("return is pressed");
        
        break;
        
        case Qt::Key_Right:
        qDebug("Right/n");
        label->setText("right is pressed");
        break;
        
        case Qt::Key_Left:
        qDebug("LEFT/n");
        label->setText("left is pressed");
        break;
        
        case Qt::Key_Up:
        qDebug("UP/n");
        label->setText("up is pressed");
        break;

        case Key_Down:
        qDebug("Down/n");
        label->setText("down is pressed");
        break;
        default:
        qDebug("Unkonw Key/n");
    }
    
    QWidget::keyPressEvent(k);
}
    功能是当你当下一个键时,label会显示他按的是什么键,在exit上按确定键后,程序退出
    后面我发现 case Qt::Key_Tab:和 case Qt::Key_BackTab:没有响应,看了C++ GUI Qt3 之后知道原因是这两个按键事件在evnt()事件中被处理了。

    具体程序的执行请参考其他两篇文章,按键驱动和测试程序见附件。
注意的是,如果提示缺少库文件,一一从/usr/local/arm/3.4.1/arm-linux/lib 复制到开发板上的lib中就行了
    还有环境变量通过直接输入:

export QTDIR=$PWD

export QTEDIR=$QTDIR
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QWS_KEYBOARD=MKBD:/dev/mykeyboard

如果保存为脚本文件,如setenv

则需要执行. ./setenv 来执行注意第一个“.”后有个空格

或者 source ./setenv,否则环境变量设置不正确。


要想去掉LCD屏上光票,可以修改源代码

src/kernel 目录下的 qwindowsystem_qws.cpp中的openMouse()函数

void QWSServer::openMouse()
{

     ...

#ifndef QT_NO_QWS_CURSOR
    //setCursorVisible( needviscurs );

     setCursorVisible( FALSE );    //changed by zhang to hide the cursor
#endif
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值