Qt 2D drawing: basic graphics drawing and gradient filling

Qt provides a powerful 2D drawing system that can use the same API to draw on screens and drawing devices. It is mainly based on the three classes QPainter, QPaintDevice and QPaintEngine. The relationship between them is shown in the figure below:

  • QPainter is used to perform drawing operations;
  • QPaintEngine provides some interfaces that can be used for QPainter to draw on different devices;
  • QPaintDevice provides a drawing device, which is an abstraction of a two-dimensional space on which QPainter can be used to draw.

The specific drawing operation is done by QPainter in the drawing system, which provides a large number of highly optimized functions to complete most of the drawing work required by GUI programming. QPainter can draw all desired graphics, from the simplest straight line to any other complex graphics, and can also be used to draw text and pictures. QPainter can draw on any object that inherits from the QPaintDevice class.

QPainter generally draws in the processing function paintEvent () of a component redrawing event (PaintEvent) , first creates a QPainter object (brush), then draws graphics, and finally destroys the QPainter object.

1. Drawing of basic graphics

Some convenient functions are provided in QPainter to draw commonly used graphics, and you can also set the brush for lines and borders and the brush for filling.

Create a new Qt Gui application, the project name is myDrawing, the base class is QWidget, and the class name is Widget. After the establishment is complete, declare the redraw event handler function in the widget.h file:

protected:
    void paintEvent(QPaintEvent *);

Then add the header file #include <QPainter> to the widget.cpp file.

The benefits of this article, the fee to receive Qt development learning materials package, technical video, content includes (C++ language foundation, Qt programming introduction, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project combat, QSS, OpenCV, Quick module, interview questions, etc.) ↓↓↓↓↓↓ See below

1.1 Drawing graphics

In the widget.cpp file, define the paintEvent() function as follows:

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    //绘制线条
    painter.drawLine(QPoint(0, 0), QPoint(100, 100));
}

Here, a QPainter object is first created, using the QPainter::QPainter(QPaintDevice *device) constructor, and specifying this as the drawing device, which means drawing on the part. Objects created using this constructor will immediately start drawing on the device, automatically call the begin() function, and then call the end() function in the QPainter destructor to end the drawing.

If you don't want to specify the drawing device when constructing the QPainter object, you can use the constructor without parameters, and then use QPainter::begin (QPaintDevice *device) to specify the drawing device when starting to draw, and then call the end() function to end the drawing after the drawing is completed. The code in the function above is equivalent to:

QPainter painter;
painter.begin(this);
painter.drawLine(QPoint(0, 0), QPoint(100, 100));
painter.end();

These two methods can complete the drawing, no matter which method is used, the drawing device must be specified, otherwise the drawing will not be possible. The second line of code uses the drawLine() function to draw a line segment. Here, an overloaded form of the function QPainter::drawLine ( const QPoint & p1, const QPoint & p2 ) is used, where p1 and p2 are the starting point and end point of the line segment, respectively. The QPoint(0, 0) here is the origin of the window, and the default is the upper left corner of the window (excluding the title bar). Results as shown below.

 

In addition to drawing simple lines, QPainter also provides some functions for drawing other commonly used graphics, and the most commonly used ones are shown in the following table.

function

Function

drawArc()

draw arc

drawChord()

draw string

drawConvexPolygon()

draw a convex polygon

drawEllipse()

draw an ellipse

drawLine()

draw lines

drawPie()

draw sector

drawPoint()

draw points

drawPolygon()

draw polygon

drawPolyline()

draw polyline

drawRect()

draw rectangle

drawRoundedRect()

Draw a rounded rectangle

In addition, we position the cursor on the QPainter class name, and then press the F1 button on the keyboard, then it will automatically jump to the help page of this class. Of course, you can also go to the help mode and directly index to find the class name. In the help, we can see many related drawing functions, as shown in the figure below.

 

If we click on a function name at will, we will jump to the introduction paragraph of the function. For example, when we click the drawEllipse() function, we jump to the introduction of the function, and an example is provided above. As shown below. We can directly copy the code in the example into the paintEvent() function to test the effect.

 

1.2 Using brushes

QPen defines how QPainter should draw lines or outlines. The brush has properties such as style style(), width width(), brush brush(), cap style capStyle() and connection style joinStyle(). First introduce the constructor of the QPen class:

QPen(const QBrush &brush, qreal width, Qt::PenStyle s = Qt::SolidLine,
         Qt::PenCapStyle c = Qt::SquareCap, Qt::PenJoinStyle j = Qt::BevelJoin);
  • The brush brush() is used to fill the lines drawn by the brush.
  • The brush style style() defines the style of the line.
  • The pen cap style capStyle() defines the end of the line drawn with QPainter;
  • The connection style joinStyle() defines how two lines are connected.
  • Brush width width() or widthF() defines the width of the brush. Note that there are no lines with a width of 0. Suppose you set width to 0, QPainter will still draw a line, and the width of this line is 1 pixel.

So many parameters can be specified at the time of construction, or can be specified with the set function, it depends entirely on your habits. Various settings can be easily modified using the setWidth(), setBrush(), setCapStyle() and setJoinStyle() functions.

brush style

 

Then change the content of the paintEvent() function as follows:

void Widget::paintEvent(QPaintEvent *)
{
    //创建画笔
    QPen pen(Qt::green, 5, Qt::DotLine, Qt::RoundCap, Qt::RoundJoin);
    //使用画笔绘制圆弧
    painter.setPen(pen);
    QRectF rectangle(70.0, 40.0, 80.0, 60.0);
    int startAngle = 30 * 16;
    int spanAngle = 120 * 16;
    painter.drawArc(rectangle, startAngle, spanAngle);
}

After creating the brush above, use setPen() to set the brush for the painter, and then use the brush to draw an arc. An overloaded form of the drawing arc function is QPainter::drawArc ( const QRectF & rectangle, int startAngle, int spanAngle ), where the three parameters correspond to the rectangle where the arc needs to be specified, the starting angle and the spanning angle, as shown in the figure below.

QRectF:: QRectF (qreal x, qreal y, qreal width, qreal height) can use floating-point numbers as parameters to determine a rectangle, which needs to specify the coordinates (x, y) of the upper left corner, width and height. If you just want to use integers to define a rectangle, you can use the QRect class. The value of the angle here is the actual degree multiplied by 16. On the clock dial, 0 degrees points to the position of 3 o'clock. If the angle value is positive, it means counterclockwise rotation. If the angle value is negative, it means clockwise rotation. The value of the whole circle is 5760 (ie 360X16).

 

1.3 Using brushes

The QBrush class provides brushes to fill graphics. A brush is defined using its color and style (such as its fill mode). First introduce the constructor of the QBrush class:

QBrush(const QColor &color, Qt::BrushStyle bs=Qt::SolidPattern);

The colors used in Qt are generally represented by the QColor class, which supports color models such as RGB, HSV, and CMYK. If there are three parameters in it, then they are the values ​​of the red, green, and blue components, which are often referred to as rgb, and the value range is 0-255. For example, (255, 0, 0) here means that the red component is 255, and the other components are 0, so the output is red. If there are four parameters, the last parameter alpha is to set the transparency, and the value range is also 0-255, 0 means completely transparent, and 255 means completely opaque. There are also 20 predefined colors in Qt, as shown in the figure below.

 

The filling mode of the QBrush style is defined by the Qt::BrushStyle enumeration variable, which includes basic pattern filling, gradient filling and texture filling. All enumeration variables are shown in the figure below. The default style is Qt::NoBrush (depending on how you build the brush), which does not fill the shape. The standard fill style is Qt::SolidPattern. There are two ways to set the brush style, one is to use the constructor, and the other is to use the setstyle function.

 

Then change the content of the paintEvent() function as follows:

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPen pen; //画笔
    pen.setColor(QColor(255, 0, 0));
    QBrush brush(QColor(0, 255, 0, 125)); //画刷
    painter.setPen(pen); //添加画笔
    painter.setBrush(brush); //添加画刷
    painter.drawRect(50, 50, 200, 100); //绘制矩形
}

A brush QPen and a brush QBrush are newly created here. Among them, the brush uses the setColor() function to set the color for it, and the brush is the color directly set for it when it is built. Then we set the pen and brush to the painter, and use drawRect() to draw a rectangle whose upper left corner is at (50, 50), with a width of 200 and a height of 100. Run the program, the effect is shown in the figure below.

 

2. Gradient fill

Gradient fills can also be used in brushes. The QGradient class is used to specify gradient fills with QBrush. Qt now supports three types of gradient fills:

  • A linear gradient interpolates colors between the start and end points;
  • Radial gradients interpolate colors between the focal point and the ring surrounding it;
  • Conical gradients (Conical) interpolate colors around the center of a circle.

These three gradients are represented by three subclasses of QGradient, QLinearGradient represents a linear gradient, QRadialGradient represents a radial gradient, and QConicalGradient represents a conical gradient.

(1) Linear Gradient

QLinearGradient::QLinearGradient ( const QPointF & start, const QPointF & finalStop )

Linear gradients need to specify the starting point Start and the end point finalstop , and then equalize the area between the starting point and the end point. The position of the starting point is 0.0, the position of the end point is 1.0. The position between them is set at the distance ratio, and then uses the QGRADIENT :: Setcolorat (QREAL POSITION, Const QCOLORJ & The color) function is in the specified color color in the specified position. Of course, the value of the posity here is between 0 and 1
.

Here you can also use the setSpread() function to set the filling diffusion method, that is, specify how to fill in areas other than the specified area. The spread method is defined by the QGradient::Spread enumeration variable, which has 3 values ​​in total, namely QGradiem::PadSpread, which is filled with the closest color, which is the default value; QGradient::ReflectSpread will reflect the gradient outside the gradient area; QGradiem::RepeatSpread repeats the gradient outside the gradient area. To use gradient fill, you can use it directly in setBrush(), then the brush style will be automatically set to the corresponding gradient fill. The effect of these three diffusion methods in the linear gradient is shown in the figure below.

 

(2) Radiant Gradient

QRadialGradient::QRadialGradient ( const QPointF & center, qreal radius, const QPointF & focalPoint )

The radial gradient needs to specify the center of the circle and the radius radius, so that a circle is determined, and then a focal point is specified. The position of the focus is 0, the position of the ring is 1, and then the color is interpolated between the focus and the ring. The radiation gradient can also use the setSpread() function to set the spread mode of the area outside the gradient area. The effects of the three spread modes are shown in the figure below.

 

(3) Conical Gradient

QConicalGradient::QConicalGradient ( const QPointF & center, qreal angle )

The tapered gradient needs to specify the center point center and an angle angle (the value is between 0 and 360), and then start to interpolate the color around the center point counterclockwise from the given angle. The angle given here is 0 at the beginning of the counterclockwise direction and 1 after one rotation. The setSpread() function has no effect on tapered gradients.

(4) Sample program

The sample program is as follows:

void Widget::paintEvent(QPaintEvent *)
{
    //线性渐变
    QLinearGradient linearGradient(QPointF(40, 190),QPointF(70, 190));
    //插入颜色
    linearGradient.setColorAt(0, Qt::yellow);
    linearGradient.setColorAt(0.5, Qt::red);
    linearGradient.setColorAt(1, Qt::green);
    //指定渐变区域以外的区域的扩散方式
    linearGradient.setSpread(QGradient::RepeatSpread);
    //使用渐变作为画刷
    QPainter painter(this);
    painter.setBrush(linearGradient);
    painter.drawRect(100, 100, 90, 40);

    //辐射渐变
    QRadialGradient radialGradient(QPointF(100, 190),50,QPointF(275,200));
    radialGradient.setColorAt(0, QColor(255, 255, 100, 150));
    radialGradient.setColorAt(1, QColor(0, 0, 0, 50));
    painter.setBrush(radialGradient);
    painter.drawEllipse(QPointF(100, 200), 50, 50);

    //锥形渐变
    QConicalGradient conicalGradient(QPointF(250, 190), 60);
    conicalGradient.setColorAt(0.2, Qt::cyan);
    conicalGradient.setColorAt(0.9, Qt::black);
    painter.setBrush(conicalGradient);
    painter.drawEllipse(QPointF(250, 200), 50, 50);
}

Execute the program, the effect is as follows:

The article is transferred from the blog garden (fengMisaka): Qt 2D drawing one: basic graphics drawing and gradient filling

The benefits of this article, the fee to receive Qt development learning materials package, technical video, content includes (C++ language foundation, Qt programming introduction, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project combat, QSS, OpenCV, Quick module, interview questions, etc.) ↓↓↓↓↓↓ See below

Guess you like

Origin blog.csdn.net/QtCompany/article/details/131816784