转:http://zoreraul.blog.163.com/blog/static/72573928200831111241719/
转:http://zoreraul.blog.163.com/blog/static/725739282010828104621410/
只要在linux下的按键驱动程序中,把每个按键的中断处理函数中将各个按键对应的键码(这个键码是需要自己来规划的,是a~z,还是1~9都行)通过hand_scancode()函数发送过去。然后在qt的gui程序里,通过KeyEvent()事件来根据采到键码值做相应的处理即可。这样实际上是把按键驱动程序输出的键码转换成了pc标准键盘上的键码,而qt对标准键盘的支持很好。不需要做任何的修改。这样很轻松的就实现了键盘与qt的联动。
0、实验环境:
硬件:
友善之臂 mini2440
进口光电编码旋钮
软件:
linux-2.6.29
qtopia-2.2.0
硬件连接:
从CON4中引线出来。
光电编码旋钮使用K1 K2 K3三个键,我把K4 K5 K6也定义成了自己想做的键。
K1->K2 说明是往右 UP 0x67
K2->K1 说明是往左 DOWN 0x6c
K3 说明是按下 ENTER 28
K4 LEFT 0x69
K5 RIGHT 0x6a
K6 RETURN 0x1
1、按键驱动:
套用友善之臂提供的mini2440_buttons.c,进行修改,主要修改返回的键盘映射码。
static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
……
……
if(key_values[0]=='1'&&key_values[1]=='1') //A=0;B=0 position-1 { if(old_key_values[0]=='0'&&old_key_values[1]=='1')//left { old_key_values[0]=key_values[0]; old_key_values[1]=key_values[1]; for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x67; }else if(old_key_values[0]=='1'&&old_key_values[1]=='0')//right { old_key_values[0]=key_values[0]; old_key_values[1]=key_values[1]; for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x6c; }//else {for(i=0;i<6;i++) key_values1='0';} }else if(key_values[0]=='0'&&key_values[1]=='1') //A=1;B=0 position-2 { if(old_key_values[0]=='0'&&old_key_values[1]=='0')//left { old_key_values[0]=key_values[0]; old_key_values[1]=key_values[1]; for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x67; }else if(old_key_values[0]=='1'&&old_key_values[1]=='1')//right { old_key_values[0]=key_values[0]; old_key_values[1]=key_values[1]; for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x6c; }//else {for(i=0;i<6;i++) key_values1='0';} }else if(key_values[0]=='0'&&key_values[1]=='0') //A=1;B=1 position-3 { if(old_key_values[0]=='1'&&old_key_values[1]=='0')//left { old_key_values[0]=key_values[0]; old_key_values[1]=key_values[1]; for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x67; }else if(old_key_values[0]=='0'&&old_key_values[1]=='1')//right { old_key_values[0]=key_values[0]; old_key_values[1]=key_values[1]; for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x6c; }//else {for(i=0;i<6;i++) key_values1='0';} }else if(key_values[0]=='1'&&key_values[1]=='0') //A=0;B=1 position-4 { if(old_key_values[0]=='1'&&old_key_values[1]=='1')//left { old_key_values[0]=key_values[0]; old_key_values[1]=key_values[1]; for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x67; }else if(old_key_values[0]=='0'&&old_key_values[1]=='0')//right { old_key_values[0]=key_values[0]; old_key_values[1]=key_values[1]; for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x6c; }//else {for(i=0;i<6;i++) key_values1='0';} } if(key_values[2]=='1') { //mdelay(10); if(key_values[2]=='1') { for(i=0;i<6;i++) key_values1='0'; key_values1[5]=28; } else for(i=0;i<6;i++) key_values1='0'; } else if(key_values[3]=='1') { for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x69; } else if(key_values[4]=='1') { for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x6a; } else if(key_values[5]=='1') { for(i=0;i<6;i++) key_values1='0'; key_values1[5]=0x1;
……
……
}
有人就问了,为什么键盘映射是这样的,我也是一个一个的试的,结果证明这一组码是可以用的。对照 源代码 qt/src/kernel/qkeyboard_qws.cpp 进行尝试!不懂的多看看QT源代码!
建议:虽然说修改QT源代码也能实现键盘的功能,但是修改QT源代码要考虑很多的问题,反而修改驱动更简单一点。
注意:在 qt/src/kernel/qkeyboard_qws.cpp 里面的1766行到1783行 有段这样的代码:
if ( type == "Buttons" ) { #if defined(QT_QWS_YOPY) handler = new QWSyopyButtonsHandler(); #elif defined(QT_QWS_CASSIOPEIA) handler = new QWSVr41xxButtonsHandler(); #endif } else if ( type == "QVFbKeyboard" ) { handler = new QWSVFbKeyboardHandler(device); } else if ( type == "USB" ) { handler = new QWSUsbKeyboardHandler(device); } else if ( type == "TTY" ) { handler = new QWSTtyKeyboardHandler(device); } else if( type == "Samsung" ) { handler = new QWSSamsungKeypadHandler(device); } else { qWarning( "Keyboard type %s:%s unsupported", spec.latin1(), device.latin1() );
我们所要使用的是TTY类键盘,所以追寻到 QWSTtyKeyboardHandler这个类。这个是可以深究一下的!
2、ARM上环境变量设置
修改/bin/qtopia为下:
export QPEDIR=/opt/Qtopia
export PATH=$QTDIR/bin:$PATH export LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH TS_INFO_FILE=/sys/devices/virtual/input/input0/uevent if [ -e $TS_INFO_FILE -a "/bin/grep -q TouchScreen < $TS_INFO_FILE" ]; then export QWS_MOUSE_PROTO="TPanel:/dev/input/event0 USB:/dev/input/mice" if [ -e /etc/pointercal -a ! -s /etc/pointercal ] ; then rm /etc/pointercal fi else export QWS_MOUSE_PROTO="USB:/dev/input/mice" >/etc/pointercal fi unset TS_INFO_FILE export QWS_KEYBOARD=TTY:/dev/buttons export KDEDIR=/opt/kde export HOME=/root exec $QPEDIR/bin/qpe 1>/dev/null 2>/dev/null
主要是 export QWS_KEYBOARD=TTY:/dev/buttons
这样子后再按下按钮后QT界面上就有反应了。
3、qte程序中控件对旋钮动作的反应。
使用事件过滤器来对事件进行分类处理这样就可以在COMBOBOX等控件上实现,按下后即把焦点转到下一个控件上的功能。
bool MainForm::eventFilter(QObject *obj, QEvent *event) { if(obj==ComboBox_Keyboard){ if(event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); if( keyEvent->key()== 4100)//ENTER on_ComboBox_Keyboard(ComboBox_Keyboard->currentItem()); if( keyEvent->key()== 4117){//DOWN if(ComboBox_Keyboard->currentItem()==ComboBox_Keyboard->count()-1) ComboBox_Keyboard->setCurrentItem(0); else ComboBox_Keyboard->setCurrentItem(ComboBox_Keyboard->currentItem()+1);} if( keyEvent->key()== 4115){//UP if(ComboBox_Keyboard->currentItem()==0) ComboBox_Keyboard->setCurrentItem(ComboBox_Keyboard->count()-1); else ComboBox_Keyboard->setCurrentItem(ComboBox_Keyboard->currentItem()-1);} return TRUE; }else{ return FALSE; } }
…………
}
下面的这段代码可以实现动态焦点放大缩小功能。
if(obj==PushButton_Import){ if(event->type()==QEvent::FocusIn) {PushButton_Import->setFixedWidth(PushButton_Import->width()+MAGIC);} if(event->type()==QEvent::FocusOut) {PushButton_Import->setFixedWidth(PushButton_Import->width()-MAGIC);} }
文章评论(0条评论)
登录后参与讨论