Qt之qss檔案編寫
轉自:
一 詳細參考
http://doc.trolltech.com/4.6/stylesheet-reference.html
二 Qt Stylesheets Tutorial
Stylesheets add spicy flavor to your boring Qt GUIs.
For a long time, Qt has allowed you to decorate your GUIs with CSS’ish style sheets. Inspired by the web, stylesheets are a great way to stylize your Qt GUI, but it seems that few people use them. In this tutorial, we’ll create an example dialog in Qt using Designer and stylesheets. This tutorial assumes that you can get around in Qt Designer, and that you understand a little about Qt layouts.
Step 1 Create a new empty form, named MyLoginForm.
Step 2 Add a QFrame to your form, and apply a vertical layout to your form (any layout will work actually: vertical, horizontal or grid). Give your form about 30 pixels of layout margin around its perimeter. Name the QFrame “mainFrame”. When dealing with stylesheets, it’s convenient to name your widgets in Designer, even if you don’t plan to use them by name in your code (we won’t be writing any code besides CSS in this tutorial).
Step 3 In Designer’s object inspector, right-click on the top-level entry in the tree (called “MyLoginForm”), and select “Change styleSheet…” from the menu. You’ll get a little editor dialog like this:
This is where we specify the style sheet for our form. You can put a style sheet on any widget in your form, but I prefer to do all my stylizing at the parent widget (“MyLoginForm” in this case). I prefer to do it this way because you’ll never have to go hunting to find your style sheet — it’s all in one place in your form. Since stylesheets cascade down to the child widgets, you can stylize any widget in your form from this point.
Side note: “CSS” stands for “Cascading Style Sheets”
Let’s type in some CSS into the style sheet editor, like this:
#MyLoginForm {
background: gray;
}
#mainFrame {
border: 3px solid gray;
border-radius: 40px;
background: white;
}
After clicking OK on the editor dialog, you should see this:
If your’s doesn’t look like this, you may have forgotten to change the parent widget’s name to “MyLoginForm” or the QFrame’s name to “mainFrame” (yes, capitalization does matter — Qt stylesheets are case sensitive). Or you may have mistyped something into the CSS dialog.
One cool feature is that you get to preview the style changes right as you make them. You don’t have to compile, save, or run anything. Designer does a very good job of showing your stylesheet changes live (WYSIWYG for you old-timers).
Let me explain what we just did. In CSS, a pound sign, ‘#’, in front of a name is how we stylize an individual widget by that name. In our example, #MyLoginForm identifies the parent widget (i.e., the background area). All we did there is give it a gray background with background: gray;.
For #mainFrame, we gave it a thick gray border, a white background, and rounded corners.
Step 4 Let’s add some widgets to make this dialog actually do something. Drag and drop a pair of QLineEdits, QLabels, and a single QPushButton on the form inside “mainFrame” and arrange them roughly like this:
Step 5 Now apply a grid layout to “mainFrame”. Just select “mainFrame” by clicking on it (taking care not to accidentally select one of the QLineEdits or QLabels instead). Then click the grid layout button in Designer’s toolbar (optionally, you can go to the menu bar and click “Form” -> “Lay Out in a Grid”, or just press Ctrl+5 for you keyboard hackers).
Then give your layout some margin. I used 50 pixels of margin and 15 pixels for both vertical and horizontal spacing.
This is what you should have now:
Step 6 Let’s stylize those boring QPushButton and QLineEdits. Add this to the style sheet for MyLoginForm:
QLineEdit {
padding: 1px;
border-style: solid;
border: 2px solid gray;
border-radius: 8px;
}
QPushButton {
color: white;
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #88d, stop: 0.1 #99e, stop: 0.49 #77c, stop: 0.5 #66b, stop: 1 #77c);
border-width: 1px;
border-color: #339;
border-style: solid;
border-radius: 7;
padding: 3px;
font-size: 10px;
padding-left: 5px;
padding-right: 5px;
min-width: 50px;
max-width: 50px;
min-height: 13px;
max-height: 13px;
}
Notice that we didn’t use the pound sign this time. When you omit the pound sign, you are specifying a “class” of widgets to stylize instead of a single widget by name. So in this case, we stylized all widgets of type “QLineEdit” and “QPushButton” (and any widget that may inherit from those widgets too).
That gives the QPushButton a cool gradient look and rounds the edges of the QLineEdits, like this:
Step 7 Now let’s make that boring white background a gradient instead. Replace the “background: white;” line in the “#mainFrame” section with this instead:
background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eef, stop: 1 #ccf);
Now you should see this:
Step 8 Since stylizing is all about detail and little tweaks, let’s mess a bit with the label font and the background color by changing the background for “#MyLoginForm” to “background: white”, and adding this:
QLabel {
font-weight: bold;
font-size: 15px;
}
Now we get our finished product:
Isn’t it great how much you can do in Designer with style sheets? There are even things you can do with style sheets that can’t be done without writing lots of yucky C++ code. For example, you can change the border style of just a single side of a QFrame.
Oddities
There is one gotcha to keep in mind when using style sheets: Once you use a style sheet, it will often override other properties, like the “font” property or the “frameStyle” property. Keep this in mind when Designer changes properties you didn’t expect.
The other oddity with style sheets is that there’s no way to “include” external style sheet files into your widget’s style sheet. This means that you can’t have a common style sheet that gets applied to your entire application like you can in the web. I have a Qt patch that allows you to do this, but so far the Trolls haven’t done anything with it (to my knowledge). This would be immensely useful.
Cross Platform Note
A style sheet tutorial wouldn’t be complete without a comment on cross-platform issues. The dialog we just designed will look exactly the same on Linux, Windows, and Mac OS X because we stylized it so aggressively. If you want your widgets to look native on
each platform, you should generally use style sheets sparingly, but if your goal is to have a consistent look across all platforms, style sheets are your best friend.
Conclusion
Now that I have discovered the power of style sheets in Qt, I use them whenever possible. What cool things have you done with Qt style sheets?
三 通過Qt4.2樣式表定製程式外觀
目錄
1. 何為Qt樣式表
2. 樣式表語法基礎
3. 方箱模型
4. 前景與背景
5. 建立可縮放樣式
6. 控制大小
7. 處理偽狀態
8. 使用子部件定義微觀樣式
8.1. 相對定位
8.2. 絕對定位
摘要
由於Qt樣式表的引入,定製Qt部件的外觀樣式變得非常簡單。 無論你是想僅僅修改一個現有部件的外觀,還是想從零開始設計一套全新的介面風格, 現在都有了一種新的方法而不必再去繼承並實現一個QStyle的子類。
1. 何為Qt樣式表
Qt樣式表的思想很大程度上是來自於HTML的層疊式樣式表(CSS), 通過呼叫QWidget::setStyleSheet()或QApplication::setStyleSheet(), 你可以為一個獨立的子部件、整個視窗,甚至是整個個應用程式指定一個樣式表。
樣式表是通過QStyle的一個叫做QStyleSheetStyle的特殊子類來實現的。 這個特殊的子類實際上是其他的系統特定風格類的包裹類, 它會把通過樣式表指定的自定義外觀風格應用在底層的系統特定風格之上。
Qt 4.2包含了一個叫做stylesheet的例子來幫助你學習樣式表, 這個例子自帶了兩個樣式:Coffee和Pagefold。
上面的Coffee風格自定義了push button、frames和tooltip,但使用了下層的風格 (例如這裡是Windows XP風格)來繪製checkbox,combobox和radio button。
Pagefold風格完全重新定義了對話方塊中使用的所有控制元件的外觀,從而實現了一種獨特的,平臺無關的外觀。
2. 樣式表語法基礎
Qt樣式表與CSS的語法規則幾乎完全相同,如果你已經瞭解了CSS,完全可以跳過本節。
一個樣式表由一系列的樣式規則構成。每個樣式規則都有著下面的形式:
selector { attribute: value }
選擇器(selector)部分通常是一個類名(例如QComboBox),當然也還有其他的語法形式。
屬性(attribute)部分是一個樣式表屬性的名字,值(value)部分是賦給該屬性的值。
為了使用方便,我們還可以使用一種簡化形式:
selector1, selector2, ..., selectorM {
attribute1: value1;
attribute2: value2;
...
attributeN: valueN;
}
這種簡化形式可以同時為與M個選擇器相匹配的部件設定N種屬性。例如:
QCheckBox, QComboBox, QSpinBox {
color: red;
background-color: white;
font: bold;
}
這個規則設定了所有的QCheckBox、QComboBox和QSpinBox的前景色、背景色和字型。
線上文件列出了每種部件支援的所有屬性。在本文中,我們只使用最常見的幾種通用屬性。
3. 方箱模型
在樣式表中,每個部件都被看作是一個由四個同心相似的矩形組成的箱體:空白(margin)、邊框(border)、填充(padding)和內容(content)。對於一個平面部件——例如一個空白、邊框和填充都是0畫素的部件——而言,這四個矩形是完全重合的。
空白區域位於邊框外,並且總是透明的。邊框為部件提供了四周的框架,其border-style屬性可以設定為一些內建的框架風格,如inset、outset、solid和ridge。填充在邊框和內容區域之間提供了空白間隔。
4. 前景與背景
部件的前景色用於繪製上面的文字,可以通過color屬性指定。背景色用於繪製部件的填充矩形,可以通過background-color屬性指定。
背景圖片使用background-image屬性定義,它用於繪製由background-origin指定的矩形區域(空白、邊框、填充或內容)。背景圖片在矩形區域內的對齊和平鋪方式可以通過background-position和background-repeat屬性指定。
如果指定的背景圖片具有alpha通道(即有半透明效果),通過background-color指定的顏色將會透過透明區域。這一功能可以使背景圖片在多種環境下重複利用。
該例子中使用的樣式表如下所示:
QFrame {
margin: 10px;
border: 2px solid green;
padding: 20px;
background-color: gray;
background-image: url(qt.png);
background-position: top right;
background-origin: content;
background-repeat: none;
}
在這個例子中,QFrame四周的空白、邊框和填充值都是一樣的。實際上margin屬性可以在上下左右四個方向分別指定我們需要的不同值,例如:
QFrame {
margin: 14px 18px 20px 18px;
}
同時,我們也可以分別指定margin-top、margin-right、margin-bottom、margin-left四個屬性。
QFrame {
margin-top: 14px;
margin-right: 18px;
margin-bottom: 20px;
margin-left: 18px;
}
雖然目前我們僅僅使用了QFrame作為例子,但是我們也可以同樣的將這些屬性應用於任何一個支援方箱模型的Qt部件,例如:QCheckBox、 QLabel、QLineEdit、QListView、QMenu、QPushButton、QTextEdit、和QToolTip。
5. 建立可縮放樣式
在預設情況下,通過background-image指定的背景圖片會自動重複平鋪,以覆蓋部件的整個填充矩形(即邊框裡面的那個區域)。如果我們想建立能夠隨著部件大小自動縮放而不是平鋪的背景,我們需要設定一種稱之為“邊框圖片”的東東。
“邊框圖片”可以通過border-image屬性指定,它同時提供了部件的背景和邊框。一個“邊框圖片”被分為九個部分(九宮格),有點向tic-tac-toe遊戲的棋盤。
當一個部件的邊框被填充時,四角的格子通常不會發生變化,而其餘的五個格子則可能被拉伸或平鋪以填充可用空間。
當指定一個“邊框圖片”時,除了圖片本身,我們還必須指定用來分割九宮格的四條分割線。同時我們還必須指定非邊角的格子是應該平鋪還是拉伸,以及邊框的寬度(用來確定邊角格子的大小,防止邊角被縮放變形)。
例如,下面的樣式表定義了上圖中的button:
QPushButton {
border-width: 4px;
border-image: url(button.png) 4 4 4 4 stretch stretch;
}
另外,“邊框圖片”還應該含有alpha通道,以使背景能夠在邊角處露出來。
6. 控制大小
min-width和min-height兩個屬性可以用來指定一個部件的內容區域的最小大小。這兩個值將影響部件的minimumSizeHint(),並在佈局時被考慮。
例如:
QPushButton {
min-width: 68px;
min-height: 28px;
}
如果該屬性沒有被指定,最小大小將從部件的內容區域和當前樣式中繼承。
7. 處理偽狀態
部件的外觀可以按照使用者介面元素狀態的不同來分別定義,這在樣式表中被稱為“偽狀態”。例如,如果我們想在一個push button在被按下的時候具有sunken的外觀,我們可以指定一個叫做 :pressed 的偽狀態。
QPushButton {
border: 2px outset green;
background: gray;
}
QPushButton:pressed {
border-style: inset;
}
下面是可用的偽狀態列表:
表 1. 偽狀態列表
偽狀態 描述
:checked button部件被選中
:disabled 部件被禁用
:enabled 部件被啟用
:focus 部件獲得焦點
:hover 滑鼠位於部件上
:indeterminate checkbox或radiobutton被部分選中
:off 部件可以切換,且處於off狀態
:on 部件可以切換,且處於on狀態
:pressed 部件被滑鼠按下
:unchecked button部件未被選中
8. 使用子部件定義微觀樣式
許多部件都包含有子元素,這些元素可以稱為“子部件”。Spin box的上下箭頭就是子部件最好的例子。
子部件可以通過::來指定,例如QDateTimeEdit::up-button。定義子部件的樣式與定義部件非常相似,它們遵循前面提到的方箱模型(即它們可以擁有自己的邊框、背景等),並且也可以和偽狀態聯合使用(例如QSpinBox::up-button:hover)。
下表列出了可用的子部件型別:
表 2. 子部件列表
子部件 描述
::down-arrow combo box或spin box的下拉箭頭
::down-button spin box的向下按鈕
::drop-down combo box的下拉箭頭
::indicator checkbox、radio button或可選擇group box的指示器
::item menu、menu bar或status bar的子專案
::menu-indicator push button的選單指示器
::title group box的標題
::up-arrow spin box的向上箭頭
::up-button spin box的向上按鈕
通過指定subcontrol-position和subcontrol-origin屬性,子部件可以被放置在部件箱體內的任何位置。並且,子部件的位置還可以使用相對或絕對的方式進一步的調整。具體選擇何種調整方式取決於子部件具有固定的大小,還是會隨著父部件而變化。
8.1. 相對定位
相對定位適合於子部件具有固定大小的情形(通過width和height指定子部件大小)。使用這種方式,子部件可以以相對於subcontrol-position和 subcontrol-origin屬性定義的原始位置進行移動調整。使用left屬性可以把子部件向右移,top屬性可以把子部件向左移。
例如:
QPushButton::menu-indicator {
image: url(menu_indicator.png);
width: 13px;
height: 13px;
subcontrol-origin: padding;
subcontrol-position: bottom right;
}
當按下按鈕時,我們可以把選單指示器從原來的位置向右下方移動幾個畫素來模擬按鈕按下的狀態。
QPushButton::menu-indicator:pressed {
position: relative;
top: 2px;
left: 2px;
}
8.2. 絕對定位
絕對定位適合於子部件的位置隨父部件的變化而變的情形。與前面的例子相同,subcontrol-origin定義了父部件箱體的參考矩形。子部件的矩形區域則可以隨後通過相對於這個參考矩形四邊的偏移量來定義。
QPushButton::menu-indicator {
border: 2px solid red;
subcontrol-origin: padding;
position: absolute;
top: 2px;
right: 2px;
bottom: 2px;
left: 40px;
}
對於寬度或高度固定的子部件,subcontrol-position被用來說明其在subcontrol-origin指定矩形內的對其方式:
QPushButton::menu-indicator {
image: url(menu_indicator.png);
width: 13px;
subcontrol-origin: padding;
subcontrol-position: bottom right;
position: absolute;
top: 2px;
bottom: 2px;
right: 2px;
}
四 http://doc.qt.nokia.com/4.6/stylesheet-examples.html#customizing-qdockwidget
五 樣式表使用
雖然Qt現在還不是特別完善,但它的跨平臺性,介面重用性,已經表現出比mfc更強的、更好的效能,昨天寫了qss樣式表demo,但是在書上對樣式表的使用,並不詳細,初學者可能會遇到一些問題,今天對照官方程式碼,終於調通,簡單記錄如下:
1、建立文字檔案,寫入樣式表內容,更改檔案字尾名為qss;
2、在工程中新建資原始檔*.qrc,將qss檔案加入資原始檔qrc中,此處注意prefix最好為"/",否則在呼叫qss檔案時會找不到檔案;
3、通過傳入路徑\檔名的方式建立一個QFile物件,以readonly的方式開啟,然後readAll,最後qApp->setStyleSheet就可以使qss生效。
樣式表的方式可以很方便的完成簡單的貼圖工作,而且效果也不錯,簡化了我以前在mfc上為了貼圖,不得不重寫控制元件類個工作,也使得美工可以很方便的修改生成的程式的顏色。
當今年4月初的時候,NOKIA收購了Qt,並推出了Qt4.2,當時並沒有太注意,而當mfc開發的介面不能滿足我的時候,我才去研究這個新的技術。
Qt很爽,因為是C++語言,所以看起來很快,預計在明年一月底,我就可以完全掌握,而且也因為是C++程式碼級跨平臺,所以也獲得了很高的執行效率。而它生成控制元件的方式則比mfc上的資原始檔好得多,mfc中的窗體資源全部在一個.src檔案中,不利於重用,而Qt中每個窗體擁有自己的資原始檔,並且和窗體類是分開的,方便了重用。從此,我不在被侷限於windows平臺。
我會研究一下如何在應用程式中完成widget部件的使用,因為那種透明、隨意拖拽的自定義部件必將是下一代UI主流。
QApplication app(...);
QFile qss("stylesheet.qss");
qss.open(QFile::ReadOnly);
app.setStyleSheet(qss.readAll());
qss.close();
六 http://thesmithfam.org/blog/2009/09/10/qt-stylesheets-tutorial/
七 補記:對一個窗體或應用設定樣式表,樣式表的內容如果不特別制定屬於那個或那類元件,其內容會應用到所有元件上;前一個的樣式,會被後來的樣式所覆蓋。
相關文章
- (轉)Qt之qss檔案編寫QT
- QT之qss教程-QSpinBoxQT
- QT新增樣式表QSS/CSS檔案後不起作用QTCSS
- 【QT】QSS美化——Buttons篇QT
- QSS總結以及最近做的Qt專案QT
- QT皮膚(QSS)程式設計QT程式設計
- Docker | dockerfile 檔案編寫Docker
- 如何編寫html檔案HTML
- 配置檔案的編寫
- qt-5.6.0 移植之qt檔案系統的建立QT
- 日常積累——彙編檔案編寫
- 如何編寫 Typescript 宣告檔案TypeScript
- 【ROS教程】編寫launch檔案ROS
- Qt學習之路(57): 文字檔案讀寫薦QT
- Qt 介面美化教程 QSS QML Qt自繪方式優缺點對比QT
- 編寫第一個Qt程式QT
- 檔案操作之按照行讀寫檔案
- C++ hpp檔案的編寫C++
- 編寫一個檔案補丁
- Qt專案檔案.proQT
- qt 寫入xml檔案例項QTXML
- 如何編寫proto型別的檔案型別
- RPM 的 spec 檔案如何編寫
- 如何編寫 RPM 的 spec 檔案
- 建立程式編寫demo.py檔案
- 如何編寫 Dockerfile 檔案建立 Docker 映象Docker
- 一篇文章快速搞懂Qt檔案讀寫操作QT
- QT從入門到入土(三)——檔案的讀寫操作QT
- windows下如何使用QT編寫dll程式WindowsQT
- 用QT在Windows下編寫dll程式QTWindows
- QT6編寫外部庫並呼叫QT
- numpy陣列之讀寫檔案陣列
- python之 檔案讀與寫Python
- Qt Creator 引入第三方庫如何寫PRI檔案QT
- 目錄與檔案屬性:編寫ls
- 全方位解讀DLL檔案—編寫DLL
- .yaml引數檔案的編寫和使用YAML
- 手把手編寫檔案伺服器伺服器