Qt Lighthouse學習(二),就是QPA(Qt Platform Abstraction) 項目的名字

上一次關注Qt Lighthouse是在6月初,但是如今都8月底了。時間真快...html

Lighthouse 是 QPA(Qt Platform Abstraction) 項目的名字,它使得將Qt移植到新的平臺變得比較簡單。儘管如今它已經徹底融入到了Qt主幹代碼中,lighthouse做爲獨立項目已經不復存在了,但本文中,咱們繼續使用這個名字(雖然已不太恰當)。後端

QPA 抽象了什麼?

不妨看看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 ...
  • src/gui/kernel.pri 等工程文件內,控制哪些文件參與編譯

 

win32 {
... } symbian { ... } unix:x11 { ... }

這一切這意味這什麼??字體

若是咱們想在這個基礎上支持一個新的窗口系統,好比wayland,須要ui

  • 添加平臺相關的宏,代碼中針對該窗口再擴充 #if #elif #endifspa

  • 添加平臺相關的文件,擴充 **.pri 文件使其融入Qt
  • ...

總之,須要對Qt的代碼進行大量的修改。這一切使得將Qt移植到新的窗口系統中,變得不是那麼容易。.net

以後

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
      • ...

能夠看到代碼集中在 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)
它來決定使用哪個paintEngine
將像素Push到屏幕上

相對而言,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://www.cppblog.com/lauer3912/archive/2011/09/15/155888.html

相關文章
相關標籤/搜索