加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 电子发烧 > 单片机学习

QT/Embedded 窗体事件是如何派发的

时间:2013-09-02  来源:123485.com  作者:9stone

    QT 的窗体系统可以包含多个进程,对于Linux 上的应用,一个进程可以对应一个应用程序,每个应用程序都有自己的MainWindow,也可以有自己的Widget stack.。假设一种情况:同时打开多个应用,并且各个应用之间的Windows 不存在完全覆盖,当我们用鼠标点击某个应用的窗体,这个应用的窗体便会出现在屏幕的最上层。对于了解windows 窗体服务器的同行来说,理解这个并不难,可能有一个类似于Windows XP X-Windows Sever 的进程负责管理鼠标、键盘、与LCD 显示的操作。对于智能手机的GUI 我是第一次接触,非智能手机的窗体管理是比较简单的,以我以前从事的一个手机平台为例,手机只存在一个dialog Stack, 把这个stack 看成一个Z 坐标,栈底位于坐标原点,显示一整屏幕完整的画面就是从栈顶沿Z 坐标向下找到没有被完全覆盖的windows 直到整个屏幕数据被完全填充,按键事件传入到ui_task(ui_task 负责初始化其他应用,所有windows event 都由dialogstack 应用负责分发)。回归正卷,QT 是如何管理窗体的呢?下面详述。

QApplication 如何取得Mouse Event?
    查看QApplication 的代码,存在一个GuiSever 类型的应用,GuiServer 类型的应用与其他类型的应用有什么区别的呢?最大的区别就在于通过qt_init 初始化函数调用QWSServer::startup 这个应用建立了一个窗体服务器。在QWSServer 的构造函数中:
openDisplay(); //初始化显示、屏幕参数,打开LCD。
openMouse(); //打开鼠标设备
openKeyboard(); //打开键盘设备
    openMouse() :QWSMouseHandler* h = newMouseHandler(ms)打开鼠标设备,打开鼠标设备后,通过QSocketNotifier接口监听打开的鼠标设备文件描述符,在QWSMouseHandler构造函数中通过调用setMouseHandler 建立了window Server与鼠标设备之间的通信即:在QWSServer中 connected SIGNAL(mouseChanged)与SLOT(setMouse)(目前这个平台与新的QT开发包有出入,在qt-embedded-free-3.3.6中 鼠标与windows Server之间通讯是通过在qmouse_ws.cpp中直接调用QWSServer::sendMouseEvent 来实现的)。
    走到这,我们已经能够获取鼠标数据了。这些数据最终会传递到哪个窗体,在sendMouseEvent中通过调用window.At(pos)查找windows List所有应用的TOP-LEVEL windows保存在此链表中,(TOP-LEVEL窗体是指无parent或者style为:WType_TopLevel的窗体)中请求响应区域包含鼠标坐标的窗体(requested-region: 窗体显示的区域),一旦找到数据便会传递到此窗体(消息放入到QApplication的incoming消息队列中,由QApplication负责派发)然后通过Client Socket将此消息传递到相应的application的消息队列里。
 

Windows List是如何建立的?
    我们在创建每一个QWidget 对象时,系统会调用QWidget::create函数,如果我们创建的这个QWidget 为TOP-LEVEL 则将发送消息到QWSSever 在这里创建一个GlobalWinowsID(参看QWSServer 中get_object_id()调用),如果QWidget 为Child widget 则在这个应用中创建了一个LocaWindowslId,( 参看takeLocalId()) 不管得到的winodwsId 在哪儿被创建,在每个独立的Application 中都会通过QWidget::setWinId 保存。
    GlobalWindows 与LocalWindows 的区别是:
    在QWSServer 中创建的GlobalwindowsID 用于全局QApp 即:按键,鼠标等事件通过QWSSever 传递至相应的应用。按键,鼠标事件则在获得这些事件的QApp 的Focus Widget 中处理,这些Focus Widget可以是GlobalWindows 也可以是LocalWindows。在这个窗口没有show 之前,我们还只是得到了WindowsId,当窗口被显示时,在QWSServer 中将创建一个基于GlobalWindowsID 的QWSWindow 对象并将此对象保存在QWSServer 的windows List 中。

QApplication 中Mouse Event 的传递与处理
    当application 的消息队列不空时调用processEvents 来处理消息队列。如果应用没有模式对话框,并且没有绑定Mouse Event 的widget,则在Application 中遍历GlobalWindow(对用户而言是可以鼠标所在的那个窗体)所对应的Widget 所有子QWidget 对象,也就是说首先从他的child widget 开始查找响应Mouse Event 的Widget,如果这个窗口没有被优先级更高的窗口被遮盖,便会调用raise 函数,将窗体调整到windows list 的最上层。
 

QWSSever 与Application 之间通信管道的建立
    QT 支持多进程,对一个嵌入式设备而言,存在一个独立的GuiServer 类型的应用,这个应用作为服务器,其他的应用作为客户端。服务器与客户端的连接在应用初始化的时候完成。
服务器:
Server Application 进程通过调用QWSServer::startup完成Server 的建立。
客户端:
Application 调用QWSDisplayData::init 创建QWSSocket 对象并通过connectToLocalFile 建立与服务器的连接。
欢迎交流。


分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->单片机学习
  • 电子应用基础
  • 电源技术
  • 无线传输技术
  • 信号处理
  • PCB设计
  • EDA技术
  • 单片机学习
  • 电子工具设备
  • 技术文章
  • 精彩拆解欣赏
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门