上一次關注Qt Lighthouse是在6月初,但是如今都8月底了。時間真快...html
Lighthouse 是 QPA(Qt Platform Abstraction) 項目的名字,它使得將Qt移植到新的平臺變得比較簡單。儘管如今它已經徹底融入到了Qt主幹代碼中,lighthouse做爲獨立項目已經不復存在了,但本文中,咱們繼續使用這個名字(雖然已不太恰當)。後端
不妨看看QPA先後,有何不一樣:api
考慮一下,傳統的Qt是如何實現圖形界面的誇平臺:app
針對不一樣的窗口系統(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 ...
win32 {
... } symbian { ... } unix:x11 { ... }
這一切這意味這什麼??字體
若是咱們想在這個基礎上支持一個新的窗口系統,好比wayland,須要ui
添加平臺相關的宏,代碼中針對該窗口再擴充 #if #elif #endifspa
總之,須要對Qt的代碼進行大量的修改。這一切使得將Qt移植到新的窗口系統中,變得不是那麼容易。.net
QPA 定義了一套接口,然後,將窗口系統相關的代碼放到插件中:插件
這時,若是咱們想支持一個新的窗口系統,怎麼辦?只須要編寫一個新的插件,而Qt自身的代碼則不須要任何改變。
(固然,編寫插件自己仍是頗有難度的,哈...)
爲了使插件能供工做,Qt中須要提供有相應的加載接口,在Qt源碼中搜索*_qpa.h、*_qpa.cpp、 *_qpa_p.h 便可找到全部(fixme)和 qpa有關的代碼:
能夠看到代碼集中在 gui/kernel 部分;除此外,和字體相關gui/text,和繪圖相關gui/painting、gui/image、gui/egl,和opengl相關
這個應該算是 QPA 的核心了,
class Q_GUI_EXPORT QApplicationPrivate : public QCoreApplicationPrivate
{ ... static QPlatformIntegration *platform_integration; ...
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 |
窗口繪圖區域(drawing area of a window) |
相對而言,QPlatformWindow 出現的比較晚一點(見Say hello to QPlatformWindow一文)之因此。之因此分離開來,緣由見Remodelling the Lighthouse。
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;
爲何要有這個東西?
一般咱們彷佛都不怎麼區分QImage和QPixmap,儘管在Manual中很大的篇幅在描述這兩者的區別。
設計目的和用途(一個是IO和像素操做,一個是屏幕顯示):
典型的用途:
與QImage不一樣,QPixmap 是平臺相關的
因而它的後端須要由各個窗口系統來提供也就不足爲奇了。
提供字體信息
詳見Fonts in Lighthouse一文。
同前面幾個同樣,從名字上容易看出是作什麼的。
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