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

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

qgroundcontrol中所有的qml页面都是使用自定义的GQC控件库

具体如下:

  1. 在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
...

具体的页面使用时,只要把QGroundControl.Controls引入就可以直接使用QGCButton创建Button了。

import QGroundControl.Controls          1.0
Item{
   ...
	QGCButton{
		text:"mybutton"
	}
}
  1. QGroundControl使用QGCPalette、ScreenTools,控件中设置size、color等都使用这两个对象,这样系统只需要维护这两个对象就可以调整整个系统的控件风格了。
    其中
    ScreenTools是singleton Module ,/qml/QGroundControl/ScreenTools 目录下,qmldir如下
Module QGroundControl.ScreenTools
singleton ScreenTools 1.0 ScreenTools.qml

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)

// theme -> colorGroup -> color name -> color

static QMap<int, QMap<int, QMap<QString, QColor>>> _colorInfoMap;   // theme -> colorGroup -> color name -> color

设置颜色

    //                                      Light                 Dark
    //                                      Disabled   Enabled    Disabled   Enabled
    DECLARE_QGC_COLOR(window,               "#ffffff", "#dfdfdf", "#333333", "#29344a")
    DECLARE_QGC_COLOR(windowShade,          "#d9d9d9", "#c9c9c9", "#222222", "#282e3d")
    ...

这里有两个需要注意一下:声明和定义

#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(); }

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 ,静态成员变量注意下
};

这文件最关键的就是这个,它保存了所有QGroundControl中qml页面实例化的QGCPalette对象,而且还是static的,

static QList<QGCPalette*> _paletteObjects;    ///< QGCPalette 对象list ,静态成员变量注意下

所以在主题变更、或者某个界面属性颜色变化时,都会遍历一下这个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();
}

而每一个color属性,都有这个声明,所以qml页面中的QGCPalette对象的color属性就接收到paletteChanged更改颜色了。

Q_PROPERTY(QColor name READ name WRITE setName NOTIFY paletteChanged)

这样QGroundControl就通过QGCPalette、ScreenTools实现了整个系统界面风格的设置,可以切换Light、Dark主题,又有自定义控件,又可以设置window、text具体颜色,font、fontsize等。

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值