在這篇文章中我們將初步體驗對qss的使用。並對在goqt中使用qss時的注意事項進行說明。
那么事不宜遲,現在開始我們的qss之旅吧。
QSS語法入門
qss是一種與css3相似的控制Qt組件的樣式表,它有着與css3相似的語法,或者在某種意義上它可以說是對css3進行某些特化后的子集。
在日常開發中,Qt控件自身的外觀有時很難滿足我們的需要,這時候一般會有兩種常見的解決方案,第一種是通過重寫paintEvent
來實現控件的自繪,這種方式最靈活,然而學習和使用成本也是最高的;另一種則是使用qss,通過qss控制widgets的外觀表達。而qss的強大之處在於它不僅簡單易學,而且功能強大,對自定義組件也能提供良好的支持。
下面我們就來簡略學習一下qss的語法。
首先是選擇器,和css3相同,qss需要用選擇器來確定對哪些控件起作用:
QSS選擇器:
名稱 | 形式/示例 | 說明 |
---|---|---|
萬用選擇器 | * | 顧名思義,選擇所有的組件,包括自定義組件 |
類型選擇器 | QLabel | 選擇所有和選擇器指定類型相同的組件,如果是繼承自該組件的類型則也會被選擇 |
屬性選擇器 | QLabel[flat="false"] | 選擇具有某一qss屬性的指定類型的控件,指定繼承類型的派生類的實例不會被選擇 |
class選擇器 | .QLabel | 與類型選擇器相似,不過它不會選擇派生類型的實例 |
ID選擇器 | QLabel#name | 通過setObjectName給控件的實例設置名字,通過這個名字選擇該實例 |
子控件選擇器 | QDialog QLabel | 將選擇父控件中的所有指定子控件 |
直接子控件選擇器 | QDialog > QLabel | 選擇父控件的所有直接子控件,如果指定的子控件包含在其他子控件中將不會被選擇 |
當需要同時使用多個選擇器時,可以像這樣SelectorA, SelectorB, ...
。
狀態選擇器
雖然文檔上這么稱呼,實際上就和css3的偽類選擇器差不多。它可以選擇處於某種狀態的控件。
名稱 | 形式/示例 | 說明 |
---|---|---|
狀態選擇器 | QPushButton:hover | 當控件處於指定的狀態時會被選擇 |
非狀態選擇器 | QPushButton:!hover | 當控件不處於指定狀態時會被選擇 |
嵌套狀態選擇器 | QPushButton:hover:!checked | 當控件擁有全部指定的狀態才會被選擇 |
通過狀態選擇器,我們可以更細致的控制widgets。
局部選擇器
它的真名叫Sub-Controls,意思是某個widget的某個局部組件,比如下拉框的下拉按鈕,所以我們簡稱叫它局部選擇器。
它的形式很簡單:QComboBox::drop-down
通過兩個冒號指定局部組件的名字,這些名字的Qt內置的。對局部選擇器選中的內容修改屬性將會影響局部組件的外觀表現。
所有可用的局部組件名稱都在Qt的文檔中,有需要的可以進行查閱。
屬性指定
看了那么多選擇器,我們再來看看如何指定屬性。
QLabel {
font-size: 20px;
color: #00ff00;
}
QMainWindow {
background-image: url(bg.jpg);
}
QComboBox::down-arrow:pressed {
position: relative;
top: 1px;
left: 1px;
}
可以看到,與css基本無異,值得注意的是定位相關屬性只能用在局部組件上。
自定義組件和qss繼承
首先明確一點,qss與css不同,子控件不會自動繼承父控件的qss。所以想對子控件的樣式進行調整就必須明確的用選擇器選擇子控件。如果你想讓子控件從父控件繼承qss屬性,需要如下代碼:
QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);
對於我們繼承各種widget而來的自定義控件,可以在選擇器里像原生控件一樣指定,例如:
MyWidget {
font-size: 10px;
}
MyWidget:hover {
backgorund: lightblue;
}
而在goqt中會有所不同,因為golang的繼承是用“包含”做的一種模擬,你看起來是繼承了某個widget,實際上只是在struct里包含了某個widget的實例而已,所以我們使用子控件的名字來定義qss是不起效果的,正確的做法如下:
type MyLabel struct {
widgets.QLabel
// some method
}
type MyWidget struct {
widgets.QWidget
// some method
}
// 錯誤做法
// myLabel.setStyleSheet("MyLabel{color:red;}")
// myWidget.setStyleSheet("MyWidget{backgorund:blue}")
// 正確做法
myLabel.setStyleSheet("QLabel{color:red;}")
myWidget.setStyleSheet("QWidget{backgorund:blue}")
不用擔心這樣做會引發沖突,因為如上文所提,每個widget的qss都是獨立的,所以在不做特別設置時完全沒有任何問題。
接下來學什么
現在我們已經學習了QSS的基礎語法,相信聰明的你已經開始查閱文檔或者動手實踐了。
在下一篇文章中我們將會接觸一個使用了QSS的簡單組件的實現,你也可以先看看源代碼做一下預習。
如果覺得以上的代碼對你有所幫助,也歡迎star我的項目:https://github.com/apocelipes/schannel-qt5
參考:
Qt Assistant: Qt Style Sheets
Qt Assistant: Qt Style Sheets Reference