QSS使用总结
QSS使用總結(jié):
1. 什么是QSS
QSS:全稱Qt Style sheet即Qt樣式表,他是Qt提供的一種用來自定義控件外觀的機(jī)制。
QSS大量參考了CSS的內(nèi)容,只不過QSS的功能比CSS要弱很多,體現(xiàn)在選擇器更少,可以使用的屬性也更少,
并且并不是所有的屬性都可以在Qt的所有控件上。
2. QSS的使用
1 全局QSS文件方式
? 一般將項(xiàng)目中所有控件的樣式寫入一個(gè)文件中,然后在程序啟動(dòng)后加載文件然后設(shè)置全局的樣式
?
int main(int argc, char* argv[])
{
?? ?...
?? ?QFile file(":/qss/default.qss");
?? ?file.open(QFile::ReadOnly);
?? ?QTextStream filetext(&file);
?? ?QString styleSheet = filetext.readAll();
?? ?qApp->setStyleSheet(styleSheet);
?? ?...
}?
2 在程序中為某個(gè)具體的控制設(shè)置樣式
ui->okBtn->setStyleSheet("font-size:30px");
--->當(dāng)用戶在程序中設(shè)置了控件的qss樣式,則會(huì)覆蓋全局的樣式
3. QSS的語法規(guī)則
QSS的規(guī)則幾乎和CSS相同,一條QSS樣式由兩部分組成,一部分為選擇器 指定了設(shè)置樣式的控件,另一部分為指定的屬性的值,表示哪些屬性會(huì)收到影響QPushButton{ color: #FF0000}。
QPushButton表示選擇器,指定了所有的QPushButton以及其子類會(huì)收到影響,注意凡是繼承QPushButton的類都會(huì)受到影響,這點(diǎn)與CSS不同,因?yàn)镃SS沒有類/子類的概念僅為標(biāo)簽。
而后的{ color: #FF0000}則是規(guī)則的定義,表明指定前景色為紅色,該樣式的意義為設(shè)置QPushButton類以及子類的所有實(shí)例的前景色設(shè)置為紅色
如果MyButton繼承自QPushButton,么上面的規(guī)則也會(huì)應(yīng)用到所有MyButton控件上,但是如果規(guī)則是如下的:
MyButton{color:#FF0000}?
則只會(huì)對MyButton的實(shí)例應(yīng)用紅色的前景顏色,而對QPushButton的實(shí)例沒有應(yīng)用。
4. `
通配選擇器:*; 匹配所有的控件
類型選擇器:QPushButton; 匹配所有的QPushButton和其子類的實(shí)例
屬性選擇器:QPushButton[flat="false"]; 匹配所有flat屬性為false的QPushButton實(shí)例,也可以使用自定義的屬性
類選擇器: .QPushButton; 匹配所有的QPushButton的實(shí)例,但是不匹配其子類。這與CSS中的選擇器不一樣,其前面有個(gè)點(diǎn)號(hào)
ID選擇器: #myButton; 匹配所有ID為myButton的控件實(shí)例,這里的ID指的是objectName指定的值
后代選擇器: QDialog QPushButton; 所有QDialog容器下面的QPushButton, 不管是直接的還是間接的
子選擇器:QDialog > QPushButton; 所有的QDialog容器下面的QPushButton,其中要求QPushButton的直接父類控件使QDialog
--->另外上面的所有的這些選擇器可以聯(lián)合使用,并且支持一次設(shè)置多個(gè)選擇器類型,用逗號(hào)隔開,這點(diǎn)和CSS一樣
例如:frameCut,#frameInterrupt,#frameJoin 表示所有這些id使用一個(gè)規(guī)則。#mytable QPushButton 表示選擇所有id為mytable的容器下面的QPushButton實(shí)例。
5. QSS子控件
QSS的子控件實(shí)際上也是選擇器的一種,因?yàn)檫@種選擇器與CSS有一些不同,所有單獨(dú)列出來。QSS的子控件選擇器是應(yīng)用在一些復(fù)雜控件上的,典型的例如QComboBox,
該控件的外觀包含幾個(gè)部分,一般情況下有一個(gè)矩形的外邊框,右邊有一個(gè)向下的箭頭用于點(diǎn)擊之后會(huì)有彈出下拉列表。
例如:QComboBox::drop-down{image:url(":/iamges/dropdown.png")}
上面的樣式指定所有的QComboBox的下拉框箭頭的圖片為自定義圖片dropdown.png
::dropdown子控件選擇器也可以與上面提到的選擇器一起聯(lián)合使用。
QComboBox#myComboBox::drop-down{image:url(":/iamges/dropdown.png")}
指定id名為myComboBox的QComboBox控件的下拉箭頭的自動(dòng)以圖片,要注意的是子控件選擇器實(shí)際上是選擇復(fù)合控件中的一部分,也就是說對復(fù)合控件中的一部分應(yīng)用樣式,
例如QComboBox的下拉箭頭指定圖片而不是為QComboBox指定圖片
QSS為很多復(fù)雜的復(fù)合控件提供了子控件的定義,以方便對這些復(fù)合控件的各個(gè)部分進(jìn)行樣式設(shè)置。限于篇幅,本文也不能將這些可用的子控件都列出來,在安裝QtCreator之后自帶的幫助中就有很詳細(xì)的描述。
https://blog.csdn.net/Staranywhere/article/details/106652678
6. QSS偽狀態(tài)
QSS的偽狀態(tài)選擇器實(shí)際上與CSS中的類似,是以冒號(hào)開頭的一個(gè)選擇表達(dá)式。例如:hover表示當(dāng)鼠標(biāo)經(jīng)過時(shí)的狀態(tài),他限制了當(dāng)控件在某一種狀態(tài)下的時(shí)候才能應(yīng)用QSS規(guī)則。偽狀態(tài)只能描述一個(gè)控件的狀態(tài),或者是一個(gè)復(fù)合控件的子控件的狀態(tài),所以該偽狀態(tài)選擇器智能放在選擇器的最后面
例如:QComboBox:hover{background-color:red;} 該規(guī)則表示當(dāng)鼠標(biāo)經(jīng)過QComboBox上面時(shí),其背景色指定為紅色,該偽狀態(tài):hover描述的是QComboBox的狀態(tài)
偽狀態(tài)除了可以描述選擇器的控件以外,還可以描述子控件選擇器所選擇的復(fù)合控件中的子控件的狀態(tài)。
例如: QComboBox::drop-down:hover{background-color:red;} 該規(guī)則表示鼠標(biāo)經(jīng)過QComboBox的下拉框箭頭的時(shí)候,該下拉框的背景顏色變成紅色。
幾個(gè)偽狀態(tài)可以一起使用, 例如:QCheckBox:hover:checked{color: red} 指定一個(gè)當(dāng)鼠標(biāo)經(jīng)過一個(gè)選中的QCheckBox的時(shí)候,設(shè)置其文字的前景顏色為紅色
QSS提供了很多的偽狀態(tài),一些偽狀態(tài)只能用在特定的控件上,具體有哪些偽狀態(tài),在Qt的幫助里面有詳細(xì)的列表,限于篇幅這里也不列出了。
https://blog.csdn.net/Staranywhere/article/details/106967756
7. QSS級(jí)聯(lián)與沖突
QSS中的級(jí)聯(lián)包含以下幾個(gè)方面
1 當(dāng)在同一個(gè)控件上應(yīng)用兩個(gè)不同的規(guī)則, 那么應(yīng)該應(yīng)用哪一個(gè)規(guī)則的問題,也就是如何解決這種沖突
2 在一個(gè)容器控件上設(shè)置的QSS規(guī)則會(huì)對容器里面的控件產(chǎn)生效果(這要取決于容器控件上設(shè)置的QSS規(guī)則時(shí)什么樣的規(guī)則, 如果其規(guī)則僅僅針對容器控件本身則該子控件無影響,如果該QSS規(guī)則里面還有對子控件的設(shè)置,則自然會(huì)對子控件產(chǎn)生效果)。
級(jí)聯(lián)問題是解決當(dāng)一個(gè)控件被層層父容器包裹,并且在每一層的父容器都有對該控件的樣式設(shè)置的時(shí)候,該控件的最終效果是合并這些父容器上的QSS效果
沖突問題:
QPushButton#okButton{color: gray}
QPushButton{color: red}
這兩條規(guī)則都會(huì)應(yīng)用到名為obButton的按鈕上,但是他們?yōu)橥粋€(gè)屬性設(shè)置了不同的顏色,這會(huì)有沖突,那么要解決這樣的沖突就必須考慮到選擇器的特異性(具體性),顯然QPushButton#okButton僅僅針對對象名為okButton的控件有效果,而QPushButton卻對所有的QPushButton的實(shí)例或者是其子類的實(shí)例有效果,顯然QPushButton#okButton選擇器更加特殊,也就是更具有特異性。所以最終okButton前景色被應(yīng)用為灰色。如果兩條規(guī)則的特異性一樣,那么就選擇聲明靠后的那一條。
--->另外如果一個(gè)選擇器應(yīng)用了偽狀態(tài),而另一個(gè)沒有,那么應(yīng)用偽狀態(tài)的選擇器更加特殊。
例如:
?? ?QPushButton:hover{color: white}
?? ?QPushButton{color: red}
顯然QPushButton:hover比單純的QPushButton更加具有特異性。這兩條規(guī)則表示當(dāng)鼠標(biāo)放在按鈕上的時(shí)候文字是白色,其他情況下都是紅色。?? ?
--->如下面兩個(gè)規(guī)則的特異性是一樣的,那么應(yīng)該是如何應(yīng)用呢:即如果兩條規(guī)則的特異性一樣,那么就選擇聲明靠后的那一條。
例如:
?? ?QPushButton:hover { color: white } ?//如果鼠標(biāo)經(jīng)過則前景白色
?? ?QPushButton:enabled { color: red } ?//如果按鈕是enabled狀態(tài)則前景紅色
所以默認(rèn)情況下前景文字是紅色的,當(dāng)鼠標(biāo)經(jīng)過的時(shí)候并不會(huì)變成白色,因?yàn)樗麄兊奶禺愋允且粯拥?#xff0c;所以選擇后面的,也就是紅色。
那么換一下順序會(huì)怎樣呢:
?? ?QPushButton:enabled { color: red } ?//如果按鈕是enabled狀態(tài)則前景紅色
?? ?QPushButton:hover { color: white } ?//如果鼠標(biāo)經(jīng)過則前景白色
當(dāng)鼠標(biāo)經(jīng)過的時(shí)候,就變成白色的了,因?yàn)樗麄兊奶禺愋砸粯?#xff0c;所以選擇后面的規(guī)則,也就是鼠標(biāo)經(jīng)過前景變成白色。
--->如果把其中的一條的特異性增加,
例如:
?? ?QPushButton:hover:enabled { color: white }
?? ?QPushButton:enabled { color: red }
那么第一條的特異性比第二條大,所以應(yīng)用第一條的規(guī)則。
--->另外一種特異性發(fā)生在類型選擇器上:
?? ?QPushButton { color: red } ? //應(yīng)用在所有的QPushButton上
?? ?QAbstractButton { color: gray } //應(yīng)用在所有的QAbstractButton上
而在類的繼承結(jié)構(gòu)上,QAbstractButton是QPushButton的父類,顯然QPushButton更加具有特異性,所以QPushButton的前景顏色被應(yīng)用為紅色,而不是灰色。
有沒有一個(gè)辦法來確定兩條QSS規(guī)則的特異性大小呢,其實(shí)QSS使用的特異性的計(jì)算方法與CSS是一樣的,詳細(xì)可以參考CSS2的文檔規(guī)范,這里還是簡要的說明一下,特異性這個(gè)東西在CSS中一般被稱為權(quán)重,權(quán)重越大的越優(yōu)先使用,CSS的計(jì)算規(guī)則如下:
A 計(jì)算一條規(guī)則中id選擇器的個(gè)數(shù),假設(shè)存放在變量a中
B 計(jì)算一條規(guī)則中類選擇器和屬性選擇器的個(gè)數(shù),粉放在變量b中
C 計(jì)算一條規(guī)則中的類型選擇器的個(gè)數(shù),存放在變量c中?
4.忽略偽元素,對應(yīng)QSS中的子控件
下面是具體的計(jì)算方法:
* ? ? ? ? ? ? {} ?/* a=0 b=0 c=0 -> specificity = ? 0 */
LI ? ? ? ? ? ?{} ?/* a=0 b=0 c=1 -> specificity = ? 1 */
UL LI ? ? ? ? {} ?/* a=0 b=0 c=2 -> specificity = ? 2 */
UL OL+LI ? ? ?{} ?/* a=0 b=0 c=3 -> specificity = ? 3 */
H1 + *[REL=up] {} ?/* a=0 b=1 c=1 -> specificity = ?11 */
UL OL LI.red ? {} ?/* a=0 b=1 c=3 -> specificity = ?13 */
LI.red.level ? ?{} ?/* a=0 b=2 c=1 -> specificity = ?21 */
#x34y ? ? ? ?{} ?/* a=1 b=0 c=0 -> specificity = 100 */
上面的計(jì)算規(guī)則是CSS的計(jì)算規(guī)則,同樣可以應(yīng)用的QSS上。
關(guān)于級(jí)聯(lián):
QSS可以設(shè)置在QApplication上,也可以設(shè)置在一個(gè)部件的容器部件上,也可以設(shè)置在子孫控件上,一個(gè)部件最終使用的樣式是合并了他的所有父容器,祖父容器等上面設(shè)置的所有樣式的結(jié)果,這些設(shè)置會(huì)進(jìn)行疊加。 如果發(fā)生沖突,則選擇部件本身設(shè)置的樣式效果
--->QSS中似乎為父容器控件本身設(shè)置了樣式,并不會(huì)被子控件繼承。
例如如果QFrame中有一個(gè)QPushButton控件,則語句 ui->frame->setStyleSheet{"Frame{color: red; border: 1px solid red}"} 僅僅為QFrame設(shè)置樣式并不會(huì)應(yīng)用到其里面的QPushButton上。 如果下面的語句就可以:
ui->frame->setStyleSheet("QPushButton{ color: red; border:1px solid red }");
ui->frame->setStyleSheet("*{ color: red; border:1px solid red }");
8 QSS實(shí)際應(yīng)用中要注意的地方
在使用QSS的時(shí)候遇到過一些坑,看似簡單,但是如果不知道的話,還是很折磨人的:
<1>使用QSS設(shè)置邊框無效,例如:
border:1px solid red; //Ok
border:solid 1px red; //Error
border:red 1px solid; //Error
border:red solid 1px; //Error
設(shè)置邊框顏色和像素的時(shí)候,必須是第一種順序,而CSS中是無所謂的,至于原因,我也不清楚,就是這么坑人。
<2> QSS設(shè)置寬高無效:
在QSS中設(shè)置寬高必須要使用 min-width和min-height,max-width,max-height來設(shè)置,用width和height設(shè)置是沒有任何效果的。
<3>QComboBox的樣式設(shè)置的問題:
QcomboBox是一個(gè)復(fù)雜的控件,QComboBox由3部分組成,一個(gè)是QComboBox的外框,里面有一個(gè)下拉按鈕,這個(gè)按鈕可以通過QComboBox::drop-down 來控制其位置,將其定義到QComboBox的左邊而不一定是右邊。另外在這個(gè)下拉按鈕上面一般會(huì)有一個(gè)向下的箭頭,這個(gè)箭頭圖像也是可以定制的,通過QComboBox::down-arrow來指定箭頭的圖像。
如果要控制QComboBox的彈出下拉列表的樣式需要通過:
QComboBox QAbstractItemView {
? //設(shè)置當(dāng)點(diǎn)擊下拉按鈕之后彈出的下拉列表的樣式,要注意的是這里的樣式
? //僅僅只能設(shè)置彈出的整個(gè)下拉列表范圍的矩形的樣式,不能設(shè)置下拉列表
? //中的每一個(gè)下拉項(xiàng)的樣式,例如不能設(shè)置每一個(gè)下拉項(xiàng)高度
}
QcomboBox{
? //設(shè)置未彈出下拉列表的樣式
}
?
QComboBox QAbstractItemView::item {
//設(shè)置彈出下拉列表中的每一個(gè)下拉項(xiàng)的樣式,這里的樣式要想生效,必須先
//對QcomboBox做下面的設(shè)置
//QStyledItemDelegate* itemDelegate = new QStyledItemDelegate();
//combox->setItemDelegate(itemDelegate); ??
}
總結(jié)
- 上一篇: 驾校一点通电脑版2015 v1.5 最新
- 下一篇: leetcode36.有效的数独(中等)