QSS的使用(二)——實現ColorLabel
在上一篇文章中,我們已經瞭解了QSS的基礎使用,現在我們將會看到一個簡單的例子來加深對QSS的理解。
需求分析
我們想要在介面中讓文字顯示出指定的顏色,現在有幾種方案:
- 使用paintEvent手動計算文字大小和位置,然後繪製
- 利用QLabel可以識別HTML標籤的特性實現彩色文字
- 利用QSS+QLabel實現彩色文字
我們逐一分析這三種方案的利弊。
首先是paintEvent的方案,這是三種方案中最靈活卻也是最複雜的,通過重繪事件可以最大限度的發揮其靈活性,但對於字型大小的計算以及文字對齊的控制都需要自行處理,如此一來工程量不可謂不大,顯然對於我們只是希望讓文字顯示出指定顏色的簡單需求來說實現成本過高了。
其次是使用HTML標籤的方案,這種方案的好處在於QLabel已經幫我們處理了文字的繪製和對齊,我們只需要將合適的HTML內容新增進去即可,雖然靈活性不如第一種,但是其簡便性是顯而易見的,例如:
label = QLabel(r'<font color="#ff0000">Qt</font>') label.show()
這將會顯示一個紅色的“Qt”文字。
然而該方案的缺點也是顯而易見的,雖然QLabel識別了HTML標籤並且不會明文顯示,但它確是實際存在於label中的:
print(label.text()) # '<font color="#ff0000">Qt</font>'
當我們需要設定/獲取label中的文字時,就不得不想辦法去除這個HTML標籤,又或者當我們想要修改label的顏色時,就不得不對text做更復雜的處理,顯然,我們的需求中也會包含以上類似的場景,所以這種看起來簡單實際上暗含了複雜性的方案我也沒有采用。事實上開發中經常會出現這種坑,所以在方案選擇時三思而後行總是有好處的。
最後一種是QSS+QLabel的方案,也是目前我採用的方案。你可能已經猜到了,這種方案兼具QLabel的實用和QSS的簡單,也不會在內部儲存多餘的資訊,在犧牲部分靈活性的前提下是最簡單也是最合適的解決方案,接下來我們就詳細瞭解下這種方案的實現。
ColorLabel的實現
所有的程式碼在ofollow,noindex" target="_blank">這裡 ,具體使用可以在我的專案 中看到。
首先是定義預設顏色和QSS模板,模板用於後續的顏色設定:
var ( // 控制顏色的qss模板 colorStyle = "QLabel{color:%s;}" // 預設顏色-黑色 defaultStyle = "QLabel{color:black;}" )
其實空字串""就表示使用系統自帶樣式,然而我這裡為了統一就選用了黑色。
ColorLabel元件的定義,繼承自QLabel,並儲存自己的樣式:
// ColorLabel 使用QSS顯示彩色文字 type ColorLabel struct { widgets.QLabel // color style sheet defaultColor string }
接著是建構函式,函式的功能在註釋中寫的比較清楚了,關鍵在於它呼叫的兩個方法:
// NewColorLabelWithColor 生成colorlabel,設定default color為color // color為空則設定為黑色 // color可以是顏色對應的名字,例如"black", "green" // 也可以是16進位制的RGB值,例如 #ffffff, #ff08ff, #000000 func NewColorLabelWithColor(text, color string) *ColorLabel { l := NewColorLabel(nil, 0) l.SetDefaultColor(color) l.SetDefaultColorText(text) return l }
SetDefaultColor
用於給ColorLabel設定預設的顏色,而SetDefaultColorText
則和setText
槽一樣,給label設定文字,並使用預設指定的顏色顯示,通過這兩個方法我們可以處理絕大部分的使用場景,現在來看看它們的實現:
// SetDefaultColor 設定defaultColor // color為""時設定為黑色 // 不會改變現有text內容的顏色 func (l *ColorLabel) SetDefaultColor(color string) { if color == "" { l.defaultColor = defaultStyle return } l.defaultColor = fmt.Sprintf(colorStyle, color) } // SetDefaultColorText 設定新的text值,並使其顯示設定的default color func (l *ColorLabel) SetDefaultColorText(text string) { l.SetText(text) l.SetStyleSheet(l.defaultColor) }
當color為空字串時使用預設顏色,否則設定為color指定的顏色,color可以是顏色的名字/16進位制值。值得一提的是,修改預設顏色並不會影響已經顯示的文字,如果想改變已經顯示的文字的顏色,需要使用ChangeColor
。
SetDefaultColorText
則先使用SetText
設定文字,隨後新增QSS,因為這中間間隔相當短所以先新增QSS還是後新增不會有明顯可見的區別,而且事件迴圈也會盡量將兩次呼叫產生的重繪事件合併。
有時候我們也需要中途修改ColorLabel的顏色,或者顏色和文字一起修改,這時上面的方法就滿足不了我們了,比如在這段程式碼 裡。
所以我們也實現了這些功能:
// ChangeColor 改變現有text的顏色 // 並且設定defaultColor為新的顏色 // color為""時設定為defaultStyle func (l *ColorLabel) ChangeColor(color string) { l.SetDefaultColor(color) text := l.Text() l.SetDefaultColorText(text) } // SetColorText 用color顯示新的text // color為""時顯示defaultStyle func (l *ColorLabel) SetColorText(text, color string) { var style string if color == "" { style = defaultStyle } else { style = fmt.Sprintf(colorStyle, color) } l.SetText(text) l.SetStyleSheet(style) }
ChangeColor
改變了已顯示文字的顏色,並設定label預設的顏色為新的顏色。SetColorText
則顯示指定顏色的文字,不會影響label的預設設定。
有了這些方法,我們就能方便地設定文字的顏色了,而且因為我們繼承自QLabel,所以可以使用QLabel提供的方法對文字的顯示做更進一步的控制。
通過這個小例子,我們已經對QSS的實際使用有了較為具體的印象,在實際應用中QSS的強大功能將會為我們提供許多的便利,掌握QSS的使用會使你的開發技能更上一層樓。
歡迎大家提出意見,也歡迎大家關注我的專案 。