1. 程式人生 > >【golang-GUI開發】QSS的使用(一)———QSS入門指南

【golang-GUI開發】QSS的使用(一)———QSS入門指南

在這篇文章中我們將初步體驗對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