Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites 
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Classes principales  ·  Annotées  ·  Classes groupées  ·  Modules  ·  Fonctions  · 

The Qt 4 Style API

Qt's style API is responsible for performing the widget drawing for built-in widgets. The Qt 4 style API has been revised to make it possible for a style to draw widgets without calling any functions on the widget.

Because Qt 4 is split across multiple libraries, Qt needed this update to be able to draw widgets from other libraries than QtGui. For application developers, this has other benefits, such as more managable parameter lists and the possibility of drawing any graphical element without having a widget of a specific type.

General Overview

The QStyle class is an abstract base class that encapsulates the look and feel of a GUI. Qt's built-in widgets use it to perform nearly all of their drawing, ensuring that they look exactly like the equivalent native widgets.

Most draw functions now take four arguments:

  • an enum value specifying which graphical element to draw
  • a QStyleOption specifying how and where to render that element
  • a QPainter that should be used to draw the element
  • a QWidget on which the drawing is performed (optional)

The style gets all the information it needs to render the graphical element from QStyleOption. The widget is passed as the last argument in case the style needs it to perform special effects (such as animated default buttons on Mac OS X), but it isn't mandatory. In fact, QStyle can be used to draw on any paint device, not just widgets, by setting the QPainter properly.

Thanks to QStyleOption, it is now possible to make QStyle draw widgets without linking in any code for the widget. This is how Qt's built-in styles can draw Qt 3 widgets such as Q3ListView without necessarily linking against the Qt3Support library. Another significant benefit of the new approach is that it's now possible to use QStyle's draw functions on other widgets than the built-in widgets; for example, you can draw a combobox on any widget, not just on a QComboBox.

QStyleOption has various subclasses for the various types of graphical elements that can be drawn, and it's possible to create custom subclasses. For example, the QStyle::PE_FrameFocusRect element expects a QStyleOptionFocusRect argument. This is documented for each enum value.

When reimplementing QStyle functions that take a QStyleOption parameter, you often need to cast the QStyleOption to a subclass (e.g., QStyleOptionFocusRect). For safety, you can use qstyleoption_cast() to ensure that the pointer type is correct. If the object isn't of the right type, qstyleoption_cast() returns 0. For example:

    const QStyleOptionFocusRect *focusRectOption =
            qstyleoption_cast<const QStyleOptionFocusRect *>(option);
    if (focusRectOption) {
        ...
    }

For performance reasons, there are few member functions and the access to the variables is direct. This "low-level" feel makes the structures use straightforward and emphasizes that these are simply parameters used by the style functions. In addition, the caller of a QStyle function usually creates QStyleOption objects on the stack. This combined with Qt's extensive use of implicit sharing for types such as QString, QPalette, and QColor ensures that no memory allocation needlessly takes place. (Dynamic memory allocation can be an expensive operation, especially when drawing very often in a short time.)

Example Code

The following code snippet illustrates how to use QStyle to draw the focus rectangle from a custom widget's paintEvent():

    void MyWidget::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        ...

        QStyleOptionFocusRect option(1);
        option.init(this);
        option.backgroundColor = palette().color(QPalette::Background);

        style().drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter,
                              this);
    }

The next example shows how to derive from an existing style to customize the look of a graphical element:

    class CustomStyle : public QWindowsStyle
    {
        Q_OBJECT

    public:
        CustomStyle() {}
        ~CustomStyle() {}

        void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                           QPainter *painter, const QWidget *widget) const;
    };

    void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                                    QPainter *painter, const QWidget *widget) const
    {
        if (element == PE_IndicatorSpinUp || element == PE_IndicatorSpinDown) {
            QPointArray points(3);
            int x = option->rect.x();
            int y = option->rect.y();
            int w = option->rect.width() / 2;
            int h = option->rect.height() / 2;
            x += (option->rect.width() - w) / 2;
            y += (option->rect.height() - h) / 2;

            if (element == PE_IndicatorSpinUp) {
                points[0] = QPoint(x, y + h);
                points[1] = QPoint(x + w, y + h);
                points[2] = QPoint(x + w / 2, y);
            } else { // PE_SpinBoxDown
                points[0] = QPoint(x, y);
                points[1] = QPoint(x + w, y);
                points[2] = QPoint(x + w / 2, y + h);
            }

            if (option->state & Style_Enabled) {
                painter->setPen(option->palette.mid().color());
                painter->setBrush(option->palette.buttonText());
            } else {
                painter->setPen(option->palette.buttonText().color());
                painter->setBrush(option->palette.mid());
            }
            painter->drawPolygon(points);
        } else {
            QWindowsStyle::drawPrimitive(element, option, painter, widget);
        }
    }

See also the Styles Example for a more detailed description of how custom styles can be created.

Comparison with Qt 3

The QStyle class has a similar API in Qt 4 as in Qt 3, with more or less the same functions. What has changed is the signature of the functions and the role played by QStyleOption. For example, here's the signature of the QStyle::drawControl() function in Qt 3:

    void drawControl(ControlElement element,
                     QPainter *painter,
                     const QWidget *widget,
                     const QRect &rect,
                     const QColorGroup &colorGroup,
                     SFlags how = Style_Default,
                     const QStyleOption &option = QStyleOption::Default) const;

Here's the signature of the same function in Qt 4:

    void drawControl(ControlElement element,
                     const QStyleOption *option,
                     QPainter *painter,
                     const QWidget *widget = 0) const;

In Qt 3, some of the information required to draw a graphical element was stored in a QStyleOption parameter, while the rest was deduced by querying the widget. In Qt 4, everything is stored in the QStyleOption parameter.

[Previous: The Network Module in Qt 4] [Home] [Next: Thread Support in Qt 4]

Publicité

Best Of

Actualités les plus lues

Semaine
Mois
Année
  1. « Quelque chose ne va vraiment pas avec les développeurs "modernes" », un développeur à "l'ancienne" critique la multiplication des bibliothèques 94
  2. Apercevoir la troisième dimension ou l'utilisation multithreadée d'OpenGL dans Qt, un article des Qt Quarterly traduit par Guillaume Belz 0
  3. Pourquoi les programmeurs sont-ils moins payés que les gestionnaires de programmes ? Manquent-ils de pouvoir de négociation ? 43
  4. Les développeurs ignorent-ils trop les failles découvertes dans leur code ? Prenez-vous en compte les remarques des autres ? 17
  5. Quelles nouveautés de C++11 Visual C++ doit-il rapidement intégrer ? Donnez-nous votre avis 10
  6. Qt Commercial : Digia organise un webinar gratuit le 27 mars sur la conception d'interfaces utilisateur et d'applications avec le framework 0
  7. 2017 : un quinquennat pour une nouvelle version du C++ ? Possible, selon Herb Sutter 9
Page suivante

Le Qt Developer Network au hasard

Logo

Les composants

Le Qt Developer Network est un réseau de développeurs Qt anglophone, où ils peuvent partager leur expérience sur le framework. Lire l'article.

Communauté

Ressources

Liens utiles

Contact

  • Vous souhaitez rejoindre la rédaction ou proposer un tutoriel, une traduction, une question... ? Postez dans le forum Contribuez ou contactez-nous par MP ou par email (voir en bas de page).

Qt dans le magazine

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.1
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 !
 
 
 
 
Partenaires

Hébergement Web