Qt Lighthouse学习(二),就是QPA(Qt Platform Abstraction) 项目的名字
上一次关注Qt Lighthouse是在6月初,可是现在都8月底了。时间真快...
Lighthouse 是 QPA(Qt Platform Abstraction) 项目的名字,它使得将Qt移植到新的平台变得比较简单。尽管现在它已经完全融入到了Qt主干代码中,lighthouse作为独立项目已经不复存在了,但本文中,我们继续使用这个名字(虽然已不太恰当)。
QPA 抽象了什么?
不妨看看QPA前后,有何不同:
之前
考虑一下,传统的Qt是如何实现图形界面的夸平台:
针对不同的窗口系统(WS)定义相应的宏: Q_WS_*
Q_WS_X11
Q_WS_MAC
Q_WS_QWS
Q_WS_WIN
Q_WS_S60
- 代码中夹杂大量的编译预处理指令 (处理小段)
#if defined(Q_WS_X11)
...
#elif defined(Q_WS_MAC)
...
#elif defined(Q_WS_WIN)
...
#endif
- 各个窗口系统相关的代码文件 (处理大段)
qapplication_x11.cpp
qapplication_win.cpp
qapplication_s60.cpp
qapplication_mac.mm
qapplication_qws.cpp
...
qwidget_win.cpp
qwidget_qws.cpp
qwidget_mac.cpp
qwidget_x11.cpp
...
- src/gui/kernel.pri 等工程文件内,控制哪些文件参与编译
win32 {
...
}
symbian {
...
}
unix:x11 {
...
}
这一切这意味这什么??
如果我们想在这个基础上支持一个新的窗口系统,比如wayland,需要
添加平台相关的宏,代码中针对该窗口再扩充 #if #elif #endif
- 添加平台相关的文件,扩充 **.pri 文件使其融入Qt
- ...
总之,需要对Qt的代码进行大量的修改。这一切使得将Qt移植到新的窗口系统中,变得不是那么容易。
之后
QPA 定义了一套接口,而后,将窗口系统相关的代码放到插件中:
- src/plugins/platforms/xlib/*
- src/plugins/platforms/wayland/*
- src/plugins/platforms/cocoa/*
这时,如果我们想支持一个新的窗口系统,怎么办?只需要编写一个新的插件,而Qt自身的代码则不需要任何改变。
(当然,编写插件本身还是很有难度的,哈...)
QPA源码结构
为了使插件能供工作,Qt中需要提供有相应的加载接口,在Qt源码中搜索*_qpa.h、*_qpa.cpp、 *_qpa_p.h 即可找到所有(fixme)和 qpa有关的代码:
- QTDIR/src/opengl
- qgl_qpa.cpp
- QTDIR/src/gui
- painting
- qcolormap_qpa.cpp
- qpaintdevice_qpa.cpp
- image
- qpixmap_qpa.cpp
- egl
- qegl_qpa.cpp
- kernel
- qplatformintegrationplugin_qpa.cpp
- qplatformcursor_qpa.cpp
- qwidget_qpa.cpp
- ...
- text
- qfontengine_qpa.cpp
- qfontengine_qpa_p.h
- ...
- painting
可以看到代码集中在 gui/kernel 部分;除此外,和字体相关gui/text,和绘图相关gui/painting、gui/image、gui/egl,和opengl相关
QPA结构
QPlatformIntegration
这个应该算是 QPA 的核心了,
- 它是QApplication(准确地说是QApplicationPrivate)的成员
class Q_GUI_EXPORT QApplicationPrivate : public QCoreApplicationPrivate
{
...
static QPlatformIntegration *platform_integration;
...
- 在初始化QAppliction时它会被创建
QApplication::QApplication()
QApplicationPrivate::construct()
qt_init()
init_platform()
QPlatfromIntegrationFactory::create()
- 它是所有窗口系统相关函数的入口点
class Q_GUI_EXPORT QPlatformIntegration
{
public:
|
GraphicsSystem functions |
|
|
virtual QPixmapData *createPixmapData() |
|
|
virtual QPlatformWindow *createPlatformWindow() |
|
|
virtual QWindowSurface *createWindowSurface() |
|
|
Window System functions |
|
|
virtual QList<QPlatformScreen *> screens() |
|
|
virtual void moveToScreen() |
|
|
virtual bool isVirtualDesktop() |
|
|
virtual QPixmap grabWindow() |
|
|
Deeper window system integrations |
|
|
virtual QPlatformFontDatabase *fontDatabase() |
|
|
virtual QPlatformClipboard *clipboard() |
|
|
... |
|
这样一来:
|
当你在程序中 |
它会向QPlatformIntegration请求 |
|
使用QWidget时 |
给我一个窗口(QPlatformWindow)及绘图区域(QWindowSurface) |
|
使用QPixmap时 |
给我一个位图的后端(QPixmapData) |
|
使用QFont时 |
给我字体数据信息(QPlatformFontDatabase) |
|
使用QGLWidget时 |
给我一个窗口 |
|
... |
... |
QPlatformWindow 与 QWindowSurface
|
QPlatformWindow |
窗口 |
|
QWindowSurface |
窗口绘图区域(drawing area of a window) |
相对而言,QPlatformWindow 出现的比较晚一点(见Say hello to QPlatformWindow一文)之所以。之所以分离开来,原因见Remodelling the Lighthouse。
QPlatformScreen
- 代表屏幕(显示器)
- 它提供的api对应用程序来说是只读的
- 用来计算分辨率 dpi
class Q_GUI_EXPORT QPlatformScreen : public QObject
{
...
virtual QRect geometry() const = 0;
virtual QRect availableGeometry() const {return geometry();}
virtual int depth() const = 0;
virtual QImage::Format format() const = 0;
virtual QSize physicalSize() const;
QPixmapData
为什么要有这个东西?
通常我们似乎都不怎么区分QImage和QPixmap,尽管在Manual中很大的篇幅在描述这二者的区别。
设计目的和用途(一个是IO和像素操作,一个是屏幕显示):
- QImage is designed and optimized for I/O, and for direct pixel access and manipulation
- while QPixmap is designed and optimized for showing images on screen.
典型的用途:
- Typically, the QImage class is used to load an image file, optionally manipulating the image data, before the QImage object is converted into a QPixmap to be shown on screen.
- Alternatively, if no manipulation is desired, the image file can be loaded directly into a QPixmap.
与QImage不同,QPixmap 是平台相关的
- Note that the pixel data in a pixmap is internal and is managed by the underlying window system.
于是它的后端需要由各个窗口系统来提供也就不足为奇了。
QPlatformFontDatabase
提供字体信息
详见Fonts in Lighthouse一文。
其他
- QPlatformClipboard
- QPlatformCursor
- ...
同前面几个一样,从名字上容易看出是做什么的。
参考
http://labs.qt.nokia.com/2010/04/06/remodelling-the-lighthouse/
http://labs.qt.nokia.com/2010/04/21/say-hello-to-qplatformwindow/
http://www.cppblog.com/lauer3912/archive/2011/09/15/155888.html
Qt Lighthouse学习(二),就是QPA(Qt Platform Abstraction) 项目的名字的更多相关文章
- QT入门学习笔记2:QT例程
转至:http://blog.51cto.com/9291927/2138876 Qt开发学习教程 一.Qt开发基础学习教程 本部分博客主要根据狄泰学院唐老师的<QT实验分析教程>创作,同 ...
- SpringCloud学习(二):微服务入门实战项目搭建
一.开始使用Spring Cloud实战微服务 1.SpringCloud是什么? 云计算的解决方案?不是 SpringCloud是一个在SpringBoot的基础上构建的一个快速构建分布式系统的工具 ...
- Qt介绍1---QPA(Qt Platform Abstraction)
Qt是一个夸平台的库(一直宣称“Qt everywhere”),但是Qt底层不是夸平台的.比如:Qt中Gui部件的核心类QWidget,该类除了qwidget.h 和 qwidget.cpp两个原文件 ...
- Qt Model/View学习(二)
Model和View的搭配使用 DEMO pro文件 #------------------------------------------------- # # Project created by ...
- 第15.27节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTreeWidget详解
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 树部件(Tree Widget)是Qt Designer中 Item Widgets(It ...
- Qt 插件学习(一)
插件是什么 注意:这儿暂时不考虑静态插件(潜意识中总觉得它根本就不算插件). 插件是一个动态库(共享库).动态库是一个独立的文件中的独立模块,可被多个程序访问. 先看动态库的两种用法 1. 程序链接时 ...
- PyQt(Python+Qt)学习随笔:QDial刻度盘部件功能简介
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 Designer中的Dial刻度盘输入部 ...
- PyQt(Python+Qt)学习随笔:QSlider滑动条部件功能简介
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 Designer输入部件中的Horizo ...
- PyQt(Python+Qt)学习随笔:纯文本编辑器QPlainTextEdit功能详解
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QPlainTextEdit是用于纯文本的一个高级文档编辑器 ...
随机推荐
- 使用Fiddler模拟客户端http响应【转】
转自:使用Fiddler模拟客户端http响应 在客户端开发中,常常需要对一些特殊情况做处理,比如404.503等,又比如服务返回错误数据等.而测试这些情况会比较麻烦,往往都是找开发人员配合修改代码, ...
- react-native初体验(2) — 认识路由
如果学习止步于 hello world, 那么人生也太没意思了.这次要做一个看起来真实的应用.多添加几个页面,让他们可以交互,动起来. react-native 官方推荐使用 react-naviga ...
- Netty源码分析第5章(ByteBuf)---->第8节: subPage级别的内存分配
Netty源码分析第五章: ByteBuf 第八节: subPage级别的内存分配 上一小节我们剖析了page级别的内存分配逻辑, 这一小节带大家剖析有关subPage级别的内存分配 通过之前的学习我 ...
- Netty源码分析第7章(编码器和写数据)---->第1节: writeAndFlush的事件传播
Netty源码分析第七章: 编码器和写数据 概述: 上一小章我们介绍了解码器, 这一章我们介绍编码器 其实编码器和解码器比较类似, 编码器也是一个handler, 并且属于outbounfHandle ...
- https、ssl、tls协议学习
一.知识准备 1.ssl协议:通过认证.数字签名确保完整性:使用加密确保私密性:确保客户端和服务器之间的通讯安全 2.tls协议:在SSL的基础上新增了诸多的功能,它们之间协议工作方式一样 3.htt ...
- sql语句(Mysql数据库)
Mysql数据库的sql语句: 一.基本操作 1.连接数据库 mysql -uroot -proot -hlocalhost -P3306 (-u表示用户名,-p密码,-h主机,-P端口号) 2.选择 ...
- 2017年10月WEB前端开发实习生面试题总结
从大一开始学习前端,今年大三,10月份开始投简历,陆续收到很多家公司的面试,目前为止的面试通过率是百分之百,总结下面试题. 不定期更新中... 百度第一次 一面 1.AJAX流程 2.promise简 ...
- 探路者 FInal冲刺中间产物
版本控制 https://git.coding.net/clairewyd/toReadSnake.git 版本控制报告 http://www.cnblogs.com/linym762/p/79976 ...
- 团队冲刺--six
昨天: 司宇航:合并版块,但部分有缺陷. 马佳慧:研究css. 王金萱:写注册界面. 季方: 研究爬虫,精确的处理数据. 今天: 司宇航:测试功能版块,优化功能版块. 马佳慧:优化界面 . 王金萱: ...
- 《[C#] int与System.Int32有什么区别》
最近园里的TeamOne写了一篇<[C#] int与System.Int32有什么区别>,发现里面有不少精彩的评论,所以忍不住想这篇文章总结一下:> 本文的主要参考资料: 1.< ...