• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            Qt Lighthouse學(xué)習(xí)(二)

            Posted on 2011-09-15 21:24 RTY 閱讀(913) 評論(0)  編輯 收藏 引用 所屬分類: Qt

            上一次關(guān)注Qt Lighthouse是在6月初,可是現(xiàn)在都8月底了。時間真快...

            Lighthouse 是 QPA(Qt Platform Abstraction) 項目的名字,它使得將Qt移植到新的平臺變得比較簡單。盡管現(xiàn)在它已經(jīng)完全融入到了Qt主干代碼中,lighthouse作為獨立項目已經(jīng)不復(fù)存在了,但本文中,我們繼續(xù)使用這個名字(雖然已不太恰當(dāng))。

            QPA 抽象了什么?

            不妨看看QPA前后,有何不同:

            之前

            考慮一下,傳統(tǒng)的Qt是如何實現(xiàn)圖形界面的夸平臺:

            • 針對不同的窗口系統(tǒng)(WS)定義相應(yīng)的宏: Q_WS_*

            Q_WS_X11
            Q_WS_MAC
            Q_WS_QWS
            Q_WS_WIN
            Q_WS_S60
            • 代碼中夾雜大量的編譯預(yù)處理指令 (處理小段)

            #if defined(Q_WS_X11)
            ...
            #elif defined(Q_WS_MAC)
            ...
            #elif defined(Q_WS_WIN)
            ...
            #endif
            • 各個窗口系統(tǒng)相關(guān)的代碼文件 (處理大段)

            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 等工程文件內(nèi),控制哪些文件參與編譯

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

            這一切這意味這什么??

            如果我們想在這個基礎(chǔ)上支持一個新的窗口系統(tǒng),比如wayland,需要

            • 添加平臺相關(guān)的宏,代碼中針對該窗口再擴充 #if #elif #endif

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

            總之,需要對Qt的代碼進行大量的修改。這一切使得將Qt移植到新的窗口系統(tǒng)中,變得不是那么容易。

            之后

            QPA 定義了一套接口,而后,將窗口系統(tǒng)相關(guān)的代碼放到插件中:

            • src/plugins/platforms/xlib/*
            • src/plugins/platforms/wayland/*
            • src/plugins/platforms/cocoa/*

            這時,如果我們想支持一個新的窗口系統(tǒng),怎么辦?只需要編寫一個新的插件,而Qt自身的代碼則不需要任何改變。

            (當(dāng)然,編寫插件本身還是很有難度的,哈...)

            QPA源碼結(jié)構(gòu)

            為了使插件能供工作,Qt中需要提供有相應(yīng)的加載接口,在Qt源碼中搜索*_qpa.h*_qpa.cpp *_qpa_p.h 即可找到所有(fixme)和 qpa有關(guān)的代碼:

            • 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 部分;除此外,和字體相關(guān)gui/text,和繪圖相關(guān)gui/painting、gui/image、gui/egl,和opengl相關(guān)

            QPA結(jié)構(gòu)

            QPlatformIntegration

            這個應(yīng)該算是 QPA 的核心了,

            • 它是QApplication(準確地說是QApplicationPrivate)的成員

            class Q_GUI_EXPORT QApplicationPrivate : public QCoreApplicationPrivate
            {
            ...
                static QPlatformIntegration *platform_integration;
            ...
            • 在初始化QAppliction時它會被創(chuàng)建

            QApplication::QApplication()
              QApplicationPrivate::construct()
               qt_init()
                 init_platform()
                   QPlatfromIntegrationFactory::create()
            • 它是所有窗口系統(tǒng)相關(guān)函數(shù)的入口點

            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()

            ...

            這樣一來:

            當(dāng)你在程序中

            它會向QPlatformIntegration請求

            使用QWidget時

            給我一個窗口(QPlatformWindow)及繪圖區(qū)域(QWindowSurface)

            使用QPixmap時

            給我一個位圖的后端(QPixmapData)

            使用QFont時

            給我字體數(shù)據(jù)信息(QPlatformFontDatabase)

            使用QGLWidget時

            給我一個窗口

            ...

            ...

            QPlatformWindow 與 QWindowSurface

            QPlatformWindow

            窗口
            負責(zé)窗口的幾何尺寸
            可以是另一個窗口的子窗口

            QWindowSurface

            窗口繪圖區(qū)域(drawing area of a window)
            它來決定使用哪一個paintEngine
            將像素Push到屏幕上

            相對而言,QPlatformWindow 出現(xiàn)的比較晚一點(見Say hello to QPlatformWindow一文)之所以。之所以分離開來,原因見Remodelling the Lighthouse

            QPlatformScreen

            • 代表屏幕(顯示器)
            • 它提供的api對應(yīng)用程序來說是只讀的
            • 用來計算分辨率 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

            為什么要有這個東西?

            通常我們似乎都不怎么區(qū)分QImage和QPixmap,盡管在Manual中很大的篇幅在描述這二者的區(qū)別。

            設(shè)計目的和用途(一個是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 是平臺相關(guān)的

            • Note that the pixel data in a pixmap is internal and is managed by the underlying window system.

            于是它的后端需要由各個窗口系統(tǒng)來提供也就不足為奇了。

            QPlatformFontDatabase

            提供字體信息

            詳見Fonts in Lighthouse一文。

            其他

            • QPlatformClipboard
            • QPlatformCursor
            • ...

            同前面幾個一樣,從名字上容易看出是做什么的。

            參考

            狠狠色丁香久久婷婷综合| 久久久精品国产sm调教网站| 久久亚洲AV成人无码电影| 亚洲AV日韩精品久久久久久| 人妻丰满AV无码久久不卡| 777米奇久久最新地址| 亚洲?V乱码久久精品蜜桃| 中文成人久久久久影院免费观看| 人妻精品久久久久中文字幕69| 久久综合久久综合九色| 久久人做人爽一区二区三区| 超级碰久久免费公开视频| 伊人久久综合无码成人网| 久久99精品久久久久久噜噜| 久久精品一区二区三区不卡| 久久精品免费全国观看国产| 国产午夜电影久久| 久久99精品国产| 精品一区二区久久| 国产精品久久久久影院色| 久久亚洲美女精品国产精品| 狠狠色丁香久久婷婷综合五月| 久久精品国产乱子伦| 日韩精品久久无码人妻中文字幕| 欧美日韩中文字幕久久久不卡| 污污内射久久一区二区欧美日韩| 91性高湖久久久久| 久久精品免费一区二区| 亚洲国产欧洲综合997久久| 久久精品国产亚洲AV大全| 狠狠色丁香久久综合婷婷| 国产精品久久网| 中文字幕精品无码久久久久久3D日动漫 | 国产精品一久久香蕉产线看| 91精品国产高清91久久久久久| 成人久久久观看免费毛片| 免费精品久久久久久中文字幕| 亚洲天堂久久久| 国产精品久久久福利| 一本久道久久综合狠狠爱| 日韩精品久久久久久久电影蜜臀|