source: trunk/doc/src/styles.qdoc@ 551

Last change on this file since 551 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 78.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \page style-reference.html
44
45 \title Implementing Styles and Style Aware Widgets
46 \ingroup architecture
47 \brief An overview of styles and the styling of widgets.
48
49 \tableofcontents
50
51 \section1 Introduction
52
53 Styles (classes that inherit QStyle) draw on behalf of widgets
54 and encapsulate the look and feel of a GUI. Several styles are
55 built into Qt (e.g., windows style and motif style). Other styles are
56 only available on specific platforms (such as the windows XP style).
57 Custom styles are made available as plugins or by creating an
58 instance of the style class in an application and setting it with
59 QApplication::setStyle().
60
61 To implement a new style, you inherit one of Qt's existing styles
62 - the one most resembling the style you want to create - and
63 reimplement a few virtual functions. This process is somewhat
64 involved, and we therefore provide this overview. We give a
65 step-by-step walkthrough of how to style individual Qt widgets.
66 We will examine the QStyle virtual functions, member variables,
67 and enumerations.
68
69 The part of this document that does not concern the styling of
70 individual widgets is meant to be read sequentially because later
71 sections tend to depend on earlier ones. The description of the
72 widgets can be used for reference while implementing a style.
73 However, you may need to consult the Qt source code in some cases.
74 The sequence in the styling process should become clear after
75 reading this document, which will aid you in locating relevant code.
76
77 To develop style aware widgets (i.e., widgets that conform to
78 the style in which they are drawn), you need to draw them using the
79 current style. This document shows how widgets draw themselves
80 and which possibilities the style gives them.
81
82 \section1 The QStyle implementation
83
84 The API of QStyle contains functions that draw the widgets, static
85 helper functions to do common and difficult tasks (e.g.,
86 calculating the position of slider handles) and functions to do
87 the various calculations necessary while drawing (e.g., for the
88 widgets to calculate their size hints). The style also help some
89 widgets with the layout of their contents. In addition, it creates
90 a QPalette that contains \l{QBrush}es to draw with.
91
92 QStyle draws graphical elements; an element is a widget or a
93 widget part like a push button bevel, a window frame, or a scroll
94 bar. When a widget asks a style to draw an element, it provides the
95 style with a style option, which is a class that contains the
96 information necessary for drawing.
97
98 We will in the course of this section look at the style elements,
99 the style options, and the functions of QStyle. Finally, we describe
100 how the palette is used.
101
102 Items in item views is drawn by \l{Delegate Classes}{delegates} in
103 Qt. The item view headers are still drawn by the style. Qt's
104 default delegate, QStyledItemDelegate, draws its items partially
105 through the current style; it draws the check box indicators and
106 calculate bounding rectangles for the elements of which the item
107 consists. In this document, we only describe how to implement a
108 QStyle subclass. If you wish to add support for other datatypes
109 than those supported by the QStyledItemDelegate, you need to
110 implement a custom delegate. Note that delegates must be set
111 programmatically for each individual widget (i.e., default
112 delegates cannot be provided as plugins).
113
114 \section2 The Style Elements
115
116 A style element is a graphical part of a GUI. A widget consists
117 of a hierarchy (or tree) of style elements. For instance, when a
118 style receives a request to draw a push button (from QPushButton,
119 for example), it draws a label (text and icon), a button bevel,
120 and a focus frame. The button bevel, in turn, consists of a frame
121 around the bevel and two other elements, which we will look at
122 later. Below is a conceptual illustration of the push button
123 element tree. We will see the actual tree for QPushButton when we
124 go through the individual widgets.
125
126 \image javastyle/conceptualpushbuttontree.png
127
128 Widgets are not necessarily drawn by asking the style to draw
129 only one element. Widgets can make several calls to the style to
130 draw different elements. An example is QTabWidget, which draws its
131 tabs and frame individually.
132
133 There are three element types: primitive elements, control
134 elements, and complex control elements. The elements are defined
135 by the \l{QStyle::}{ComplexControl}, \l{QStyle::}{ControlElement},
136 and \l{QStyle::}{PrimitiveElement} enums. The values of
137 each element enum has a prefix to identify their type: \c{CC_} for
138 complex elements, \c{CE_} for control elements, and \c{PE_} for
139 primitive elements. We will in the following three sections see what
140 defines the different elements and see examples of widgets that use
141 them.
142
143 The QStyle class description contains a list of these elements and
144 their roles in styling widgets. We will see how they are used when
145 we style individual widgets.
146
147 \section3 Primitive Elements
148
149 Primitive elements are GUI elements that are common and often used
150 by several widgets. Examples of these are frames, button bevels,
151 and arrows for spin boxes, scroll bars, and combo boxes.
152 Primitive elements cannot exist on their own: they are always part
153 of a larger construct. They take no part in the interaction with
154 the user, but are passive decorations in the GUI.
155
156 \section3 Control Elements
157
158 A control element performs an action or displays information
159 to the user. Examples of control elements are push buttons, check
160 boxes, and header sections in tables and tree views. Control
161 elements are not necessarily complete widgets such as push
162 buttons, but can also be widget parts such as tab bar tabs and
163 scroll bar sliders. They differ from primitive elements in that
164 they are not passive, but fill a function in the interaction with
165 the user. Controls that consist of several elements often use the
166 style to calculate the bounding rectangles of the elements. The
167 available sub elements are defined by the \l{QStyle::}{SubElement}
168 enum. This enum is only used for calculating bounding rectangles,
169 and sub elements are as such not graphical elements to be drawn
170 like primitive, control, and complex elements.
171
172 \section3 Complex Control Elements
173
174 Complex control elements contain sub controls. Complex controls
175 behave differently depending on where the user handles them with
176 the mouse and which keyboard keys are pressed. This is dependent
177 on which sub control (if any) that the mouse is over or received a
178 mouse press. Examples of complex controls are scroll bars and
179 combo boxes. With a scroll bar, you can use the mouse to move the
180 slider and press the line up and line down buttons. The available
181 sub controls are defined by the \l{QStyle}{SubControl} enum.
182
183 In addition to drawing, the style needs to provide the widgets
184 with information on which sub control (if any) a mouse press was
185 made on. For instance, a QScrollBar needs to know if the user
186 pressed the slider, the slider groove, or one of the buttons.
187
188 Note that sub controls are not the same as the control elements
189 described in the previous section. You cannot use the style to
190 draw a sub control; the style will only calculate the bounding
191 rectangle in which the sub control should be drawn. It is common,
192 though, that complex elements use control and primitive elements
193 to draw their sub controls, which is an approach that is
194 frequently used by the built-in styles in Qt and also the Java
195 style. For instance, the Java style uses PE_IndicatorCheckBox to
196 draw the check box in group boxes (which is a sub control of
197 CC_GroupBox). Some sub controls have an equivalent control element,
198 e.g., the scroll bar slider (SC_SCrollBarSlider and
199 CE_ScrollBarSlider).
200
201 \section3 Other QStyle Tasks
202
203 The style elements and widgets, as mentioned, use the style to
204 calculate bounding rectangles of sub elements and sub controls,
205 and pixel metrics, which is a style dependent size in screen
206 pixels, for measures when drawing. The available rectangles and
207 pixel metrics are represented by three enums in QStyle:
208 \l{QStyle::}{SubElement}, \l{QStyle::}{SubControl}, and
209 \l{QStyle::}{PixelMetric}. Values of the enums can easily by
210 identified as they start with SE_, SC_ and PM_.
211
212 The style also contain a set of style hints, which is
213 represented as values in the \l{QStyle::}{StyleHint} enum. All
214 widgets do not have the same functionality and look in the
215 different styles. For instance, when the menu items in a menu do not
216 fit in a single column on the screen, some styles support
217 scrolling while others draw more than one column to fit all items.
218
219 A style usually has a set of standard images (such as a warning, a
220 question, and an error image) for message boxes, file dialogs,
221 etc. QStyle provides the \l{QStyle::}{StandardPixmap} enum. Its
222 values represent the standard images. Qt's widgets use these, so
223 when you implement a custom style you should supply the images
224 used by the style that is being implemented.
225
226 The style calculates the spacing between widgets in layouts. There
227 are two ways the style can handle these calculations. You can set
228 the PM_LayoutHorizontalSpacing and PM_LayoutVerticalSpacing, which
229 is the way the java style does it (through QCommonStyle).
230 Alternatively, you can implement QStyle::layoutSpacing() and
231 QStyle::layoutSpacingImplementation() if you need more control over
232 this part of the layout. In these functions you can calculate the
233 spacing based on control types (QSizePolicy::ControlType) for
234 different size policies (QSizePolicy::Policy) and also the style
235 option for the widget in question.
236
237 \section2 Style Options
238
239 A style option (a class that inherit QStyleOption) stores
240 parameters used by QStyle functions. The sub-classes of
241 QStyleOption contain all information necessary to style the
242 individual widgets. The style options keep public variables for
243 performance reasons. Style options are filled out by the widgets.
244
245 The widgets can be in a number of different states, which are
246 defined by the \l{QStyle::}{State} enum. Some of the state flags have
247 different meanings depending on the widget, but others are common
248 for all widgets like State_Disabled. It is QStyleOption that sets
249 the common states with QStyleOption::init(); the rest of the
250 states are set by the individual widgets.
251
252 Most notably, the style options contain the palette and bounding
253 rectangles of the widgets to be drawn. Most widgets have
254 specialized style options. QPushButton and QCheckBox, for
255 instance, use QStyleOptionButton as style option, which contain
256 the text, icon, and the size of their icon. The exact contents of
257 all options are described when we go through individual widgets.
258
259 \section2 QStyle Functions
260
261 The QStyle class defines three functions for drawing the primitive,
262 control, and complex elements:
263 \l{QStyle::}{drawPrimitive()},
264 \l{QStyle::}{drawControl()}, and
265 \l{QStyle::}{drawComplexControl()}. The functions takes the
266 following parameters:
267
268 \list
269 \o the enum value of the element to draw
270 \o a QStyleOption which contains the information needed to
271 draw the element.
272 \o a QPainter with which to draw the element.
273 \o a pointer to a QWidget, typically the widget
274 that the element is painted on.
275 \endlist
276
277 Not all widgets send a pointer to themselves. If the style
278 option sent to the function does not contain the information you
279 need, you should check the widget implementation to see if it
280 sends a pointer to itself.
281
282 The QStyle class also provides helper functions that are used
283 when drawing the elements. The \l{QStyle::}{drawItemText()}
284 function draws text within a specified rectangle and taking a
285 QPalette as a parameter. The \l{QStyle::}{drawItemPixmap()}
286 function helps to align a pixmap within a specified bounding
287 rectangle.
288
289 Other QStyle functions do various calculations for the
290 functions that draw. The widgets also use these functions for
291 calculating size hints and also for bounding rectangle
292 calculations if they draw several style elements themselves.
293 As with the functions that draw elements the helper functions
294 typically takes the same arguments.
295
296 \list
297 \o The \l{QStyle::}{subElementRect()} function takes a
298 \l{QStyle::}{SubElement} enum value, and calculates a bounding
299 rectangle for a sub element. The style uses this function to
300 know where to draw the different parts of an element. This is
301 mainly done for reuse. If you create a new style, you can use
302 the same location of sub elements as the super class.
303
304 \o The \l{QStyle::}{subControlRect()} function is used to
305 calculate bounding rectangles for sub controls in complex
306 controls. When you implement a new style, you reimplement \c
307 subControlRect() and calculate the rectangles that are different
308 from the super class.
309
310 \o The \l{QStyle::}{pixelMetric()} function returns a pixel
311 metric, which is a style dependent size given in screen
312 pixels. It takes a value of the \l{QStyle::}{PixelMetric} enum
313 and returns the correct measure. Note that pixel metrics do
314 not necessarily have to be static measures, but can be
315 calculated with, for example, the style option.
316
317 \o The \l{QStyle::}{hitTestComplexControl()} function returns the
318 sub control that the mouse pointer is over in a complex control.
319 Usually, this is simply a matter of using
320 \l{QStyle::}{subControlRect()} to get the bounding rectangles of
321 the sub controls, and see which rectangle contains the position of
322 the cursor.
323 \endlist
324
325 QStyle also have the functions \l{QStyle::}{polish()} and
326 \l{QStyle::}{unpolish()}. All widgets are sent to the \c polish()
327 function before being shown and to \c unpolish() when they
328 are hidden. You can use these functions to set attributes on the
329 widgets or do other work that is required by your style. For
330 instance, if you need to know when the mouse is hovering over the
331 widget, you need to set the \l{Qt::}{WA_Hover} widget attribute.
332 The State_MouseOver state flag will then be set in the widget's