這次講Qt Style Sheet(QSS),QSS是一種與CSS類似的語言,實際上這兩者幾乎完全一樣。既然談到CSS我們就有必要說一下盒模型。
1. 盒模型(The Box Model)
在樣式中,每一個UI控件都可以抽象成一個盒模型:
盒模型由4個同心矩形組成,從外到內分別是外邊距、邊界、內襯和內容,大部分UI視覺內容都包含在內容矩形中。默認情況下,前三個矩形的大小屬性都是0,因此這四個矩形都重疊成一個了。這里與前三個大小相關的屬性有:
- margin:代指外邊距矩形與邊界矩形之間的間距。
- border-width:代指外邊距矩形與內襯矩形之間的間距。
- padding:代指內襯矩形與內容矩形之間的間距。
2. QSS(Qt Style Sheet)
QSS與CSS相似,因此這里只大概介紹QSS的特點:
- 子控件:Qt允許我們控制復雜控件的子控件,例如QComboBox的下拉按鈕、QCheckBox的勾選框等等。
- 偽狀態:Qt包含一些特殊的狀態:last、first等。
- 支持自定義類的樣式設置:得力於Qt的元對象系統,QSS可以對用戶自己定義的類進行樣式設置。
- 命名空間特殊語法:由於C++中的命名控件寫法(
::
)與Q 的子控件寫法沖突,因此改用--
來表示命名空間。 - Qt屬性支持:任何通過Q_PROPERTY定義的屬性和Q_ENUM枚舉類都可以被樣式化。
3. 自定義樣式實例
這里我們通過一個示例程序來接觸QSS,因為實例程序涉及多個控件但我們篇幅有限,我們只介紹菜單相關的樣式設置。菜單分為兩部分:菜單欄(QMenuBar)、菜單(QMenu)。
3.1 菜單欄樣式
我們把菜單欄寬度設置成大於等於菜單item的寬度60px(這里的width不指代整個菜單欄的寬度,比較奇怪),防止item的寬度被菜單欄的寬度限制,並且設置灰色點邊框。
QMenuBar {
width:60px;
background-color:white;
border:1px dotted gray;
}
item這里代指菜單欄上的每一項菜單,我們設置邊框位groove以使其看起來有凹凸效果;設置margin-right,這樣兩個item之間會有合適的間隔;我們還在不同的狀態下設置不同的背景顏色,這樣交互上比較友好。
QMenuBar::item {
height:15px;
width:60px;
background:transparent;
border:2px groove gray;
margin-right:1px;
}
QMenuBar::item:selected {
color:green;
background-color:rgb(236, 242, 245);
}
QMenuBar::item:pressed {
color:green;
background-color:rgb(233, 227, 227);
}
3.2 菜單樣式
菜單我們設置成與菜單欄一樣;菜單的item指代每一個菜單選項,我們對其設置合適的margin和padding大小,border、item的selected和pressed狀態設置成菜單欄的樣式,使其看起來布局空間合理且與菜單欄一致:
QMenu {
background-color:white;
border:1px solid rgb(0, 171, 255);
padding:1px;
}
QMenu::item {
height:15px;
width:60px;
background-color:white;
margin:1px;
padding:2px 2px 2px 20px;
border:2px groove gray;
}
QMenu::item:selected {
color:green;
background-color:rgb(236, 242, 245);
}
QMenu::item:pressed {
color:green;
background-color:rgb(233, 227, 227);
}
我們重繪菜單之間的間隔條(separator),簡單的用淺藍色填充1像素高的背景:
QMenu::separator {
height:1px;
margin:1px;
background-color:lightblue;
}
菜單的選中指示框和子菜單我們用圖片來顯示,圖片選用png格式,保持透明通道,使其與背景一致:
QMenu::indicator:checked {
width:10px;
height:10px;
margin-left:3px;
border:0px solid blue;
image:url(:/checked-icon.png);
}
QMenu::right-arrow {
width:15px;
height:15px;
image:url(:/right-arrow.png);
}
4. 運行結果
程序的完整運行結果如下:
代碼見鏈接。
5. 總結
優點:
- 開發效率高,使用簡單。
- QSS繪制模式統一(盒模型),一次學習多處使用。
缺點:
- 與CSS一樣,某些繪制細節比較復雜,需要嘗試。例如QLCDNumber沒有文檔說明可以應用QSS,但是實際上可以設置border和color,然而hover狀態下color屬性不管用。
- 繪制控件相對比較受限制。因為同CSS一樣,繪制都是按照既有的規則進行,自然不能像Qt原生控件那樣靈活(但是個人覺得很多場景用QSS就夠用了)。
- 某些控件的子控件不能獨立繪制。一旦一個子控件設置了樣式,其他子控件也需要設置。