前端網(wǎng)站效果有哪些中國十大企業(yè)管理培訓(xùn)機(jī)構(gòu)
前言:
之前寫過一些關(guān)于qss的文章:
【Qt樣式(qss)-1】手冊(cè)小結(jié)(附例:軟件深色模式)_深藍(lán)色主題qss表-CSDN博客
【Qt樣式(qss)-2】使用小結(jié)(軟件換膚,比如暗黑模式)_qt 黑色qss_大橘的博客-CSDN博客
【Qt樣式(qss)-3】幾套配色方案_qt界面配色_大橘的博客-CSDN博客
【Qt樣式(qss)-4】應(yīng)用到QMdiArea不生效的解決_qt樣式不生效_大橘的博客-CSDN博客
主要是記錄一下備忘。
回顧:
先說一下我對(duì)層疊樣式的理解(qss/css),各位看看有無錯(cuò)誤:
一般情況下樣式優(yōu)先,除非畫筆強(qiáng)制。
發(fā)生嵌套時(shí),局部優(yōu)先。
有先后順序時(shí),后面的優(yōu)先,因?yàn)楦采w了前面的。就好像給一個(gè)變量賦值,肯定最后一次有效。
問題:
最近遇到一個(gè)問題,簡單如下圖所示,畫一個(gè)窗體,上面放QTabWidget,頁面里面放若干QLabel,和QPushButton。然后統(tǒng)一在主窗體構(gòu)造中設(shè)置qss。
代碼:
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);this->setStyleSheet("* { background-color: red; }");this->setStyleSheet("");this->setStyleSheet("* { background-color: none; }");
// this->setStyleSheet("* { background-color: 0; }");
// this->setStyleSheet("* { background-color: transparent; }");ui->label->clear();ui->label->setPixmap(QPixmap("D:/_nx/_zonglin/ImgDisplay/_imgdisplay_images/_common/back.png"));ui->label->lower();
}MainWindow::~MainWindow()
{delete ui;
}
按上面這樣,按理說非常簡單,不能有意外。先預(yù)測一下運(yùn)行效果,理論上以下三句:
? ? this->setStyleSheet("* { background-color: red; }");this->setStyleSheet("");this->setStyleSheet("* { background-color: none; }");
應(yīng)該相當(dāng)于啥也沒寫,因?yàn)槟J(rèn)這些組件就是透明的。實(shí)際效果也確實(shí)如下:
首先是否有人質(zhì)疑,為什么background-color的值不是寫transparent?我試過,是這樣的:
意外吧?這個(gè)我不想深究了。重要的是下面。
在設(shè)計(jì)器中,隨便把某個(gè)子控件設(shè)置個(gè)qss,不管是代碼還是設(shè)計(jì)器當(dāng)中,一樣的。比如這樣:
我是在設(shè)計(jì)器中把最后那個(gè)QLabel更改了樣式表,background-color: yellow;
按照構(gòu)造順序,理論上最后主窗體的三個(gè)setStyleSheet應(yīng)該覆蓋了這個(gè)yellow,不是層疊樣式嗎?運(yùn)行一下是這樣的:
這是覆蓋哪去了?這個(gè)QTabWidget就像一個(gè)結(jié)界一樣。首先,主窗體setupUi當(dāng)中,分別調(diào)用了子控件的構(gòu)造,也會(huì)加載qss,所以先顯示為黃色。
主窗體中,第一次setStyleSheet,QTabWidget中的按鈕都跟著成了紅色,它生效了。
this->setStyleSheet("* { background-color: red; }");
第二次設(shè)置qss為空,是為了先清空一下以防異常。
this->setStyleSheet("");
第三次設(shè)置背景透明,按說應(yīng)該一切恢復(fù),但它成了結(jié)界??
this->setStyleSheet("* { background-color: none; }");
然后為了解決就各種嘗試,不行。幾乎打破了我對(duì)qss的所有認(rèn)知。
直到最后發(fā)現(xiàn),去掉之前設(shè)置的yellow,一切正常了。
思考:
這個(gè)問題對(duì)于我來說不需要深究,但茶余飯后跟同事聊天時(shí),突然有個(gè)想法。
qss局部優(yōu)先是沒問題的,如果沒有設(shè)置局部,肯定全局渲染。如果設(shè)置了局部,估計(jì)是有個(gè)標(biāo)記變量,這個(gè)變量會(huì)更改規(guī)則,全局渲染時(shí)它會(huì)繞開已經(jīng)渲染的局部。
所以上面代碼,當(dāng)我不指定那個(gè)label是黃色時(shí),全局有效沒有問題。當(dāng)指定了某個(gè)label是黃色時(shí),我猜是這樣:
首先啟用了局部優(yōu)先規(guī)則。
第一次全局渲染成紅色時(shí),因?yàn)檫@時(shí)候除了黃色label,其它都沒有渲染,所以全局被渲染成紅色。
之后再全局渲染時(shí),因?yàn)橹耙呀?jīng)都成了紅色,相當(dāng)于這些局部都已經(jīng)有了紅色渲染,所以就被繞開了,因此只有外圍有效。
結(jié)論:
由于不想投入太多精力,所以目前為止我沒有去找有力的依據(jù)。目前上述只能歸結(jié)為qss局部渲染機(jī)制問題。亦即:
一旦局部組件被顯式地單獨(dú)渲染,就會(huì)啟用局部優(yōu)先規(guī)則。
一旦啟用局部有限規(guī)則,全局渲染時(shí)就會(huì)繞開已經(jīng)被渲染的局部組件。
但其實(shí),我覺得更好的方式是:它應(yīng)該去只繞開顯式局部渲染的組件,而不是有渲染就繞開。