這兩天一直研究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