Game Programming using Qt 5 Beginner's Guide
上QQ阅读APP看书,第一时间看更新

Pens and brushes

The pen and brush are two attributes that define how different drawing operations are performed. The pen (represented by the QPen class) defines the outline, and the brush  (represented by the QBrush class) fills the drawn shapes. Each of them is really a set of parameters. The most simple one is the color defined, either as a predefined global color enumeration value (such as Qt::red or Qt::transparent), or an instance of the QColor class. The effective color is made up of four attributes: three color components (red, green, and blue) and an optional alpha channel value that determines the transparency of the color (the larger the value, the more opaque the color). By default, all components are expressed as 8-bit values (0 to 255) but can also be expressed as real values representing a percentage of the maximum saturation of the component; for example, 0.6 corresponds to 153 (0.6?255). For convenience, one of the QColor constructors accepts hexadecimal color codes used in HTML (with #0000FF being an opaque blue color) or even bare color names (for example, blue) from a predefined list of colors returned by a static function—QColor::colorNames(). Once a color object is defined using RGB components, it can be queried using different color spaces (for example, CMYK or HSV). Also, a set of static methods are available that act as constructors for colors expressed in different color spaces.

For example, to construct a clear magenta color any of the following expressions can be used:

  • QColor("magenta")
  • QColor("#FF00FF")
  • QColor(255, 0, 255)
  • QColor::fromRgbF(1, 0, 1)
  • QColor::fromHsv(300, 255, 255)
  • QColor::fromCmyk(0, 255, 0, 0)
  • Qt::magenta

Apart from the color, QBrush has two additional ways of expressing the fill of a shape. You can use QBrush::setTexture() to set a pixmap that will be used as a stamp or QBrush::setGradient() to make the brush use a gradient to do the filling. For example, to use a gradient that goes diagonally and starts as yellow in the top-left corner of the shape, becomes red in the middle of the shape, and ends as magenta at the bottom-right corner of the shape, the following code can be used:

QLinearGradient gradient(0, 0, width, height);
gradient.setColorAt(0,   Qt::yellow);
gradient.setColorAt(0.5, Qt::red);
gradient.setColorAt(1.0, Qt::magenta);
QBrush brush = gradient; 

When used with drawing a rectangle, this code will give the following output:

Qt can handle linear (QLinearGradient), radial (QRadialGradient), and conical (QConicalGradient) gradients. Qt provides a Gradients example (shown in the following screenshot) where you can see different gradients in action:

As for the pen, its main attribute is its width (expressed in pixels), which determines the thickness of the shape outline. A pen can, of course, have a color set but, in addition to that, you can use any brush as a pen. The result of such an operation is that you can draw thick outlines of shapes using gradients or textures.

There are three more important properties for a pen. The first is the pen style, set using QPen::setStyle(). It determines whether lines drawn by the pen are continuous or divided in some way (dashes, dots, and so on). You can see the available line styles here:

                                     

The second attribute is the cap style, which can be flat, square, or round. The third attribute—the join style—is important for polyline outlines and dictates how different segments of the polyline are connected. You can make the joins sharp (with Qt::MiterJoin or Qt::SvgMiterJoin), round (Qt::RoundJoin), or a hybrid of the two (Qt::BevelJoin). You can see the different pen attribute configurations (including different join and cap styles) in action by launching the Path Stroking example shown in the following screenshot: