您的位置:首页 > 编程语言 > Qt开发

qte流程分析,键盘的挂载和键盘消息的传递

2012-02-12 14:17 369 查看
 

1.启动流程

QApplication

{

Construct();——qt_init()——if(type==QApplication::GuiServer)

}                                   |                {

                              Initialize()      QWSServer::startup(flags)——init_display()

                                     |                                }              |                                |

          Eventloop->appSettingUp()                          |                                |

                                                                                   1.1                             1.2  

 

1.1 startup

      |

 New QWSServer(flags)

         |

 New QWSServerData

         |

 openDisplay————qt_init_display

         |                                        |

 New QWSClient        init_display

         |                                         |    

 OpenMouse                         1.2

         |

 Openkeyboard

         |

  ScreenRegion

////////////////////////////////////////////////////////////////////////////

1.2 init_display

         |

Qt_fbdpy=new QWSDisplay()——d=new Data

                                   |                               |

                QColor::initialize                    init()

      |                                                             |

QFont::initialize                      qt_get_screen()

     |

QPainter::initialize

     |

QApplication::setFont()

 

2.QT/E操作系统角度移植

2.1 键盘

2.2 鼠标

2.3 Lcd (framebuffer)

2.4 时钟

2.5 Qthread(使用linux线程库)

2.6 QSocketDevice

2.7 QFile,使用文件操作  ::open

                   ::close :: read ::write  定义于Qplatformdefs.h

2.8 内存分配 malloc

2.9 管道 pipe

2.10 mmap

2.11 信号量

 

3.QT/E键盘加载和键值传递流程

3.1 打开键盘设备,建立socket,将键盘描述符与读取函数建立信号槽

kbdFD = ::open(device.isEmpty()?"/dev/tty0":device.latin1(), O_RDWR|O_NDELAY, 0);

if ( kbdFD >= 0 )

 {

       QSocketNotifier *notifier;

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

       connect( notifier, SIGNAL(activated(int)), this, SLOT(readKeyboardData()) );

 }

 

3.2 键盘描述符登记socket

QSocketNotifier::QSocketNotifier( int socket, Type type, QObject *parent,

                              const char *name )

    : QObject( parent, name )

{

#if defined(QT_CHECK_RANGE)

    if ( socket < 0 )

       qWarning( "QSocketNotifier: Invalid socket specified" );

#  if defined(Q_OS_UNIX)

    if ( socket >= FD_SETSIZE )

       qWarning( "QSocketNotifier: Socket descriptor too large for select()" );

#  endif

#endif

    sockfd = socket;

    sntype = type;

    snenabled = TRUE;

    QApplication::eventLoop()->registerSocketNotifier( this );

}

3.3 select()检测设备描述符的变化

// 主循环中第二个是检测哪个设备描述符出现了错误

nsel = select( highest + 1,

                     &d->sn_vec[0].select_fds,

                     &d->sn_vec[1].select_fds,

                     &d->sn_vec[2].select_fds,

                     tm );

 

3.4 键盘信号槽中,从检测到描述符变化,发信号,到槽激活的过程

activateSocketNotifiers();

           |

            ——QApplication::sendEvent( sn->obj, &event );

                                                   |

                                                   ——qApp ? qApp->notify( receiver, event ) : FALSE;

                                                                              |

                                                                              ——default:

                                                                             res = internalNotify( receiver, e );     //一路没处理,跑到最后

                                                                                  break;

                                                                                        |

                                                                                          ——consumed = receiver->event( e );  //一路没处理,跑到最后

                                                                                                             |

                                                                                                             ——QSocketNotifier::event(QEvent::SockAct)

                                                                                                                                |

                                                                                                                                  ——emit activated(sockfd)  // 激发信号

 

注:在activateSocketNotifiers();中指定了receiver和event,具体详看代码如下:

     int QEventLoop::activateSocketNotifiers()

{

    if ( d->sn_pending_list.isEmpty() )

       return 0;

 

    // activate entries

    int n_act = 0;

    QEvent event( QEvent::SockAct );

    QPtrListIterator<QSockNot> it( d->sn_pending_list );

    QSockNot *sn;

    while ( (sn=it.current()) ) {

       ++it;

       d->sn_pending_list.removeRef( sn );

       if ( FD_ISSET(sn->fd, sn->queue) ) {

           FD_CLR( sn->fd, sn->queue );

           QApplication::sendEvent( sn->obj, &event );

           n_act++;

       }

    }

    return n_act;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息