qml 皮肤(三)添加自定义的控件库和Palette(qgroundcontrol)

非 Y 不嫁゛ 提交于 2019-11-29 18:18:30

这两天一直研究qml皮肤,发现qgroundcontrol这个开源项目里的挺好用。
可以借鉴一下QGCPalette的实现方式。

qgroundcontrol中所有的qml页面都是使用自定义的GQC控件库
具体如下:

在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了。

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 定义页面使用的所有尺寸、字体信息等

在使用时,直接通过ScreenTools调用即可。


QGCPalette是c++类型,这个类实现的方式跟官方给的方式是差不多的

先声明一个 _qgcPal,然后调用_qgcPal.windowShade 这个color属性值设置控件颜色


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!