常用的UI系统一般包括以下三个功能:
1) 显示
2) 鼠标、键盘事件处理
3) 窗口管理器
我现在逐个详细叙述:
1) 显示系统
显示系统最顶层的就是各种控件和widget,其中有一部分是可以drawable的,也就是可以显示出来的。而有些抽象的,不能显示出来。
可供显示的地方,除了手机屏幕之外,还可以保存为文件或者QPixmap对象等,在台式机上还可以打印,在QT中我们一般称这类对象为PaintDevice。
这类对象一般都有一个内存区域存储点阵像素信息。
有另外一类对象叫QPainter专门用来在QPaintDevice上做渲染工作
这里paint有三种情况
a) 2D图形:比如画直线,曲线,圆,椭圆,包括用图片填充区域等。
b) 3D图形:
c) 多媒体视频和图像:
这三类情况都需要经历自身的图形或者图像算法,包括视频解压算法等,然后通过一种叫“光栅化”的过程刷新到QPaintDevice 的像素缓冲区上,整个过程,称之为“渲染”
整个渲染工作就是由Painter来完成的,就相当于每一个控件都拥有一个小画师,在控件独有的一块画布上画画,然后再通过窗口管理器合并到手机屏幕上显示出来。
由于CPU的速度特别快,所以屏幕上的图像很快就能画出来,就算每秒钟几十帧,都不成问题。
我们工作中常用的是2D渲染,它有包括图片和文字。文字部分叫QtText.
其实还提供了其他图形库和文字库,叫CAIRO和Pango
在android的图形库叫skia 或者,在GOOGLE的CHROME浏览器里也是用这个库做2D渲染。
其实UI系统显示部分的工作,就是一个Layout + Rendering + Object System,包括浏览器的显示部分的原理也是这样。
当然现在的手机操作系统也支持3D渲染,在手机上用的是OPENGL的子集,OPENGL ES.这样可以提供更好的用户体验,现在手机上大部分比较炫目的效果就是用OPENGL做的。
当然要提供很好的用户体验,肯定会用到硬件加速,所以现在的智能手机,一般都带独立显卡,主流的是PowerVR公司的sgx系列。
2) 鼠标、键盘处理
每一个应用程序,如果是基于GUI的,在应用程序的进程创建的时候,都会为主GUI线程创建一个消息队列,窗口管理器,捕获到底层鼠标键盘驱动发来 的事件后,会根据相关窗口的坐标,得出该事件属于哪个活动窗口,从而判断出属于那一个应用程序,从而发送一个事件给相应的应用程序。
应用程序在自己的主GUI线程里面,会根据对象树,逐级的把事件传送到相关的控件,以处理这个事件。
事件可以是来自于鼠标键盘,UI框架自身也会产生一些时间,比如需要重画某个控件的时候,就会发送一个重画事件给相关控件。
如果当我们在主GUI线程里面做一些比较耗时的操作的时候,程序的界面就会出现卡住不动的情况,所以一般处理耗时任务或者带阻塞的任务的时候,我们都会使用工作者线程。
而由于QT的那些控件代码不是基于线程安全的,所以QT规定只能在主GUI线程里面调用QT自身的UI代码。