廣西欽州有人幫做網(wǎng)站的公司嗎百度地圖3d實(shí)景地圖
目錄
1、背景介紹
2、基本語法
3、QSS 設(shè)置方式
3.1?指定控件樣式設(shè)置
代碼示例: 子元素受到影響
3.2?全局樣式設(shè)置
代碼示例: 使用全局樣式
代碼示例: 樣式的層疊特性
代碼示例: 樣式的優(yōu)先級(jí)
3.3?從文件加載樣式表
代碼示例: 從文件加載全局樣式
3.4?使用?Qt Designer 編輯樣式
代碼示例: 使用?Qt Designer 編輯樣式
4、選擇器
4.1 選擇器概況
代碼示例: 使用類型選擇器選中子類控件
代碼示例: 使用?id 選擇器
代碼示例: 使用并集選擇器
4.2 子控件選擇器 (Sub-Controls)
代碼示例: 設(shè)置下拉框的下拉按鈕樣式
4.3?偽類選擇器 (Pseudo-States)
?代碼示例: 設(shè)置按鈕的偽類樣式.
1、背景介紹
在網(wǎng)頁前端開發(fā)領(lǐng)域中, CSS 是一個(gè)至關(guān)重要的部分. 描述了一個(gè)網(wǎng)頁的 "樣式". 從而起到對(duì)網(wǎng)頁美化的作用.
- 所謂樣式, 包括不限于大小, 位置, 顏色,?背景, 間距, 字體等等.
現(xiàn)在的網(wǎng)頁很難找到?jīng)]有 CSS 的. 可以說讓 "界面好看" 是?個(gè)剛需.
一個(gè)程序的界面是否好看,是否重要呢?
- 有些面向?qū)I(yè)領(lǐng)域的程序,界面好看與否,不是很關(guān)鍵,更關(guān)鍵的是實(shí)際的效果。
- 有些面向普通用戶領(lǐng)域的程序,界面好看還是很大的加分項(xiàng)。
網(wǎng)頁開發(fā)作為 GUI 的典型代表, 也對(duì)于其他客戶端 GUI 開發(fā)產(chǎn)生了影響. Qt 也是其中之一.
Qt 仿照 CSS 的模式, 引入了 QSS, 來對(duì) Qt 中的控件做出樣式上的設(shè)定, 從而允許程序猿寫出界面更好看的代碼.
- 同樣受到 HTML 的影響, Qt 還引入了 QML 來描述界面, 甚至還可以直接把一個(gè)原生的 html 頁面加載到界面上.
注意:
- 如果通過 QSS 設(shè)置的樣式和通過 C++ 代碼設(shè)置的樣式?jīng)_突, 則 QSS 優(yōu)先級(jí)更高.
2、基本語法
對(duì)于 CSS 來說, 基本的語法結(jié)構(gòu)非常簡(jiǎn)單.
選擇器 {屬性名: 屬性值;
}
QSS 沿用了這樣的設(shè)定.
選擇器 {屬性名: 屬性值;
}
其中:
- 選擇器 描述了 "哪個(gè) widget 要應(yīng)用樣式規(guī)則"。
- 屬性 則是一個(gè)鍵值對(duì), 屬性名表示要設(shè)置哪種樣式, 屬性值表示了設(shè)置的樣式的值。
例如:
QPushButton { color: red; }
?或者:
QPushButton {color: red;
}
上述代碼的含義表示, 針對(duì)界面上所有的 QPushButton , 都把文本顏色設(shè)置為 紅色?.
- 編寫 QSS 時(shí)使用單行的格式和多行的格式均可.
代碼示例: QSS 基本使用
1) 在界面上創(chuàng)建?個(gè)按鈕.
2) 編寫代碼, 設(shè)置樣式
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->pushButton->setStyleSheet("QPushButton { color : red;}");
}
3) 運(yùn)行程序, 觀察效果. 可以看到文本已經(jīng)是紅色了.
注意:
????????上述代碼中, 我們是只針對(duì)這一個(gè)按鈕通過 setStyleSheet 方法設(shè)置的樣式. 此時(shí)這個(gè)樣式僅針對(duì)該按鈕生效. 如果創(chuàng)建其他按鈕, 其他按鈕不會(huì)受到影響.
3、QSS 設(shè)置方式
3.1?指定控件樣式設(shè)置
QWidget 中包含了 setStyleSheet 方法, 可以直接設(shè)置樣式.
上述代碼我們已經(jīng)演示了上述設(shè)置方式.
另一方面, 給指定控件設(shè)置樣式之后, 該控件的子元素也會(huì)受到影響.
代碼示例: 子元素受到影響
1) 在界面上創(chuàng)建一個(gè)按鈕
2) 修改 widget.cpp, 這次我們不再給按鈕設(shè)置樣式, 而是給 Widget 設(shè)置樣式 (Widget 是 QPushButton 的父控件).
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 給 Widget 本身設(shè)置樣式this->setStyleSheet("QPushButton { color : green;}");
}
3) 運(yùn)行程序, 可以看到樣式對(duì)于子控件按鈕同樣會(huì)生效.
3.2?全局樣式設(shè)置
還可以通過 QApplication 的 setStyleSheet 方法設(shè)置整個(gè)程序的全局樣式. 全局樣式優(yōu)點(diǎn):
- 使同一個(gè)樣式針對(duì)多個(gè)控件生效, 代碼更簡(jiǎn)潔.
- 所有控件樣式內(nèi)聚在一起, 便于維護(hù)和問題排查.
代碼示例: 使用全局樣式
1) 在界面上創(chuàng)建三個(gè)按鈕.
2) 編輯 main.cpp, 設(shè)置全局樣式
int main(int argc, char *argv[])
{QApplication a(argc, argv);// 設(shè)置全局樣式a.setStyleSheet("QPushButton{ color : red; }");Widget w;w.show();return a.exec();
}
3) 運(yùn)行程序, 可以看到此時(shí)三個(gè)按鈕的顏色都設(shè)置為紅色了.
代碼示例: 樣式的層疊特性
- 如果通過全局樣式給某個(gè)控件設(shè)置了屬性1, 通過指定控件樣式給控件設(shè)置屬性2, 那么這兩個(gè)屬性都會(huì)產(chǎn)生作用.
1) 在界面上創(chuàng)建兩個(gè)按鈕
2) 編寫 main.cpp, 設(shè)置全局樣式, 把按鈕文本設(shè)置為紅色.
int main(int argc, char *argv[])
{QApplication a(argc, argv);// 設(shè)置全局樣式a.setStyleSheet("QPushButton{ color : red; }");Widget w;w.show();return a.exec();
}
3) 編寫 widget.cpp, 給第一個(gè)按鈕設(shè)置字體大小.
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 設(shè)定指定控件樣式ui->pushButton->setStyleSheet("QPushButton{ font-size : 60px; }");
}
4) 運(yùn)行程序, 可以看到, 對(duì)于第一個(gè)按鈕來說, 同時(shí)具備了顏色和字體大小樣式. 而第二個(gè)按鈕只有顏色樣式.
- 說明針對(duì)第一個(gè)按鈕, 兩種設(shè)置方式設(shè)置的樣式, 疊加起來了.
形如上述這種屬性疊加的效果, 我們稱為 "層疊性".
- CSS 全稱為 Cascading Style Sheets, 其中 Cascading 就是 "層疊性" 的意思. QSS 也繼承了這樣的設(shè)定.
實(shí)際上把 QSS 叫做 QCSS 也許更合適?些~
代碼示例: 樣式的優(yōu)先級(jí)
- 如果全局樣式, 和指定控件樣式?jīng)_突, 則指定控件樣式優(yōu)先展示.
1) 在界面上創(chuàng)建兩個(gè)按鈕
2) 編輯 main.cpp, 把全局樣式設(shè)置為紅色.
int main(int argc, char *argv[])
{QApplication a(argc, argv);// 設(shè)置全局樣式a.setStyleSheet("QPushButton{ color : red; }");Widget w;w.show();return a.exec();
}
3) 編輯 widget.cpp, 把第一個(gè)按鈕樣式設(shè)為綠色.
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 設(shè)定指定控件樣式ui->pushButton->setStyleSheet("QPushButton{ color : green; }");
}
4) 運(yùn)行程序, 觀察效果. 可以看到第一個(gè)按鈕已經(jīng)成為綠色了, 但是第二個(gè)按鈕仍然是紅色。
????????在 CSS 中也存在類似的優(yōu)先級(jí)規(guī)則. 通常來說都是 "局部" 優(yōu)先級(jí)高于 "全局" 優(yōu)先級(jí). 相當(dāng)于全局樣式先 "奠定基調(diào)" , 再通過指定控件樣式來 "特事特辦" .
3.3?從文件加載樣式表
- 上述代碼都是把樣式通過硬編碼的方式設(shè)置的. 這樣使 QSS 代碼和 C++ 代碼耦合在一起了, 并不方便代碼的維護(hù).
- 因此更好的做法是把樣式放到單獨(dú)的文件中, 然后通過讀取文件的方式來加載樣式.
代碼示例: 從文件加載全局樣式
1) 在界面上創(chuàng)建一個(gè)按鈕
2) 創(chuàng)建 resource.qrc 文件, 并設(shè)定前綴為 /?.
3) 創(chuàng)建 style.qss 文件, 并添加到 resource.qrc 中.
- style.qss 是需要程序運(yùn)行時(shí)加載的. 為了規(guī)避絕對(duì)路徑的問題, 仍然使用?qrc 的方式來組織. (即把資源文件內(nèi)容打包到 cpp 代碼中).
- Qt Creator 沒有提供創(chuàng)建 qss 文件的選項(xiàng). 咱們直接 右鍵 -> 新建文件 -> 手動(dòng)設(shè)置文件擴(kuò)展名為 qss 即可.
4) 使用?Qt Creator 打開 style.qss , 編寫內(nèi)容
QPushButton {color : red;
}
5) 修改 main.cpp, 新增一個(gè)函數(shù)用來加載樣式
QString loadQss(){QFile file(":/style.qss");// 打開文件file.open(QFile::ReadOnly);// 讀取文件內(nèi)容,雖然 readAll 返回的是 QByteArray, 但是 QString 提供了QByteArray 版本的構(gòu)造函數(shù)QString style = file.readAll();// 關(guān)閉文件file.close();return style;
}
6) 修改 main.cpp, 在 main 函數(shù)中調(diào)用上述函數(shù), 并設(shè)置樣式.
int main(int argc, char *argv[])
{QApplication a(argc, argv);// 調(diào)用上述函數(shù)加載樣式a.setStyleSheet(loadQss());Widget w;w.show();return a.exec();
}
7) 運(yùn)行程序, 可以看到樣式已經(jīng)生效了.
3.4?使用?Qt Designer 編輯樣式
????????QSS 也可以通過 Qt Designer 直接編輯, 從而起到實(shí)時(shí)預(yù)覽的效果. 同時(shí)也能避免 C++ 和 QSS 代碼的耦合.
代碼示例: 使用?Qt Designer 編輯樣式
1) 在界面上創(chuàng)建?個(gè)按鈕
2) 右鍵按鈕, 選擇 "改變樣式表"
3) 在彈出的樣式表編輯器中, 可以直接填寫樣式. 填寫完畢, 點(diǎn)擊 OK 即可.
4) 此時(shí) Qt Designer 的預(yù)覽界面就會(huì)實(shí)時(shí)顯示出樣式的變化.
5) 運(yùn)行程序, 可以看到樣式確實(shí)發(fā)生了改變.
這種方式設(shè)置樣式, 樣式內(nèi)容會(huì)被以 xml 格式記錄到 ui 文件中.
<property name="styleSheet">
<string notr="true">QPushButton { color : blue; }</string>
</property>
同時(shí)在控件的 styleSheet 屬性中也會(huì)體現(xiàn).
當(dāng)我們發(fā)現(xiàn)一個(gè)控件的樣式不符合預(yù)期的時(shí)候, 要記得排查這四個(gè)地方:
- 全局樣式
- 指定控件樣式
- qss 文件中的樣式
- ui 文件中的樣式
4、選擇器
4.1 選擇器概況
QSS 的選擇器支持以下幾種:
選擇器 | 示例 | 說明 |
全局選擇器 | * | 選擇所有的 widget. |
類型選擇器 (type selector) | QPushButton | 選擇所有的 QPushButton 和 其子類 的控件. |
類選擇器 (class selector) | .QPushButton | 選擇所有的 QPushButton 的控件. 不會(huì)選擇子類. |
ID 選擇器 | #pushButton_2 | 選擇 objectName 為 pushButton_2 的控件. |
后代選擇器 | QDialog QPushButton | 選擇 QDialog 的所有后代(子控件, 孫子控件等等) 中的 QPushButton. |
子選擇器 | QDialog > QPushButton | 選擇 QDialog 的所有子控件中的 QPushButton. |
并集選擇器 | QPushButton, QLineEdit, QComboBox | 選擇 QPushButton, QLineEdit, QComboBox 這三種控件. (即接下來的樣式會(huì)針對(duì)這三種控件都生效). |
屬性選擇器 | QPushButton[flat="false"] | 選擇所有 QPushButton 中, flat 屬性為 false 的控件. |
代碼示例: 使用類型選擇器選中子類控件
1) 在界面上創(chuàng)建一個(gè)按鈕.
2) 修改 main.cpp, 設(shè)置全局樣式
- 注意, 此處選擇器使用的是 QWidget . QPushButton 也是 QWidget 的子類, 所以會(huì)受到 QWidget 選擇器的影響.
int main(int argc, char *argv[])
{QApplication a(argc, argv);// 設(shè)置全局樣式a.setStyleSheet("QWidget { color : red; }");Widget w;w.show();return a.exec();
}
?3) 運(yùn)行程序, 可以看到按鈕的文本顏色已經(jīng)是紅色了.
5) 如果把上述樣式代碼修改為下列代碼
// 設(shè)置全局樣式
a.setStyleSheet(".QWidget { color : red; }");
此時(shí)按鈕的顏色不會(huì)發(fā)生改變. 此時(shí)只是選擇 QWidget 類, 而不會(huì)選擇 QWidget 的子類 QPushButton 了.
代碼示例: 使用?id 選擇器
1) 在界面上創(chuàng)建 3 個(gè)按鈕, objectName 為 pushButton , pushButton_2 , pushButton_3
2) 編寫 main.cpp, 設(shè)置全局樣式
- 先通過 QPushButton 設(shè)置所有的按鈕為黃色.
- 再通過 #pushButton 和 #pushButton_2 分別設(shè)置這兩個(gè)按鈕為紅色和綠色.
int main(int argc, char *argv[])
{QApplication a(argc, argv);// 設(shè)置全局樣式QString style = "";style += "QPushButton { color : yellow; }";style += "#pushButton_2 { color : red; }";style += "#pushButton_3 { color : green; }";a.setStyleSheet(style);Widget w;w.show();return a.exec();
}
?3) 執(zhí)行程序, 觀察效果
- 當(dāng)某個(gè)控件身上, 通過類型選擇器和 ID 選擇器設(shè)置了沖突的樣式時(shí), ID 選擇器樣式優(yōu)先級(jí)更高.
- 同理, 如果是其他的多種選擇器作用同一個(gè)控件時(shí)出現(xiàn)沖突的樣式, 也會(huì)涉及到優(yōu)先級(jí)問題. Qt 文檔上有具體的優(yōu)先級(jí)規(guī)則介紹 (參見?The Style Sheet Syntax 的 Conflict Resolution 章節(jié)).
- 實(shí)踐中我們可以簡(jiǎn)單的認(rèn)為, 選擇器描述的范圍越精準(zhǔn), 則優(yōu)先級(jí)越高. 一般來說, ID 選擇器優(yōu)先級(jí)是最高的.
代碼示例: 使用并集選擇器
1) 創(chuàng)建按鈕, label, 單行輸入框
2) 編寫 main.cpp, 設(shè)置全局樣式
int main(int argc, char *argv[])
{QApplication a(argc, argv);// 設(shè)置全局樣式a.setStyleSheet("QPushButton, QLabel, QLineEdit { color : red; }");Widget w;w.show();return a.exec();
}
3) 運(yùn)行程序, 可以看到這三種控件的文字顏色都設(shè)置為了紅色
????????并集選擇器是?種很好的代碼復(fù)用的方式. 很多時(shí)候我們希望界面上的多個(gè)元素風(fēng)格是統(tǒng)?的, 就可以使用并集選擇器, 把樣式屬性同時(shí)指定給多種控件.
4.2 子控件選擇器 (Sub-Controls)
有些控件內(nèi)部包含了多個(gè) "子控件" . 比如 QComboBox 的下拉后的面板, 比如 QSpinBox 的上下按鈕等.
可以通過子控件選擇器 :: , 針對(duì)上述子控件進(jìn)行樣式設(shè)置.
🌴哪些控件擁有哪些子控件, 參考文檔 Qt Style Sheets Reference 中 List of Sub-Controls 章節(jié).
代碼示例: 設(shè)置下拉框的下拉按鈕樣式
1) 在界面上創(chuàng)建?個(gè)下拉框, 并創(chuàng)建幾個(gè)選項(xiàng)
2) 創(chuàng)建 resource.qrc , 并導(dǎo)入圖片?down.png
3) 修改 main.cpp, 編寫全局樣式
- 使用子控件選擇器 QComboBox::down-arrow 選中了 QComboBox 的下拉按鈕.
- 再通過 image 屬性設(shè)置圖片.
int main(int argc, char *argv[])
{QApplication a(argc, argv);QString style = "";style += "QComboBox::down-arrow { image: url(:/down.png) }";a.setStyleSheet(style);Widget w;w.show();return a.exec();
}
?4) 執(zhí)行程序, 觀察效果
4.3?偽類選擇器 (Pseudo-States)
偽類選擇器, 是根據(jù)控件所處的某個(gè)狀態(tài)被選擇的. 例如按鈕被按下, 輸入框獲取到焦點(diǎn), 鼠標(biāo)移動(dòng)到某個(gè)控件上等.
- 當(dāng)狀態(tài)具備時(shí), 控件被選中, 樣式生效.
- 當(dāng)狀態(tài)不具備時(shí), 控件不被選中, 樣式失效.
使用?: 的方式定義偽類選擇器.
常用的偽類選擇器:
偽類選擇器 | 說明 |
:hover | 鼠標(biāo)放到控件上 |
:pressed | 鼠標(biāo)左鍵按下時(shí) |
:focus | 獲取輸入焦點(diǎn)時(shí) |
:enabled | 元素處于可用狀態(tài)時(shí) |
:checked | 被勾選時(shí) |
:read-only | 元素為只讀狀態(tài)時(shí) |
這些狀態(tài)可以使用?! 來取反. 比如 :!hover 就是鼠標(biāo)離開控件時(shí), :!pressed 就是鼠標(biāo)松開時(shí), 等等.
更多偽類選擇器的詳細(xì)情況, 參考 Qt Style Sheets Reference 的 Pseudo-States 章節(jié).
?代碼示例: 設(shè)置按鈕的偽類樣式.
1) 在界面上創(chuàng)建?個(gè)按鈕
2) 編寫 main.cpp, 創(chuàng)建全局樣式
int main(int argc, char *argv[])
{QApplication a(argc, argv);QString style = "QPushButton { color : red; }";style += "QPushButton:hover { color : green; }";style += "QPushButton:pressed { color : blue; }";a.setStyleSheet(style);Widget w;w.show();return a.exec();
}
3) 運(yùn)行程序, 可以看到, 默認(rèn)情況下按鈕文字是紅色, 鼠標(biāo)移動(dòng)上去是綠色, 鼠標(biāo)按下按鈕是藍(lán)色.