这两天一直研究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
来源:oschina
链接:https://my.oschina.net/u/4000302/blog/3108316