qml 皮膚(三)添加自定義的控件庫和Palette(qgroundcontrol)

這兩天一直研究qml皮膚,發現qgroundcontrol這個開源項目裏的挺好用。
能夠借鑑一下QGCPalette的實現方式。c++

qgroundcontrol中全部的qml頁面都是使用自定義的GQC控件庫
具體以下:ide

在QGroundControl裏資源文件中,添加QGroundControl.Controls模塊,將自定義的控件所有放入controls目錄字體

Controls目錄的qmldir文件中設置模塊名:
Module QGroundControl.Controls
QGCButton               1.0 QGCButton.qml
QGCCheckBox             1.0 QGCCheckBox.qml
QGCColoredImage         1.0 QGCColoredImage.qml
QGCComboBox             1.0 QGCComboBox.qml
...
1
2
3
4
5
6
具體的頁面使用時,只要把QGroundControl.Controls引入就能夠直接使用QGCButton建立Button了。ui

import QGroundControl.Controls          1.0
Item{
   ...
    QGCButton{
        text:"mybutton"
    }
}
1
2
3
4
5
6
7
QGroundControl使用QGCPalette、ScreenTools,控件中設置size、color等都使用這兩個對象,這樣系統只須要維護這兩個對象就能夠調整整個系統的控件風格了。
其中
ScreenTools是singleton Module ,/qml/QGroundControl/ScreenTools 目錄下,qmldir以下
Module QGroundControl.ScreenTools
singleton ScreenTools 1.0 ScreenTools.qml
1
2
ScreenTools.qml 定義頁面使用的全部尺寸、字體信息等.net

在使用時,直接經過ScreenTools調用便可。3d


QGCPalette是c++類型,這個類實現的方式跟官方給的方式是差很少的對象

先聲明一個 _qgcPal,而後調用_qgcPal.windowShade 這個color屬性值設置控件顏色blog


QGCPalette實現主要是將一組屬性放入colorInfoMap中資源

    DEFINE_QGC_COLOR(window,                setWindow)
    DEFINE_QGC_COLOR(windowShade,           setWindowShade)
    DEFINE_QGC_COLOR(windowShadeDark,       setWindowShadeDark)
    DEFINE_QGC_COLOR(text,                  setText)
    DEFINE_QGC_COLOR(warningText,           setWarningText)
    DEFINE_QGC_COLOR(warningLowText,        setWarningLowText)
    DEFINE_QGC_COLOR(warningMidText,        setWarningMidText)
1
2
3
4
5
6
7
// theme -> colorGroup -> color name -> color文檔

static QMap<int, QMap<int, QMap<QString, QColor>>> _colorInfoMap;   // theme -> colorGroup -> color name -> color
1
設置顏色

    //                                      Light                 Dark
    //                                      Disabled   Enabled    Disabled   Enabled
    DECLARE_QGC_COLOR(window,               "#ffffff", "#dfdfdf", "#333333", "#29344a")
    DECLARE_QGC_COLOR(windowShade,          "#d9d9d9", "#c9c9c9", "#222222", "#282e3d")
    ...
1
2
3
4
5
這裏有兩個須要注意一下:聲明和定義

#define DECLARE_QGC_COLOR(name, lightDisabled, lightEnabled, darkDisabled, darkEnabled) \
    { \
        PaletteColorInfo_t colorInfo = { \
            { QColor(lightDisabled), QColor(lightEnabled) }, \
            { QColor(darkDisabled), QColor(darkEnabled) } \
        }; \
        qgcApp()->toolbox()->corePlugin()->paletteOverride(#name, colorInfo); \
        _colorInfoMap[Light][ColorGroupEnabled][QStringLiteral(#name)] = colorInfo[Light][ColorGroupEnabled]; \
        _colorInfoMap[Light][ColorGroupDisabled][QStringLiteral(#name)] = colorInfo[Light][ColorGroupDisabled]; \
        _colorInfoMap[Dark][ColorGroupEnabled][QStringLiteral(#name)] = colorInfo[Dark][ColorGroupEnabled]; \
        _colorInfoMap[Dark][ColorGroupDisabled][QStringLiteral(#name)] = colorInfo[Dark][ColorGroupDisabled]; \
    }

#define DEFINE_QGC_COLOR(name, setName) \
    Q_PROPERTY(QColor name READ name WRITE setName NOTIFY paletteChanged) \
    QColor name() const { return _colorInfoMap[_theme][_colorGroupEnabled  ? ColorGroupEnabled : ColorGroupDisabled][QStringLiteral(#name)]; } \
    void setName(QColor& color) { _colorInfoMap[_theme][_colorGroupEnabled  ? ColorGroupEnabled : ColorGroupDisabled][QStringLiteral(#name)] = color; _signalPaletteChangeToAll(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
QGCPalette.h就跟幫助文檔給的例子很像了,挑關鍵的放吧。

class QGCPalette : public QObject
{
    Q_OBJECT
    Q_ENUMS(Theme)
public:
    ...
    Q_PROPERTY(Theme    globalTheme         READ globalTheme        WRITE setGlobalTheme        NOTIFY paletteChanged)
    Q_PROPERTY(bool     colorGroupEnabled   READ colorGroupEnabled  WRITE setColorGroupEnabled  NOTIFY paletteChanged)

    DEFINE_QGC_COLOR(window,                setWindow)
    DEFINE_QGC_COLOR(windowShade,           setWindowShade)
    DEFINE_QGC_COLOR(windowShadeDark,       setWindowShadeDark)
    ....
    ....
    bool colorGroupEnabled      (void) const { return _colorGroupEnabled; }
    void setColorGroupEnabled   (bool enabled);
    
    static Theme    globalTheme     (void) { return _theme; }
    static void     setGlobalTheme  (Theme newTheme);

signals:
    void paletteChanged ();
    ...
    static Theme                _theme;             /// 主題Light 或者 Dark
    bool                        _colorGroupEnabled;  ///設置是否跟隨Palette對象風格的標識

    static QMap<int, QMap<int, QMap<QString, QColor>>> _colorInfoMap;   // 畫板集合,存儲Light和Dark主題的全部顏色屬性
    ///theme -> colorGroup -> color name -> color
    static QList<QGCPalette*> _paletteObjects;    ///< QGCPalette 對象list ,靜態成員變量注意下
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
這文件最關鍵的就是這個,它保存了全部QGroundControl中qml頁面實例化的QGCPalette對象,並且仍是static的,

static QList<QGCPalette*> _paletteObjects;    ///< QGCPalette 對象list ,靜態成員變量注意下
1
因此在主題變動、或者某個界面屬性顏色變化時,都會遍歷一下這個static list裏對象,發出paletteChanged()信號

void QGCPalette::setGlobalTheme(Theme newTheme)
{
    // Mobile build does not have themes
    if (_theme != newTheme) {
        _theme = newTheme;
        _signalPaletteChangeToAll();
    }
}

void QGCPalette::_signalPaletteChangeToAll()
{
    // Notify all objects of the new theme
    foreach (QGCPalette* palette, _paletteObjects) {
        palette->_signalPaletteChanged();
    }
}

void QGCPalette::_signalPaletteChanged()
{
    emit paletteChanged();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
而每個color屬性,都有這個聲明,因此qml頁面中的QGCPalette對象的color屬性就接收到paletteChanged更改顏色了。

Q_PROPERTY(QColor name READ name WRITE setName NOTIFY paletteChanged) 1 這樣QGroundControl就經過QGCPalette、ScreenTools實現了整個系統界面風格的設置,能夠切換Light、Dark主題,又有自定義控件,又能夠設置window、text具體顏色,font、fontsize等。 ———————————————— 版權聲明:本文爲CSDN博主「momo0303kaka」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。 原文連接:https://blog.csdn.net/lyang0303/article/details/82912572

相關文章
相關標籤/搜索