The Qt drawing system allows the same API to be used to draw on screens and other printing devices. The entire drawing system QPainter
is based on, QPainterDevice
and QPaintEngine
three classes.
QPainter
An abstraction of a two-dimensional space, a two-dimensional space that QPaintDevice
allows QPainter
drawing on top of it, that is, QPainter
the work space, and QPaintEngine
provides a QPainter
uniform interface for drawing brushes () on different devices. QPaintEngine
classes are applied to QPainter
and QPaintDevice
between, and are usually transparent to the developer. Unless you need to customize a device, you don't need to care about QPaintEngine
this class. We can interpret it as a brush, as a QPainter
QPaintDevice
place to use brushes, such as paper, screen, etc., and for paper and screen, we must draw with different brushes, in order to unify the use of a brush, we have designed the QPaintEngine
class, which allows different paper, A brush can be used on the screen.
Gives the hierarchy between the three classes (from the Qt API documentation):
The above tells us that Qt's drawing system is actually used to QPainter
QPainterDevice
draw on, using communication between them QPaintEngine
( QPainter
that is, translating instructions).
Below we use an example to introduce QPainter
:
12345678910 |
//!!! Qt4/qt5class paintedwidget : Public qwidget { q_object public: paintedwidget(qwidget *parent = 0); protected: void paintevent(qpaintevent *); }; |
Notice the function we have rewritten QWidget
paintEvent()
. This is perhaps the first practical application after we have understood the Qt event system. Next is PaintedWidget
the source code:
12345678910111213141516171819 |
//!!! Qt4/qt5paintedwidget::paintedwidget(qwidget *parent) : Qwidget(parent) { Resize(+ ); setwindowtitle(tr("Paint Demo")); } void paintedwidget::paintevent(qpaintevent *) { qpainter painter(this); painter. DrawLine(650, max ); painter. Setpen(Qt::red); painter.drawrect (10, 10, 100, 400 painter. Setpen(qpen(Qt::green, 5)); painter. Setbrush(Qt::blue); painter. DrawEllipse(a ); } |
In the constructor, we just set the size and caption of the window. And the paintEvent()
function is the code that is drawn. First, we create an object on the stack, which means that the QPainter
object is rebuilt every time the paintEvent()
function is run QPainter
. Note that this may cause some detail problems: as we rebuild each time, the QPainter
brush color, state, etc. set at the first run are lost when the second entry is made to this function. Sometimes we want to save the brush state, we have to save the data ourselves, otherwise we need to be a QPainter
member variable of the class.
QPainter
Receives a QPaintDevice
pointer as a parameter. QPaintDevice
There are many subclasses, for example QImage
, as well QWidget
. Remember that QPaintDevice
you can understand where to draw, and now we want to draw in this component, so the pass is the this pointer.
QPainter
There are a lot of functions that start with draw, which are used for drawing various shapes, such as here drawLine()
, drawRect()
and drawEllipse()
so on. The property that is used when drawing the contour line QPainter
pen()
. For example, if we call to painter.setPen(Qt::red)
set the pen to red, the rectangle drawn below has a red outline. Next, we'll change the pen to green, 5 like wide ( painter.setPen(QPen(Qt::green, 5))
), and set the paint brush to blue. When the draw function is called again, it is an ellipse with a green 5-pixel wide outline and a blue fill.
Run our program to see the final effect:
We'll cover the properties of brushes and brushes in more detail later in this chapter QPen
QBrush
.
Also, note that our drawing order, first is the line, then the rectangle, and finally the ellipse. In this drawing order, you can see that the line is the first drawing, at the bottom layer, and the rectangle is the second drawing, in the middle layer; the ellipse is the last to be drawn, at the top.
If you know OpenGL, you must have heard the phrase: OpenGL is a state machine. The so-called state machine, that is, OpenGL saves only a variety of states. For example, if you set the brush color to red, the color will always be red unless you reset the other color. QPainter
also, its state does not recover itself unless you use a variety of setup functions. So if, in the code above, we draw a rectangle after the ellipse is drawn, it will also have a green 5-pixel contour and a blue fill, unless you explicitly call the SET function to update the state. This is how most drawing systems are implemented, including OpenGL, QPainter
and java2d. Just because QPainter
it is a state machine, will lead us to the previous introduction of a detail problem: because paintEvent()
it is necessary to repeat the entry, it is necessary to pay attention to the second entry, QPainter
the state is not the same as the first time, otherwise it may cause flashing phenomenon. This flicker is not due to a double-buffering problem, but rather because of the fast switching of the drawing state.
QT Learning Path: Introduction to QT Mapping system