文章目錄
❤️一.前言
不少人應該和我同樣,想作界面才接觸的Qt,結果就是作不出來華麗的界面,想給控件上個色?不會,百度半天,好不容易給控件添加了背景色,下一個控件又不會了,別急,此次福利來了,我將平時用到的樣式表作了一個總結,並作了一個一鍵生成,調節數據就能夠實時顯示,裏面包括了Label,LineEdit,PushButton,CheckBox,RadioButton,ScrollBar,Slider,Progressbar,Tabwidget,ToolBox,TabWidget控件的自定義。代碼很簡單,就是重複寫槽函數,但其對於新手的學習頗有幫助,避免了盲目,大量的經過百度數據拼接樣式表。一來方便學習,因此參數都寫在左下角,方便了解到使用了什麼生成了什麼,二來不用重複造輪子,調節後,可直接將左下角生成的QSS代碼複製到qt的樣式表裏面便可顯示效果。可能有一些人會說這是一種偷懶,讓人逐漸不想學習,只能說智者見智仁者見仁吧。
css
而後上面是效果圖,哈哈哈,你們若是想要軟件,可直接拉到文末地址獲取,而這篇文章除了想告訴你們這個一鍵生成以外,就是湊個字數好上推薦,哈哈,開個玩笑,仍是想主要說一下qt裏面樣式表的一個語法和使用步驟,以及一些經驗。隨着深刻學習,你會漸漸知道閱讀文檔和本身動手實踐纔是最高效的學習方法。html
❤️二.三種方式添加樣式表
- 直接在Qt Designer 中添加樣式
- 在代碼中使用setstylesheet函數添加樣式
- 建立qss文件添加樣式
不管哪種添加,都離不開樣式表語法,樣式表語法由選擇器和聲明構成,選擇器能夠指定對誰生效,能夠指定不一樣狀態時生效不一樣的樣式,而聲明就是樣式,這些知識點,下面都將一一說明。git
➡️1.先說第一種,直接在Qt Designer 中添加樣式。
這種方式的優勢就是快,直接,缺點也很明顯,就是隻能設定一次,應用在固定不變的ui上,這種方法是首選,可是當須要根據當前操做作出對應的變化,第一種方法就不行了,例如按一下按鈕變一種顏色,或者調節參數,這時咱們就須要第二種方法。
github
➡️2.在代碼中使用setstylesheet函數添加樣式
好比在Qt Designer 上咱們拖了一個標籤控件,咱們就能夠在cpp這樣來設置樣式表:windows
ui->Lable->setStyleSheet("background:rgb(150, 190, 60);"); //注意後面的分號要加上,其實就是把第一種方法裏面的樣式表,加上雙引號放在括號裏面就能夠了。
利用第二種方法就能夠隨意更改樣式表:編輯器
if(xxxx) { ui->Lable->setStyleSheet("background:rgb(150, 190, 60);"); } if(xxxx) { ui->Lable->setStyleSheet("background:rgb(150, 100, 100);"); }
第二種方法也有缺點,就是耦合性高,爲了下降耦合性(與邏輯代碼分離),咱們一般會定義一個QSS文件,來存放樣式,也就是第三種方式。ide
注意:setStyleSheet的設置以最後一次設置爲準,每次設置(調用setStyleSheet(「樣式」))都會覆蓋以前一次設置的樣式。
函數
➡️3.建立qss文件添加樣式
建立qss文件不要使用windows下的記事本,這裏推薦使用Nodetad++或者更高級的編輯器。不然可能會出錯。
緣由是記事本生成的utf-8文件是帶bom(自行百度),這個咱們沒法經過記事本去掉,而Nodetad++能夠,儘管qt在編碼項目-編碼有一個老是bom的選項,可是經測試,沒什麼用,bom仍是存在,能夠看一下這個Qt讀取qss文件失敗或qss不生效解決方案。
咱們建立一個qss後綴的文件,並寫入
學習
#label { background:rgb(100,100,100); }
將這個qss文件做爲資源文件加載到qt中,以下圖,建立一個資源文件,並添加現有文件(qss文件):
在構造函數中編寫以下代碼:
測試
QString qss; QFile qssFile("./lib/sheet.qss"); qssFile.open(QFile::ReadOnly); if(qssFile.isOpen()) { qss=QLatin1String(qssFile.readAll()); qDebug()<<qss; this->setStyleSheet(qss); qssFile.close(); }
最後將utf-8 bom由原先的是utf-8就添加改成目前存在了則保留。至此qss樣式表加載完成。
運行結果:
這就是第三方法,這種方法在界面樣式較複雜時,咱們在文件中編寫樣式,內容比較清晰,下降耦合性(與邏輯代碼分離)。
- 三種方法使用哪種?
- 對於初學者,我認爲第一種方法是首選,由於初學者每每不須要過多複雜控件,對於少許的控件,代碼也不是不少,使用第一種方法簡單高效,而且能夠幫助咱們檢驗樣式是否編寫正確,這是對於初學者最有幫助。
- 對於有一點基礎的,隨着學習的深刻,不用我說,也應該感受到第一種的侷限性,也就是我說是的缺點,這個時候就應該使用第二種方法,來彌補第一種方法帶來的缺陷,這個時候控件還不是不少,代碼寫樣式表還容易找。
- 第三種方法就是對於你已經很厲害了,能寫出一個本身看得過去的程序了,控件也多了起來,業務邏輯也多了起來,這個時候就能夠下降耦合性(與邏輯代碼分離),從而使用第三方法。
- 最終的建議就是說將第二種和第三者方法結合使用,來彌補各自的不足。
爲了講解方便,下面的說明將使用第一種方法展開。
❤️三.選擇器
qt的官方文檔介紹了最有的選擇器,而不是最全的,Qt樣式表支持CSS2中定義的全部選擇器。下面截取了qt支持的選擇器,點擊瀏覽CSS2文檔。
翻譯過來就是,使用的網頁翻譯,可能有錯誤。
想要所有介紹,我以爲不現實,因此就拿一些經常使用的來舉例子,各位看官觸類旁通。
➡️1.通用選擇器(*)
通用選擇器能夠說是最老實的選擇器,它匹配因此的控件。若是通用選擇器不是"簡單選擇器"的惟一組成部分,則能夠省略「 *」。好比
*#label { background-color:rgb(50,50,50);//聲明 }
選擇器中除了通用選擇器,還有咱們下面將要介紹的ID選擇器,注意上面那句話:若是通用選擇器不是"簡單選擇器"的惟一組成部分,則能夠省略「 *」。因此這裏的「*」是能夠省略的。
#label { background-color:rgb(50,50,50);//聲明 }
所達到的效果和上面的效果是同樣的。因此也是最簡單的選擇器。
➡️2.類型選擇器(控件類名,如QPushButton)
類型選擇器會匹配控件類及其子類的實例,與類選擇器的不一樣的是類選擇器匹配控件類實例,但不匹配其子類的實例。
QPushBuuton { background-color: rgb(0, 255, 255); }
當有多個相同控件,例如按鈕須要使用一種樣式表的時候,就可使用類型選擇器,咱們只須要將按鈕放在同一個容器中,例如frame,就能夠應用到容器中的按鈕了,點擊Apply,糟糕,是否是沒有任何做用?不急,讓咱們看看文檔怎麼說。
在按鈕控件旁邊的說明中,有一個警告,翻譯過來就是:
警告:若是僅在QPushButton上設置背景色,除非將border屬性設置爲某個值,不然背景可能不會出現。這是由於,默認狀況下,QPushButton繪製的本機邊框與背景色徹底重疊。
哦,咱們知道了想要讓背景生效,就須要指定border這個值,那咱們就隨便給border加一個值,再點擊Apply看看,是否是好了。
➡️3.後代選擇器(QFrame QPushBuuton)
QFrame QPushBuuton { background-color: rgb(0, 255, 255); border:none; }
匹配全部QPushButton實例,它們是QFrame的後代(子代,孫子代等),如圖中的QFrame(藍色)中包含了四個QPushButton,以及一個QWidget(黃色),而且QWidget下面還有兩個QPushButton,這樣對於QFrame來講,四個QPushButton和QWidget是子代,而QWidget裏面的兩個QPushButton對於QFrame來講就是孫子代。
➡️4.子代選擇器(QFrame > QPushBuuton)
QFrame > QPushBuuton { background-color: rgb(0, 255, 255); border:none; }
匹配全部QPushButton實例,它們是QFrame的直接子代,仍是拿上面的圖來體現,QFrame QPushBuuton中間加了>符號之後,只有QFrame的直接子代能夠匹配。
➡️5.ID選擇器(QLabel #label)
匹配對象名稱爲label的全部QLabel實例。
這裏的QLabel和通用選擇器一個,能夠選擇省略,由於每一個控件的ID(名字)是同樣的,無需指定類型,這個沒什麼難點。
➡️6.類選擇器(.QPushButton)
.QPushBuuton
{
background-color: rgb(0, 255, 255);
border:none;
}
匹配QPushButton的實例,但不匹配其子類的實例,這個能夠說與類型選擇器是一對,就好像後代選擇器和子代選擇器的關係,這種選擇器只會匹配該類的全部對象, 而不會匹配其派生類的對象。
➡️7.屬性選擇器(QPushButton[flat=「false」])
屬性選擇器應用於同一個類型下不一樣實現效果(如但願 QPushButton 有兩套通用樣式),文字好理解,操做起來不必定好理解,我舉兩個例子幫助你們理解。
QPushButton { color:rgb(100,0,0); border:none; } QPushButton[flat = "true"] { background-color:rgb(100,100,100); } QPushButton[flat = "false"] { background-color:rgb(255,255,255); }
flat=「false」/flat=「true」這兩個值,能夠隨意定義,格式就是「key」對應「value」。(隨便說一下這個flat屬性,爲真的時候就是去掉邊框,鼠標按下去纔會出現邊框,能夠提示用戶體驗。)定義類型屬性,須要用到setProperty(「key」,「value」);這個函數,咱們來試一下,先建立兩個按鈕,而後用咱們上面說過的第二種樣式表添加方法來實現。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->pushButton_3->setProperty("name","zhangsan"); ui->pushButton_4->setProperty("name","lisi"); this->setStyleSheet("QPushButton{color:rgb(255,255,255);}" "QPushButton[name = 'zhangsan']{background:rgb(0,0,255);}" "QPushButton[name = \"lisi\"]{background:rgb(255,0,0);}"); //這裏的value 用雙引號或者單引號均可以 }
效果以下:
❤️四.僞類
➡️1.狀態僞類
僞狀態對類型選擇器或類選擇器指定的全部控件設置它在指定狀態時的樣式,僞狀態以冒號(:)做爲分隔 緊跟着選擇器,狀態僞類不少,上圖是從官方截取的,全部的僞狀態,都打包進了軟件,你們能夠下載軟件查看,這裏就介紹兩個初學者經常使用的,讓你們體會到僞狀態的用法。
可能細心讀者已經發現了,至此,咱們上面所說的這些樣式是固定樣式,通俗一點就是不會動,爲了能給用戶更好的體驗和互交,軟件界面的按鈕或者什麼功能控件,當鼠標滑過或者按下去,控件自己就會發送變化,僞狀態就是運用到了這裏,咱們一塊兒往下看。
#pushButton_4 { background-color: rgb(78, 110, 255); border:none; } #pushButton_4:hover { background-color: rgb(255, 80, 141); }
這個:hover就是僞狀態,表示鼠標滑過期的樣式。
:pressed 鼠標按下
這裏咱們不光能指定顏色,也能夠指定文字的顏色,大小,字體,都是能夠的。
:focus 焦點,這個多用於文本輸入框。
軟件包含大量僞狀態說明,可下載查看。
❤️五.聲明
聲明就是{}號裏面的內容,例如:
- background:rgb(150, 190, 60); 背景顏色
- border-color:rgba(0,0,0,255); 邊框顏色
- color:rgb(150, 190, 60);文字顏色
- border-style:none; 邊框風格
- border-radius:0px;圓角大小
- font:15px 「宋體」;字體大小/字體
- font-weight: bold;字體粗細
- text-decoration:line-through;字體修飾
更多的可使用軟件查看:裏面包含了大量聲明。包括文末最後的官方連接。
❤️六.子控件
除了像QLabel,QPushButton這一類比較簡單的控件,沒有子控件,還有複雜控件,他們除了自己,還有屬於本身的子控件。
爲何複雜控件須要子控件呢,好比Slider滑條:
- 滑塊(紅色)的凹槽使用:: groove設置樣式。默認狀況下,凹槽位於窗口小部件的「內容」矩形中。
- 滑塊(綠色)的拇指使用:: handle子控件設置樣式。子控件在凹槽子控件的「內容」矩形中移動。
若是隻是簡單控件,那麼一旦設置背景顏色,整個滑塊和滑塊的拇指都是一個顏色,顯然對用戶不太友好,而將兩個簡單控件組成複雜控件,這樣就能夠單獨對某一個小控件進行樣式調整,大大提示美感。
關於全部的子控件,你們能夠點擊文末地址,也可使用軟件。
❤️七.解決衝突
當多個樣式規則使用不一樣的值指定相同的屬性時,就會發生衝突。考慮如下樣式表:
QPushButton #okButton {color: gray} QPushButton {color: red}
這兩個規則都匹配被調用的QPushButton實例okButton,而且該color屬性存在衝突。要解決此衝突,咱們必須考慮選擇器的特殊性。在上面的示例中,QPushButton#okButton被認爲比更爲具體QPushButton,由於它(一般)引用單個對象,而不是類的全部實例。
一樣,具備僞狀態的選擇器比未指定僞狀態的選擇器更具體。所以,如下樣式表指定當鼠標懸停在QPushButton上時,QPushButton應該具備白色文本,而不是紅色文本:
QPushButton:hover { color: white } QPushButton { color: red }
爲了肯定規則的特殊性,Qt樣式表遵循CSS2規範:
選擇器的特異性計算以下:
計算選擇器中ID屬性的數量(= a)
計算選擇器中其餘屬性和僞類的數量(= b)
計算選擇器中元素名稱的數量(= c)
忽略僞元素[即子控件 ]。
將三個數字abc(在基數較大的數字系統中)鏈接起來可得出特異性。
一些例子:
獲得的數字最大者即最終樣式,若是數字同樣,則以最後樣式表爲準。
❤️八.級聯和遺產
➡️1.級聯
能夠在QApplication父窗口小部件和子窗口小部件上設置樣式表。經過合併在小部件祖先(父母,祖父母等)上設置的樣式表以及在QApplication上設置的任何樣式表,能夠獲取任意小部件的有效樣式表。
當發生衝突時,不管衝突規則的特殊性如何,始終要優先於任何繼承的樣式表使用窗口小部件本身的樣式表。一樣,父窗口小部件的樣式表優先於祖父母的樣式表等。
這樣的結果之一是,在窗口小部件上設置樣式規則會自動賦予它優先於祖先窗口小部件的樣式表或QApplication樣式表中指定的其餘規則的優先級。考慮如下示例。首先,咱們在QApplication上設置樣式表:
qApp->setStyleSheet("QPushButton { color: white }");
而後,在QPushButton對象上設置樣式表:
myPushButton->setStyleSheet("* { color: blue }");
在樣式表QPushButton力QPushButton(以及任何子部件)有藍色的文字,儘管應用程序範圍內的樣式表提供的更具體規則集。
若是咱們寫了,結果將是相同的
myPushButton->setStyleSheet("color: blue");
除非QPushButton有子級(這不太可能),不然樣式表對它們沒有影響。
➡️1.遺產
在經典CSS中,當未明確設置項目的字體和顏色時,它將自動從父項繼承。當使用Qt樣式表,一個小部件並不會自動從其父繼承控件的字體和顏色設置。
例如,考慮QGroupBox內的QPushButton:
qApp->setStyleSheet("QGroupBox { color: red; } ");
該QPushButton沒有一個明確的顏色設置。所以,它具備系統顏色,而不是繼承其父QGroupBox的顏色。若是要在QGroupBox及其子級上設置顏色,能夠編寫:
qApp->setStyleSheet("QGroupBox, QGroupBox * { color: red; }");
相反,設置字體並使用QWidget :: setFont()和QWidget :: setPalette()傳播到子窗口小部件。
❤️九.相關連接或下載
- Qt樣式表語法官方文檔,包含詳細的語法說明。
- Qt小部件,僞狀態,屬性清單官方文檔,包含詳細的僞狀態,屬性清單。
- Qt控件樣式表示例官方文檔,包含大量控件的樣式表示例。
- Qt控件樣式表自定義官方文檔,列出了可使用樣式表自定義的Qt小部件。
- FdpgQtStyleSheet源碼,別忘了給個star再走!
- FdpgQtStyleSheet軟件(最近csdn推出了粉絲免費下載機制,因此你只要關注,就能夠免費下載了,不再須要積分了!)