Implementing Styles and Style Aware Widgets
|
State flag | Set |
---|---|
State_Sunken | Yes |
State_NoChange | No |
State_On | Yes |
State_Off | No |
State_MouseOver | Yes |
State_Enabled | Yes |
State_HasFocus | Yes |
State_KeyboardFocusChange | No |
State_Active | Yes |
The QCheckBox paints itself in QWidget::paintEvent() with style option opt and QStylePainter p. The QStylePainter class is a convenience class to draw style elements. Most notably, it wraps the methods in QStyle used for painting. The QCheckBox draws itself as follows:
QStylePainter p(this); QStyleOptionButton opt = d->getStyleOption(); p.drawControl(QStyle::CE_CheckBox, opt);
QCommonStyle handles the CE_CheckBox element. The QCheckBox has two sub elements: SE_CheckBoxIndicator (the checked indicator) and SE_CheckBoxContents (the contents, which is used for the checkbox label). QCommonStyle also implements these sub element bounding rectangles. We have a look at the QCommonStyle code:
QStyleOptionButton subopt = *btn; subopt.rect = subElementRect(SE_CheckBoxIndicator, btn, widget); drawPrimitive(PE_IndicatorCheckBox, &subopt, p, widget); subopt.rect = subElementRect(SE_CheckBoxContents, btn, widget); drawControl(CE_CheckBoxLabel, &subopt, p, widget); if (btn->state & State_HasFocus) { QStyleOptionFocusRect fropt; fropt.QStyleOption::operator=(*btn); fropt.rect = subElementRect(SE_CheckBoxFocusRect, btn, widget); drawPrimitive(PE_FrameFocusRect, &fropt, p, widget); }
As can be seen from the code extract, the common style gets the bounding rectangles of the two sub elements of CE_CheckBox, and then draws them. If the checkbox has focus, the focus frame is also drawn.
The java style draws CE_CheckBoxIndicator, while QCommonStyle handles CE_CheckboxLabel. We will examine each implementation and start with CE_CheckBoxLabel:
const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt); uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter); if (!styleHint(SH_UnderlineShortcut, btn, widget)) alignment |= Qt::TextHideMnemonic; QPixmap pix; QRect textRect = btn->rect; if (!btn->icon.isNull()) { pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled); drawItemPixmap(p, btn->rect, alignment, pix); if (btn->direction == Qt::RightToLeft) textRect.setRight(textRect.right() - btn->iconSize.width() - 4); else textRect.setLeft(textRect.left() + btn->iconSize.width() + 4); } if (!btn->text.isEmpty()){ drawItemText(p, textRect, alignment | Qt::TextShowMnemonic, btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText); }
visualAlignment() adjusts the alignment of text according to the layout direction. We then draw an icon if it exists, and adjust the space left for the text. drawItemText() draws the text taking alignment, layout direction, and the mnemonic into account. It also uses the palette to draw the text in the right color.
The drawing of labels often get somewhat involved. Luckily, it can usually be handled by the base class. The java style implements its own push button label since Java-contrary to windows-center button contents also when the button has an icon. You can examine that implementation if you need an example of reimplementing label drawing.
We take a look at the java implementation of CE_CheckBoxIndicator in drawControl():
case PE_IndicatorCheckBox: { painter->save(); drawButtonBackground(option, painter, true); if (option->state & State_Enabled && option->state & State_MouseOver && !(option->state & State_Sunken)) { painter->setPen(option->palette.color(QPalette::Button)); QRect rect = option->rect.adjusted(1, 1, -2, -2); painter->drawRect(rect); rect = rect.adjusted(1, 1, -1, -1); painter->drawRect(rect); } if (option->state & State_On) { QImage image(":/images/checkboxchecked.png"); painter->drawImage(option->rect.topLeft(), image); } painter->restore(); break;
We first save the state of the painter. This is not always necessary but in this case the QWindowsStyle needs the painter in the same state as it was when PE_IndicatorCheckBox was called (We could also set the state with function calls, of course). We then use drawButtonBackground() to draw the background of the check box indicator. This is a helper function that draws the background and also the frame of push buttons and check boxes. We take a look at that function below. We then check if the mouse is hovering over the checkbox. If it is, we draw the frame java checkboxes have when the box is not pressed down and the mouse is over it. You may note that java does not handle tristate boxes, so we have not implemented it.
Here we use a png image for our indicator. We could also check here if the widget is disabled. We would then have to use another image with the indicator in the disabled color.
void JavaStyle::drawButtonBackground(const QStyleOption *option, QPainter *painter, bool isCheckbox) const { QBrush buttonBrush = option->palette.button(); bool sunken = option->state & State_Sunken; bool disabled = !(option->state & State_Enabled); bool on = option->state & State_On; if (!sunken && !disabled && (!on || isCheckbox)) buttonBrush = gradientBrush(option->rect); painter->fillRect(option->rect, buttonBrush); QRect rect = option->rect.adjusted(0, 0, -1, -1); if (disabled) painter->setPen(option->palette.color(QPalette::Disabled, QPalette::WindowText)); else painter->setPen(option->palette.color(QPalette::Mid)); painter->drawRect(rect); if (sunken && !disabled) { drawSunkenButtonShadow(painter, rect, option->palette.color(QPalette::Mid), option->direction == Qt::RightToLeft); } }
We have seen how check boxes are styled in the java style from the widget gets a paint request to the style is finished painting. To learn in detail how each widget is painted, you need to go through the code step-by-step as we have done here. However, it is usually enough to know which style elements the widgets draw. The widget builds a style option and calls on the style one or more times to draw the style elements of which it consists. Usually, it is also sufficient to know the states a widget can be in and the other contents of the style option, i.e., what we list in the next section.
In this section, we will examine how most of Qt's widgets are styled. Hopefully, this will save you some time and effort while developing your own styles and widgets. You will not find information here that is not attainable elsewhere (i.e., by examining the source code or the class descriptions for the style related classes).
We mostly use java style widgets as examples. The java style does not draw every element in the element trees. This is because they are not visible for that widget in the java style. We still make sure that all elements are implemented in a way that conforms with the java style as custom widgets might need them (this does not exclude leaving implementations to QWindowsStyle though).
The following is given for each widget:
The element tree contains the primitive, control, and complex style elements. By doing a top-down traversal of the element tree, you get the sequence in which the elements should be drawn. In the nodes, we have written the sub element rectangles, sub control elements, and pixel metrics that should be considered when drawing the element of the node.
Our approach on styling center on the drawing of the widgets. The calculations of sub elements rectangles, sub controls, and pixel metrics used during drawing is only listed as contents in the element trees. Note that there are rectangles and pixel metrics that are only used by widgets. This leaves these calculations untreated in the walkthrough. For instance, the subControlRect() and sizeFromContents() functions often call subElementRect() to calculate their bounding rectangles. We could draw trees for this as well. However, how these calculations are done is completely up to the individual styles, and they do not have to follow a specific structure (Qt does not impose a specific structure). You should still make sure that you use the appropriate pixel metrics, though. To limit the size of the document, we have therefore chosen not to include trees or describe the calculations made by the Java (or any other) style.
You may be confused about how the different pixel metrics, sub element rectangles, and sub control rectangles should be used when examining the trees. If you are in doubt after reading the QStyle enum descriptions, we suggest that you examine the QCommonStyle and QWindowsStyle implementations.
Some of the bounding rectangles that we outline in the widget images are equal. Reasons for this are that some elements draw backgrounds while others draw frames and labels. If in doubt, check the description of each element in QStyle. Also, some elements are there to layout, i.e., decide where to draw, other elements.
Some states and variables are common for all widgets. These are set with QStyleOption::init(). Not all elements use this function; it is the widgets that create the style options, and for some elements the information from init() is not necessary.
A table with the common states follows:
State | State Set When |
---|---|
State_Enabled | Set if the widget is not disabled (see QWidget::setEnabled()) |
State_Focus | Set if the widget has focus (see QWidget::hasFocus()) |
State_KeyobordFocusChange | Set when the user changes focus with the keyboard (see Qt::WA_KeyboardFocusChange) |
State_MouseOver | Set if the mouse cursor is over the widget |
State_Active | Set if the widget is a child of the active window. |
State_HasEditFocus | Set if the widget has the edit focus |
The other common members for widgets are:
Member | Content |
---|---|
rect | The bounding rectangle of the element to draw. This is set to the widget bounding rectangle (QWidget::rect()). |
direction | The layout direction; a value of the Qt::LayoutDirection enum. |
palette | The QPalette to use when drawing the element. This is set to the widgets palette (QWidget::palette()). |
fontMetrics | The QFontMetrics to use when drawing text on the widget. |
The complex style options (classes that inherit QStyleOptionComplex) used for complex style elements share two variables: subControls and activeSubControls. Both variables are an OR'ed combination of QStyle::SubControl enum values. They indicate which sub controls the complex control consists of and which of these controls are currently active.
As mentioned, the style calculates the size of the widgets contents, which the widgets calculate their size hints from. In addition, complex controls also use the style to test which sub-controls the mouse is over.
Without further delay, we present the widget walkthrough; each widget has its own sub-section.
The style structure for push buttons is shown below. By doing a top-down traversal of the tree, you get the sequence in which the elements should be drawn.
The layout of the buttons, with regard element bounds, varies from style to style. This makes it difficult to show conceptual images of this. Also, elements may - even be intended to - have the same bounds; the PE_PushButtonBevel, for instance, is used in QCommonStyle to draw the elements that contains it: PE_FrameDefaultButton, PE_FrameButtonBevel, and PE_PanelButtonCommand, all of which have the same bounds in common and windows style. PE_PushButtonBevel is also responsible for drawing the menu indicator (QCommonStyle draws PE_IndicatorArrowDown).
An image of a push button in the java style that show the bounding rectangles of the elements is given below. Colors are used to separate the bounding rectangles in the image; they do not fill any other purpose. This is also true for similar images for the other widgets.
The java style, as well as all other styles implemented in Qt, does not use PE_FrameButtonBevel. It is usual that a button with a PE_DefaultFrame adjusts the PE_PanelButtonCommand's rectangle by PM_ButtonDefaultIndicator. The CE_PushButtonLabel is found by adjusting the rect by PM_DefaultFrameWidth.
We will now examine the style option for push buttons - QStyleOptionButton. A table for the states that QPushButton can set on the style option follows:
State | State Set When |
---|---|
State_Sunken | Button is down or menu is pressed shown |
State_On | Button is checked |
State_Raised | Button is not flat and not pressed down |
Other members of QStyleOptionButton is:
Member | Content |
---|---|
features | Flags of the QStyleOptionButton::ButtonFeatures enum, which describes various button properties (see enum) |
icon | The buttons QIcon (if any) |
iconSize | The QSize of the icon |
text | a QString with the buttons text |
The structures for radio and check buttons are identical. We show the structure using QCheckBox element and pixel metric names:
QStyleOptionButton is used as the style option for both check and radio buttons. We first give a table of the states that can be set in the option:
State | State Set When |
---|---|
State_sunken | The box is pressed down |
State_NoChange | The box is partially checked (for tristate checkboxes.) |
State_On | The box is checked |
State_Off | The box is unchecked |
See Push Buttons for a table over other members in the QStyleOptionButtonClass.
In Qt, QTabBar uses the style to draw its tabs. Tabs exist either in a QTabWidget, which contains a QTabBar, or as a separate bar. If the bar is not part of a tab widget, it draws its own base.
QTabBar lays out the tabs, so the style does not have control over tab placement. However, while laying out its tabs, the bar asks the style for PM_TabBarTabHSpace and PM_TabBarTabVSpace, which is extra width and height over the minimum size of the tab bar tab label (icon and text). The style can also further influence the tab size before it is laid out, as the tab bar asks for CT_TabBarTab. The bounding rectangle of the bar is decided by the tab widget when it is part of the widget (still considering CT_TabBarTab).
The tab bar is responsible for drawing the buttons that appear on the tab bar when all tabs do not fit. Their placement is not controlled by the style, but the buttons are QToolButtons and are therefore drawn by the style.
Here is the style structure for QTabWidget and QTabBar:
The dotted lines indicate that the QTabWidget contains a tab bar, but does not draw it itself, that QTabBar only draws its base line when not part of a tab widget, and that the tab bar keeps two tool buttons that scroll the bar when all tabs do not fit; see Tool Buttons for their element tree. Also note that since the buttons are children of the tab bar, they are drawn after the bar. The tabs bounding rectangles overlap the base by PM_TabBarBaseOverlap.
Here is a tab widget in the java style:
In the java style (and also windows), the tab bar shape and label have the same bounding rectangle as CE_TabBarTab. Notice that the tabs overlap with the tab widget frame. The base of the tab bar (if drawn) is the area where the tabs and frame overlap.
The style option for tabs (QStyleOptionTab) contains the necessary information for drawing tabs. The option contains the position of the tab in the tab bar, the position of the selected tab, the shape of the tab, the text, and icon. After Qt 4.1 the option should be cast to a QStyleOptionTabV2, which also contains the icons size.
As the java style tabs don't overlap, we also present an image of a tab widget in the windows style. Note that if you want the tabs to overlap horizontally, you do that when drawing the tabs in CE_TabBarTabShape; the tabs bounding rectangles will not be altered by the tab bar. The tabs are drawn from left to right in a north tab bar shape, top to bottom in an east tab bar shape, etc. The selected tab is drawn last, so that it is easy to draw it over the other tabs (if it is to be bigger).
A table of the states a tab bar can set on its tabs follows:
State | State Set When |
---|---|
State_Sunken | The tab is pressed on with the mouse. |
State_Selected | If it is the current tab. |
State_HasFocus | The tab bar has focus and the tab is selected |
Note that individual tabs may be disabled even if the tab bar is not. The tab will be active if the tab bar is active.
Here follows a table of QStyleOptionTabV2's members:
Member | Content |
---|---|
cornerWidgets | Is flags of the CornerWidget enum, which indicate if and which corner widgets the tab bar has. |
icon | The QIcon of the tab |
iconSize | The QSize of the icon |
position | A TabPosition enum value that indicates the tabs position on the bar relative to the other tabs. |
row | holds which row the tab is in |
selectedPosition | A value of the SelectedPosition enum that indicates whether the selected tab is adjacent to or is the tab. |
shape | A value of the QTabBar::Shape enum indication whether the tab has rounded or triangular corners and the orientation of the tab. |
text | The tab text |
The frame for tab widgets use QStyleOptionTabWidgetFrame as style option. We list its members here. It does not have states set besides the common flags.
Member | content |
---|---|
leftCornerWidgetSize | The QSize of the left corner widget (if any). |
rightCornerWidgetSize | The QSize of the right corner widget (if any). |
lineWidth | holds the line with for drawing the panel. |
midLineWith | this value is currently always 0. |
shape | The shape of the tabs on the tab bar. |
tabBarSize | The QSize of the tab bar. |
Here is the style structure for scrollBars:
QScrollBar simply creates its style option and then draws CC_ScrollBar. Some styles draw the background of add page and sub page with PE_PanelButtonBevel and also use indicator arrows to draw the arrows in the nest and previous line indicators; we have not included these in the tree as their use is up to the individual style. The style's PM_MaximumDragDistance is the maximum distance in pixels the mouse can move from the bounds of the scroll bar and still move the handle.
Here is an image of a scrollbar in the java style:
You may notice that the scrollbar is slightly different from Java's as it has two line up indicators. We have done this to show how that you can have two separate bounding rectangles for a single sub control. The scroll bar is an example of a widget that is entirely implemented by the java style - neither QWindowsStyle nor QCommonStyle are involved in the drawing.
We have a look at the different states a scroll bar can set on the style option:
State | State Set When |
---|---|
State_Horizontal | The scroll bar is horizontal |
The style option of QScrollBar is QStyleOptionSlider. Its members are listed in the following table. The option is used by all QAbstractSliders; we only describe the members relevant for scroll bars here.
Member | Content |
---|---|
maximum | the maximum value of the scroll bar |
minimum | the minimum value of the scroll bar |
notchTarget | the number of pixels between notches |
orientation | a value of the Qt::Orientation enum that specifies whether the scroll bar is vertical or horizontal |
pageStep | the number to increase or decrease the sliders value (relative to the size of the slider and its value range) on page steps. |
singleStep | the number to increase or decrease the sliders value on single (or line) steps |
sliderValue | The value of the slider |
sliderPosition | the position of the slider handle. This is the same as sliderValue if the scroll bar is QAbstractSlider::tracking. If not, the scroll bar does not update its value before the mouse releases the handle. |
upsideDown | holds the direction in which the scroll bar increases its value. This is used instead of QStyleOption::direction for all abstract sliders. |
When calculating the sliders size hint, PM_SliderTickness and PM_SliderLength is queried from the style. As with scroll bars, the QSlider only lets the user move the handle if the mouse is within PM_MaximumDragDistance from the slider bounds. When it draws itself it creates the style option and calls drawComplexControl() with CC_Slider:
We also show a picture of a slider in the java style. We show the bounding rectangles of the sub elements as all drawing is done in CC_Slider.
QSlider uses QStyleOptionSlider as all QAbstractSliders do. We present a table with the members that affect QSlider:
Member | Content |
---|---|
maximum | the maximum value of the slider |
minimum | the minimum value of the slider |
notchTarget | this is the number of pixels between each notch |
orientation | a Qt::Orientation enum value that gives whether the slider is vertical or horizontal. |
pageStep | a number in slider value to increase or decrease for page steps |
singleStep | the number to increase or decrease the sliders value on single (or line) steps. |
sliderValue | the value of the slider. |
sliderPosition | the position of the slider given as a slider value. This will be equal to the sliderValue if the slider is tracking; if not, the sliders value will not change until the handle is released with the mouse. |
upsideDown | this member is used instead of QStyleOption::direction for all abstract sliders. |
You should note that the slider does not use direction for reverse layouts; it uses upsideDown.
When QSpinBox paints itself it creates a QStyleOptionSpinBox and asks the style to draw CC_SpinBox. The edit field is a line edit that is a child of the spin box. The dimensions of the field is calculated by the style with SC_SpinBoxEditField.
Here follows the style tree for spin boxes. It is not required that a style uses the button panel primitive to paint the indicator backgrounds. You can see an image below the tree showing the sub elements in QSpinBox in the java style.
The QStyleOptionSpinBox, which is the style option for spin boxes. It can set the following states on the spin box.:
State | State Set When |
---|---|
State_Sunken | Is set if one of the sub controls CC_SpinUp or CC_SpinDown is pressed on with the mouse. |
The rest of the members in the spin boxes style options are:
Property | Function |
---|---|
frame | boolean that is true if the spin box is to draw a frame. |
buttonSymbols | Value of the ButtonSymbols enum that decides the symbol on the up/down buttons. |
stepEnabled | A value of the StepEnabled indication which of the spin box buttons are pressed down. |
The title bar complex control, CC_TitleBar, is used to draw the title bars of internal windows in QMdiArea. It typically consists of a window title and close, minimize, system menu, and maximize buttons. Some styles also provide buttons for shading the window, and a button for context sensitive help.
The bar is drawn in CC_TitleBar without using any sub elements. How the individual styles draw their buttons is individual, but there are standard pixmaps for the buttons that the style should provide.
In an image over a title bar in the java style, we show the bounding rectangles of the sub elements supported by the java style (all of which are drawn with standard pixmaps). It is usual to draw the button backgrounds using PE_PanelButtonTool, but it's no rule.
The style option for title bars is QStyleOptionTitleBar. It's members are:
Member | Content |
---|---|
icon | The title bars icon |
text | the text for the title bar's label |
windowFlags | flags of the Qt::WindowFlag enum. The window flags used by QMdiArea for window management. |
titleBarState | this is the QWidget::windowState() of the window that contains the title bar. |
A QComboBox uses the style to draw the button and label of non-editable boxes with CC_ComboBox and CE_ComboBoxLabel.
The list that pops up when the user clicks on the combo box is drawn by a delegate, which we do not cover in this overview. You can, however, use the style to control the list's size and position with the sub element SC_ComboBoxListBoxPopup. The style also decides where the edit field for editable boxes should be with SC_ComboBoxEditField; the field itself is a QLineEdit that is a child of the combo box.
We show an image over a java style combo box in which we have outlined its sub elements and sub element rectangles:
Java combo boxes do not use the focus rect; it changes its background color when it has focus. The SC_ComboBoxEdit field is used both by QComboBox to calculate the size of the edit field and the style for calculating the size of the combo box label.
The style option for combo boxes is QStyleOptionComboBox. It can set the following states:
State | Set When |
---|---|
State_Selected | The box is not editable and has focus |
State_Sunken | SC_ComboBoxArrow is active |
State_on | The container (list) of the box is visible |
The style options other members are:
Member | Content |
---|---|
currentIcon | the icon of the current (selected) item of the combo box. |
currentText | the text of the current item in the box. |
editable | holds whether the combo box is editable or not |
frame | holds whether the combo box has a frame or not |
iconSize | the size of the current items icon. |
popupRect | the bounding rectangle of the combo box's popup list. |
When calculating the size hint, QGroupBox fetches three pixel metrics from the style: PM_IndicatorWidth, PM_CheckBoxLabelSpacing, and PM_IndicatorHeight. QGroupBox has the following style element tree:
Qt does not impose restrictions on how the check box is drawn; the java style draws it with CE_IndicatorCheckBox. See Check and Radio Buttons for the complete tree.
We also give an image of the widget with the sub controls and sub control rectangles drawn:
The style option for group boxes are QStyleOptionGroupBox. The following states can be set on it:
State | Set When |
---|---|
State_On | The check box is checked |
State_Sunken | The checkbox is pressed down |
State_Off | The check box is unchecked (or there is no check box) |
The remaining members of QStyleOptionGroupBox are:
Member | Content |
---|---|
features | flags of the QStyleOptionFrameV2::FrameFeatures enum describing the frame of the group box. |
lineWidth | the line width with which to draw the panel. This is always 1. |
text | the text of the group box. |
textAlignment | the alignment of the group box title |
textColor | the QColor of the text |
As the structure of splitters are simple and do not contain any sub elements, we do not include image of splitters. CE_Splitter does not use any other elements or metrics.
For its style option, Splitters uses the base class QStyleOption. It can set the following state flags on it:
State | Set When |
---|---|
State_Horizontal | Set if it is a horizontal splitter |
QSplitter does not use init() to set up its option; it sets the State_MouseOver and State_Disabled flags itself.
The CE_ProgressBar element is used by QProgressBar, and it is the only element used by this widget. We start with looking at the style structure:
Here is a progress bar in the windows style (the java style bounding rectangles are equal):
The style option for QProgressBar is QStyleOptionProgressBarV2. The bar does not set any state flags, but the other members of the option are:
Member | Content |
---|---|
minimum | The minimum value of the bar |
maximum | The maximum value of the bar |
progress | The current value of the bar |
textAlignment | How the text is aligned in the label |
textVisible | Whether the label is drawn |
text | The label text |
orientation | Progress bars can be vertical or horizontal |
invertedAppearance | The progress is inverted (i.e., right to left in a horizontal bar) |
bottomToTop | Boolean that if true, turns the label of vertical progress bars 90 degrees. |
Tool buttons exist either independently or as part of tool bars. They are drawn equally either way. The QToolButton draws only one style element: CC_ToolButton.
As you must be used to by now (at least if you have read this document sequentially), we have a tree of the widget's style structure:
Note that PE_FrameButtonTool and PE_IndicatorArrowDown are included in the tree as the java style draws them, but they can safely be omitted if you prefer it. The structure may also be different. QWindowsStyle, for instance, draws both PE_IndicatorButtonDropDown and PE_IndicatorArrowDown in CE_ToolButton.
We also have an image of a tool button where we have outlined the sub element bounding rectangles and sub controls.
Here is the states table for tool buttons:
State | Set When |
---|---|
State_AutoRise | the tool button has the autoRise property set |
State_raised | the button is not sunken (i.e., by being checked or pressed on with the mouse). |
State_Sunken | the button is down |
State_On | the button is checkable and checked. |
QStyleOptionToolButton also contains the following members:
Member | Content |
---|---|
arrowType | a Qt::ArrowType enum value, which contains the direction of the buttons arrow (if an arrow is to be used in place of an icon) |
features | flags of the QStyleOptionToolButton::ButtonFeature enum describing if the button has an arrow, a menu, and/or has a popup-delay. |
font | the QFont of the buttons label |
icon | the QIcon of the tool button |
iconSize | the icon size of the button's icon |
pos | the position of the button, as given by QWidget::pos() |
text | the text of the button |
toolButtonStyle | a Qt::ToolButtonStyle enum value which decides whether the button shows the icon, the text, or both. |
Toolbars are part of the main window framework and cooperates with the QMainWindow to which it belongs while it builds its style option. A main window has 4 areas that toolbars can be placed in. They are positioned next to the four sides of the window (i.e., north, south, west, and east). Within each area there can be more than one line of toolbars; a line consists of toolbars with equal orientation (vertical or horizontal) placed next to each other.
QToolbars in Qt consists of three elements CE_ToolBar, PE_IndicatorToolBarHandle, and PE_IndicatorToolBarSeparator. It is QMainWindowLayout that calculates the bounding rectangles (i.e., position and size of the toolbars and their contents. The main window also uses the sizeHint() of the items in the toolbars when calculating the size of the bars.
Here is the element tree for QToolBar:
The dotted lines indicate that the QToolBar keeps an instance of QToolBarLayout and that QToolBarSeparators are kept by QToolBarLayout. When the toolbar is floating (i.e., has its own window) the PE_FrameMenu element is drawn, else QToolbar draws CE_ToolBar.
Here is an image of a toolbar in the java style:
QToolBarSaparator uses QStyleOption for their style option. It sets the State_horizontal flag if the toolbar they live in is horizontal. Other than that, they use init().
The style option for QToolBar is QStyleOptionToolBar. The only state flag set (besides the common flags) is State_Horizontal if the bar is horizontal (i.e., in the north or south toolbar area). The member variables of the style option are:
Member | Content |
---|---|
features | Holds whether the bar is movable in a value of the ToolBarFeature, which is either Movable or None. |
lineWidth | The width of the tool bar frame. |
midLineWidth | This variable is currently not used and is always 0. |
positionOfLine | The position of the toolbar line within the toolbar area to which it belongs. |
positionWithinLine | The position of the toolbar within the toolbar line. |
toolBarArea | The toolbar area in which the toolbar lives. |
Menus in Qt are implemented in QMenu. The QMenu keeps a list of action, which it draws as menu items. When QMenu receives paint events ,it calculates the size of each menu item and draws them individually with CE_MenuItem. (Menu items do not have a separate element for their label (contents), so all drawing is done in CE_MenuItem. The menu also draws the frame of the menu with PE_FrameMenu. It also draws CE_MenuScroller if the style supports scrolling. CE_MenuTearOff is drawn if the menu is to large for its bounding rectangle.
In the style structure tree, we also include QMenu as it also does styling related work. The bounding rectangles of menu items are calculated for the menus size hint and when the menu is displayed or resized.
The CE_MenuScroller and CE_MenuTearOff elements are handled by QCommonStyle and are not shown unless the menu is to large to fit on the screen. PE_FrameMenu is only drawn for pop-up menus.
QMenu calculates rectangles based on its actions and calls CE_MenuItem and CE_MenuScroller if the style supports that.
It is also usual to use PE_IndicatorCheckBox (instead of using PE_IndicatorMenuCheckMark) and PE_IndicatorRadioButton for drawing checkable menu items; we have not included them in the style tree as this is optional and varies from style to style.
The style option for menu items is QStyleOptionMenuItem. The following tables describe its state flags and other members.
State | Set When |
---|---|
State_Selected | The mouse is over the action and the action is not a separator. |
State_Sunken | The mouse is pressed down on the menu item. |
State_DownArrow | Set if the menu item is a menu scroller and it scrolls the menu downwards. |
Member | Content |
---|---|
checkType | A value of the CheckType enum, which is either NotCheckable, Exclusive, or NonExclusive. |
checked | Boolean that is true if the menu item is checked. |
font | The QFont to use for the menu item's text. |
icon | the QIcon of the menu item. |
maxIconWidth | The maximum width allowed for the icon |
menuHasChecableItem | Boolean which is true if at least one item in the menu is checkable. |
menuItemType | The type of the menu item. This a value of the MenuItemType. |
menuRect | The bounding rectangle for the QMenu that the menu item lives in. |
tabWidth | This is the distance between the text of the menu item and the shortcut. |
text | The text of the menu item. |
The setup of the style option for CE_MenuTearOff and CE_MenuScroller also uses QStyleOptionMenuItem; they only set the menuRect variable in addition to the common settings with QStyleOption's init().
QMenuBar uses the style to draw each menu bar item and the empty area of the menu bar. The pull-down menus themselves are QMenus (see Menus). The style element tree for the menu bar follows:
The panel and empty area is drawn after the menu items. The QPainter that the QMenuBar sends to the style has the bounding rectangles of the items clipped out (i.e., clip region), so you don't need to worry about drawing over the items. The pixel metrics in QMenuBar is used when the bounding rectangles of the menu bar items are calculated.
QStyleOptionMenuItem is used for menu bar items. The members that are used by QMenuBar is described in the following table:
Member | Content |
---|---|
menuRect | the bounding rectangle of the entire menu bar to which the item belongs. |
text | the text of the item |
icon | the icon of the menu item (it is not common that styles draw this icon) |
QStyleOptionMenuItem is also used for drawing CE_EmptyMenuBarArea.
QStyleOptionFrame is used for drawing the panel frame The lineWidth is set to PM_MenuBarPanelWidth. The midLineWidth is currently always set to 0.
It is the style that draws the headers of Qt's item views. The item views keeps the dimensions on individual sections. Also note that the delegates may use the style to paint decorations and frames around items. QItemDelegate, for instance, draws PE_FrameFocusRect and PE_IndicatorViewItemCheck.
Here is a QTableWidget showing the bounding rects of a Java header:
The QHeaderView uses CT_HeaderSection, PM_HeaderMargin and PM_HeaderGripMargin for size and hit test calculations. The PM_HeaderMarkSize is currently not used by Qt. QTableView draws the button in the top-left corner (i.e., the area where the vertical and horizontal headers intersect) as a CE_Header.
The style option for header views is QStyleOptionHeader. The view paints one header section at a time, so the data is for the section being drawn. Its contents are:
Member | Content |
---|---|
icon | the icon of the header (for section that is being drawn). |
iconAlignment | the alignment (Qt::Alignment) of the icon in the header. |
orientation | a Qt::Orientation value deciding whether the header is the horizontal header above the view or the vertical header on the left. |
position | a QStyleOptionHeader::SectionPosition value giving the header section's position relative to the other sections. |
section | holds the section that is being drawn. |
selectedPosition | a QStyleOptionHeader::SelectedPosition value giving the selected section's position relative to the section that is being painted. |
sortIndicator | a QStyleOptionHeader::SortIndicator value that describes the direction in which the section's sort indicator should be drawn. |
text | the text of the currently drawn section. |
textAlignment | the Qt::Alignment of the text within the headersection. |
The branch indicators in a tree view is drawn by the style with PE_IndicatorBranch. We think of indicators here as the indicators that describe the relationship of the nodes in the tree. The generic QStyleOption is sent to the style for drawing this elements. The various branch types are described by states. Since there are no specific style option, we simply present the states table:
State | Set When |
---|---|
State_Sibling | the node in the tree has a sibling (i.e., there is another node in the same column). |
State_Item | this branch indicator has an item. |
State_Children | the branch has children (i.e., a new sub-tree can be opened at the branch). |
State_Open | the branch indicator has an opened sub-tree. |
The tree view (and tree widget) use the style to draw the branches (or nodes if you will) of the tree.
QStyleOption is used as the style for PE_IndicatorBranch has state flags set depending on what type of branch it is.
Since there is no tree structure for branch indicators, we only present an image of a tree in the java style. Each state is marked in the image with a rectangle in a specific color (i.e., these rectangles are not bounding rectangles). All combinations of states you must be aware of are represented in the image.
PM_SmallIconSize for sizeHints.
QToolBox is a container that keeps a collection of widgets. It has one tab for each widget and display one of them at a time. The tool box lays the components it displays (the tool box buttons and selected widget) in a QVBoxLayout. The style tree for tool boxes looks like this:
We show an image of a tool box in the Plastique style:
All elements have the same bounding rectangles in the Plastique as well as the other Qt built-in styles.
The style option for tool boxes is QStyleOptionToolBox. It contains the text and icon of the tool box contents. The only state set by QToolBox is State_Sunken, which is set when the user presses a tab down with the mouse. The rest of the QStyleOptionToolBox members are:
Member | Content |
---|---|
icon | the icon on the toolbox tab |
text | the text on the toolbox tab |
The size grip calculates its size hint with CT_SizeGrip. The pixel metric PM_SizeGripSize is currently unused by Qt. The element tree for and an image in the Plastique style of QSizeGrip follows:
We show the size grip in a QMainWindow's bottom right corner.
The size grip style option, QStyleOptionSizeGrip, have one member except the common members from QStyleOption:
Member | Content |
---|---|
corner | a Qt::Corner value that describe which corner in a window (or equivalent) the grip is located. |
The QRubberBand's style tree consists of two nodes.
We present an image of a Java style window being moved in a QMdiArea with a rubber band:
The style option for rubber bands is QStyleOptionRubberBand. Its members are:
Member | Content |
---|---|
opaque | boolean that is true if the rubber band must be drawn in an opaque style (i.e., color) |
shape | a QRubberBand::Shape enum value that holds the shape of the band (which is either a rectangle or a line) |
When the dock widget lays out its contents it asks the style for these pixel metrics: PM_DockWidgetSeparatorExtent, PM_DockWidgetTitleBarButtonMargin, PM_DockWidgetFrameWidth, and PM_DockWidgetTitleMargin. It also calculates the bounding rectangles of the float and close buttons with SE_DockWidgetCloseButton and SE_DockWidgetFloatButton.
The dotted lines indicate that the sender keeps instances of the recipient of the arrow (i.e., it is not a style element to draw). The dock widget only draws PE_frameDockWidget when it is detached from its main window (i.e., it is a top level window). If it is docked it draws the indicator dock widget resize handle. We show a dock widget in both docked and floating state in the plastique style:
The style option is QStyleOptionDockWidget:
Member | Content |
---|---|
closeable | boolean that holds whether the dock window can be closed |
floatable | boolean that holds whether the dock window can float (i.e., detach from the main window in which it lives) |
movable | boolean that holds whether the window is movable (i.e., can move to other dock widget areas) |
title | the title text of the dock window |
For the buttons, QStyleOptionButton is used (see Tool Buttons for content description). The dock widget resize handle has a plain QStyleOption.
Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. | Qt 4.4 | |
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD. | ||
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP ! |
Copyright © 2000-2012 - www.developpez.com