📄 qpainter.cpp
字号:
function that draws the outline of the given path (i.e. strokes the path). See also the \l {demos/deform}{Vector Deformation} demo which shows how to use advanced vector techniques to draw text using a QPainterPath, the \l {demos/gradients}{Gradients} demo which shows the different types of gradients that are available in Qt, and the \l {demos/pathstroke}{Path Stroking} demo which shows Qt's built-in dash patterns and shows how custom patterns can be used to extend the range of available patterns. \table \row \o \inlineimage qpainter-vectordeformation.png \o \inlineimage qpainter-gradients.png \o \inlineimage qpainter-pathstroking.png \header \o \l {demos/deform}{Vector Deformation} \o \l {demos/gradients}{Gradients} \o \l {demos/pathstroke}{Path Stroking} \endtable There are functions to draw pixmaps/images, namely drawPixmap(), drawImage() and drawTiledPixmap(). Both drawPixmap() and drawImage() produce the same result, except that drawPixmap() is faster on-screen while drawImage() may be faster on a QPrinter or other devices. Text drawing is done using drawText(). When you need fine-grained positioning, boundingRect() tells you where a given drawText() command will draw. There is a drawPicture() function that draws the contents of an entire QPicture. The drawPicture() function is the only function that disregards all the painter's settings as QPicture has its own settings. \section1 Rendering Quality To get the optimal rendering result using QPainter, you should use the platform independent QImage as paint device; i.e. using QImage will ensure that the result has an identical pixel representation on any platform. The QPainter class also provides a means of controlling the rendering quality through its RenderHint enum and the support for floating point precision: All the functions for drawing primitives has a floating point version. These are often used in combination with the \l {RenderHint}{QPainter::AntiAliasing} render hint. \table 100% \row \o \inlineimage qpainter-concentriccircles.png \o \bold {Concentric Circles Example} The \l {painting/concentriccircles}{Concentric Circles} example shows the improved rendering quality that can be obtained using floating point precision and anti-aliasing when drawing custom widgets. The application's main window displays several widgets which are drawn using the various combinations of precision and anti-aliasing. \endtable The RenderHint enum specifies flags to QPainter that may or may not be respected by any given engine. \l {RenderHint}{QPainter::AntiAliasing} indicates that the engine should antialias edges of primitives if possible, \l {RenderHint}{QPainter::TextAntialiasing} indicates that the engine should antialias text if possible, and the \l {RenderHint}{QPainter::SmoothPixmapTransform} indicates that the engine should use a smooth pixmap transformation algorithm. \l {RenderHint}{HighQualityAntialiasing} is an OpenGL-specific rendering hint indicating that the engine should use fragment programs and offscreen rendering for antialiasing. The renderHints() function returns a flag that specifies the rendering hints that are set for this painter. Use the setRenderHint() function to set or clear the currently set RenderHints. \section1 Coordinate Transformations Normally, the QPainter operates on the device's own coordinate system (usually pixels), but QPainter has good support for coordinate transformations. \table \row \o \inlineimage qpainter-clock.png \o \inlineimage qpainter-rotation.png \o \inlineimage qpainter-scale.png \o \inlineimage qpainter-translation.png \header \o nop \o rotate() \o scale() \o translate() \endtable The most commonly used transformations are scaling, rotation, translation and shearing. Use the scale() function to scale the coordinate system by a given offset, the rotate() function to rotate it clockwise and translate() to translate it (i.e. adding a given offset to the points). You can also twist the coordinate system around the origin using the shear() function. See the \l {demos/affine}{Affine Transformations} demo for a visualization of a sheared coordinate system. See also the \l {painting/transformations}{Transformations} example which shows how transformations influence the way that QPainter renders graphics primitives. In particular it shows how the order of transformations affects the result. \table 100% \row \o \bold {Affine Transformations Demo} The \l {demos/affine}{Affine Transformations} demo show Qt's ability to perform affine transformations on painting operations. The demo also allows the user to experiment with the transformation operations and see the results immediately. \o \inlineimage qpainter-affinetransformations.png \endtable All the tranformation operations operate on the transformation worldMatrix(). A matrix transforms a point in the plane to another point. For more information about the transformation matrix, see the \l {The Coordinate System} and QMatrix documentation. The setWorldMatrix() function can replace or add to the currently set worldMatrix(). The resetMatrix() function resets any transformations that were made using translate(), scale(), shear(), rotate(), setWorldMatrix(), setViewport() and setWindow() functions. The deviceMatrix() returns the matrix that transforms from logical coordinates to device coordinates of the platform dependent paint device. The latter function is only needed when using platform painting commands on the platform dependent handle, and the platform does not do transformations nativly. When drawing with QPainter, we specify points using logical coordinates which then are converted into the physical coordinates of the paint device. The mapping of the logical coordinates to the physical coordinates are handled by QPainter's combinedMatrix(), a combination of viewport() and window() and worldMatrix(). The viewport() represents the physical coordinates specifying an arbitrary rectangle, the window() describes the same rectangle in logical coordinates, and the worldMatrix() is identical with the transformation matrix. See also \l {The Coordinate System} documentation. \section1 Clipping QPainter can clip any drawing operation to a rectangle, a region, or a vector path. The current clip is available using the functions clipRegion() and clipPath(). Whether paths or regions are preferred (faster) depends on the underlying paintEngine(). For example, the QImage paint engine prefers paths while the X11 paint engine prefers regions. Setting a clip is done in the painters logical coordinates. After QPainter's clipping, the paint device may also clip. For example, most widgets clip away the pixels used by child widgets, and most printers clip away an area near the edges of the paper. This additional clipping is not reflected by the return value of clipRegion() or hasClipping(). \section1 Composition Modes \target Composition Modes QPainter provides the CompositionMode enum which defines the Porter-Duff rules for digital image compositing; it describes a model for combining the pixels in one image, the source, with the pixels in another image, the destination. The two most common forms of composition are \l {QPainter::CompositionMode}{Source} and \l {QPainter::CompositionMode}{SourceOver}. \l {QPainter::CompositionMode}{Source} is used to draw opaque objects onto a paint device. In this mode, each pixel in the source replaces the corresponding pixel in the destination. In \l {QPainter::CompositionMode}{SourceOver} composition mode, the source object is transparent and is drawn on top of the destination. Note that composition transformation operates pixelwise. For that reason, there is a difference between using the grahic primitive itself and its bounding rectangle: The bounding rect contains pixels with alpha == 0 (i.e the pixels surrounding the primitive). These pixels will overwrite the other image's pixels, affectively clearing those, while the primitive only overwrites its own area. \table 100% \row \o \inlineimage qpainter-compositiondemo.png \o \bold {Composition Modes Demo} The \l {demos/composition}{Composition Modes} demo, available in Qt's demo directory, allows you to experiment with the various composition modes and see the results immediately. \endtable \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example}*//*! \enum QPainter::RenderHint Renderhints are used to specify flags to QPainter that may or may not be respected by any given engine. \value Antialiasing Indicates that the engine should antialias edges of primitives if possible. \value TextAntialiasing Indicates that the engine should antialias text if possible. \value SmoothPixmapTransform Indicates that the engine should use a smooth pixmap transformation algorithm (such as bilinear) rather than nearest neighbor. \value HighQualityAntialiasing An OpenGL-specific rendering hint indicating that the engine should use fragment programs and offscreen rendering for antialiasing. \sa renderHints(), setRenderHint(), {QPainter#Rendering Quality}{Rendering Quality}, {Concentric Circles Example}*//*! Constructs a painter. \sa begin(), end()*/QPainter::QPainter(){ d_ptr = new QPainterPrivate(this); d_ptr->init();}/*! \fn QPainter::QPainter(QPaintDevice *device) Constructs a painter that begins painting the paint \a device immediately. This constructor is convenient for short-lived painters, e.g. in a QWidget::paintEvent() and should be used only once. The constructor calls begin() for you and the QPainter destructor automatically calls end(). Here's an example using begin() and end(): \code void MyWidget::paintEvent(QPaintEvent *) { QPainter p; p.begin(this); p.drawLine(...); // drawing code p.end(); } \endcode The same example using this constructor: \code void MyWidget::paintEvent(QPaintEvent *) { QPainter p(this); p.drawLine(...); // drawing code } \endcode Since the constructor cannot provide feedback when the initialization of the painter failed you should rather use begin() and end() to paint on external devices, e.g. printers. \sa begin(), end()*/QPainter::QPainter(QPaintDevice *pd){ d_ptr = new QPainterPrivate(this); d_ptr->init(); Q_ASSERT(pd != 0); begin(pd);}/*! Destroys the painter.*/QPainter::~QPainter(){ if (isActive()) end(); delete d_ptr;}/*! Returns the paint device on which this painter is currently painting, or 0 if the painter is not active. \sa isActive()*/QPaintDevice *QPainter::device() const{ Q_D(const QPainter); return d->original_device;}/*! Returns true if begin() has been called and end() has not yet been called; otherwise returns false. \sa begin(), QPaintDevice::paintingActive()*/bool QPainter::isActive() const{ Q_D(const QPainter); return d->engine && d->engine->isActive();}/*! Initializes the painters pen, background and font to the same as the given \a widget. Call this function after begin() while the painter is active. \sa begin(), {QPainter#Settings}{Settings}*/void QPainter::initFrom(const QWidget *widget){ Q_ASSERT_X(widget, "QPainter::initFrom(const QWidget *widget)", "Widget cannot be 0"); if (!isActive()) { qWarning("QPainter::initFrom: Painter not active, aborted"); return; } const QPalette &pal = widget->palette(); Q_D(QPainter); d->state->pen = QPen(pal.brush(widget->foregroundRole()), 0); d->state->bgBrush = pal.brush(widget->backgroundRole()); d->state->deviceFont = QFont(widget->font(), d->device); d->state->font = d->state->deviceFont; if (d->engine) { d->engine->setDirty(QPaintEngine::DirtyPen); d->engine->setDirty(QPaintEngine::DirtyBrush); d->engine->setDirty(QPaintEngine::DirtyFont); } d->state->layoutDirection = widget->layoutDirection();}/*! Saves the current painter state (pushes the state onto a stack). A save() must be followed by a corresponding restore(); the end() function unwinds the stack. \sa restore()*/void QPainter::save(){#ifdef QT_DEBUG_DRAW if (qt_show_painter_debug_output) printf("QPainter::save()\n");#endif if (!isActive()) { qWarning("QPainter::save: Painter not active"); return; } Q_D(QPainter); d->updateState(d->state); d->state = new QPainterState(d->states.back()); d->states.push_back(d->state); d->engine->state = d->state;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -