Qt中設(shè)置Widget背景顏色及圖片的注意事項
Qt中設(shè)置Widget背景顏色及圖片的注意事項是本文要介紹的內(nèi)容,不多說,先來看內(nèi)容。在Qt中設(shè)置widget背景顏色或者圖片方法很多種:重寫paintEvent() , 調(diào)色板QPalette , 樣式表setStyleSheet等等。 測試環(huán)境:Qt4.5.0 + vc2005
但是各種方法都有其注意事項,如果不注意則很容易陷入麻煩中。
1、setStyleSheet()
這個函數(shù)我一直很喜歡使用,因為只要寫一句就可以實現(xiàn)效果,比其他方法都簡單,但是其卻有一個很值得注意的地方,也就是這個地方讓我大吃苦頭。
亦即:
(1)該函數(shù)只能用于設(shè)置有父窗口的子窗口的背景!如果一個窗口沒有子窗口,則無法使用該函數(shù)來設(shè)置背景顏色或圖片!!
(2)同時:對于一個父窗口而言:如果我們用setStyleShette設(shè)置了其樣式,而對于其子窗口:如果沒有用同樣的函數(shù)來設(shè)置的話, 則其子窗口的樣式和其父窗口完全一致,亦即:其集成了自己父窗口的樣式!
(3)延伸:對頂層窗口(沒有父窗口),其有若干個子窗口,則當(dāng)我們用setStyleShette來設(shè)置這個頂層窗口的樣式后,依據(jù)①可知:該父窗口本身沒有任何變化,亦即設(shè)置沒有生效;而其子窗口:只要子窗口本身沒有用setStyleShette來設(shè)置自己的樣式表,則其就是用的自己父窗口的樣式表?。?/p>
例如:
主窗口(沒有父類)為MainWin
- MainWin::MainWin()
- {
- this->setStyleSheet("background-image:url(:/bmp/IMG_0345.JPG)");
- iButton = new QPushButton(this);
- iLabel = new QLabel(iButton);
- }
運行一下,效果如下:
亦即:雖然我們設(shè)置的是頂層的父窗口,但是該樣式卻是在其子窗口中生效,而頂層父窗口沒有任何變化! 這驗證了①。
修改一下上例代碼:
- MainWin::MainWin()
- {
- this->setStyleSheet("background-image:url(:/bmp/IMG_0345.JPG)");
- iButton = new QPushButton(this);
- iLabel = new QLabel(iButton);
- iLabel->setStyleSheet("background-image:url(:/bmp/1257253475842.jpg)");
- }
則運行效果如下:
可見:子窗口只有調(diào)用setStyleSheet()設(shè)置了自己的樣式后才可以隔斷父窗口的樣式,否則其將是用父窗口的樣式。
再修改一下代碼:
- MainWin::MainWin()
- {
- iButton = new QPushButton(this);
- iButton ->setStyleSheet("background-image:url(:/bmp/IMG_0345.JPG)");
- iLabel = new QLabel(iButton);
- }
運行 一下,效果如下
可見:設(shè)置有父窗口的子窗口時:setStyleSheet()一定生效!?。?/p>
#p#
后來我又思考了一個問題,那就是:對于頂層父窗口,如果我 setStyleSheet()設(shè)置了樣式表,而對其子窗口,我用其他方法,比如用QPalette調(diào)色板來設(shè)置背景圖片/顏色,這時子窗口的背景到底是由繼承自父窗口的樣式表決定呢還是由子窗口本身的QPalette調(diào)色板決定呢?
再次修改代碼:
- MainWin::MainWin()
- {
- this->setStyleSheet("background-image:url(:/bmp/IMG_0345.JPG)");
- iButton = new QPushButton(this);
- iLabel = new QLabel(iButton);
- QPalette palette;
- palette.setBrush(iLabel->backgroundRole(),QBrush(QImage(":/bmp/1257253475842.jpg")));
- iLabel->setPalette(palette);
- iLabel->setAutoFillBackground(true);
- }
此段代碼中我用QPalette來設(shè)置子窗口的背景圖片,看下到底是樣式表還是調(diào)色板生效,效果如下:
由此 可見:一旦頂層窗口設(shè)置了樣式表,則其子窗口無論用什么方法來設(shè)置背景,都會不生效!??!
那如果不是頂層窗口而僅僅是一般窗口設(shè)置了樣式表呢?再次修改代碼:
- MainWin::MainWin()
- {
- iButton = new QPushButton(this);
- iButton ->setStyleSheet("background-image:url(:/bmp/IMG_0345.JPG)");
- iLabel = new QLabel(iButton);
- QPalette palette;
- palette.setBrush(iLabel->backgroundRole(),QBrush(QImage(":/bmp/1257253475842.jpg")));
- iLabel->setPalette(palette);
- iLabel->setAutoFillBackground(true);
- }
運行 效果同上,這說明:不管是頂層窗口還是一般窗口,只要用setStyleSheet設(shè)置了樣式表,則其子窗口用其它方式設(shè)置背景顏色/圖片均不生效,只能用同樣方式setStyleSheet來設(shè)置更改?。。?/p>
為了驗證上邊的結(jié)論,再次修改代碼:
- MainWin::MainWin()
- iButton = new QPushButton(this);
- iLabel = new QLabel(iButton);
- QPalette palette;
- palette.setBrush(iLabel->backgroundRole(),QBrush(QImage(":/bmp/1257253475842.jpg")));
- iLabel->setPalette(palette);
- iLabel->setAutoFillBackground(true);
- }
運行一下:
Qt中設(shè)置Widget背景顏色及圖片的注意事項
此時調(diào)色板才生效,這也間接證明了上述結(jié)論。
總結(jié):
1、不要在頂層窗口(無父類的窗口)中使用setStyleSheet() ,否則其一父窗口的背景不會改變,其次其子窗口的背景設(shè)置方法變得局限唯一,不能再使用其它方法!
2、如果一個一般窗口(非頂層窗口)還有子窗口,那最好不要使用setStyleSheet()來設(shè)置其背景顏色,因為雖然此時該窗口的背景設(shè)置是生效的,但是其子窗口的背景設(shè)置也變得局限唯一,只能使用setStyleSheet,而不能使用其它方法! 當(dāng)然:你如果就是只想使用這種方法,那也完全可以??!
說白了就是:不要再MainWindow中使用setStyleSheet()!
而上邊之所以強調(diào)拓寬子窗口設(shè)置背景的方法范圍,這是因為:如果只能用setStyleSheet樣式表來設(shè)置背景圖片的話,該圖片是無法縮放的,如果其大小與widget窗口大小不相符,則我們無法用程序來實現(xiàn)圖片的縮放,除非我們直接處理圖片使其大小與widget窗口相符; 而如果不局限于用setStyleSheet樣式表來設(shè)置的話,我們可以選擇用QPalette調(diào)色版,其內(nèi)部setBrush()之前,我們完全可以先對圖片進(jìn)行scale縮放再刷到窗口上,這樣就避免直接去處理圖片,靈活性強一點!
注意:該文只針對QWidget體系,并不適用用QGraphicsWidget體系!關(guān)于這兩種體系之間的區(qū)分,詳見文章 http://blog.csdn.net/NRC_DouNingBo/archive/2010/05/09/5571149.aspx
小結(jié):Qt中設(shè)置Widget背景顏色及圖片的注意事項的內(nèi)容介紹完了,希望本文對你有所幫助!