mirror of https://github.com/qt/qtdoc.git
Graphics 2D docs
This adds an overview of 2D graphics in Qt and how they compare to each other. There are many tools for this in Qt and they all have their place. This will hopefully help users navigate the forest. Pick-to: 6.10 Fixes: QTBUG-137101 Change-Id: I855c5db8f6f1efe34cfbeecd0d2e05703bc124da Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
This commit is contained in:
parent
913aca0b95
commit
9438576ce4
Binary file not shown.
After Width: | Height: | Size: 143 KiB |
Binary file not shown.
After Width: | Height: | Size: 145 KiB |
Binary file not shown.
After Width: | Height: | Size: 215 KiB |
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
Binary file not shown.
After Width: | Height: | Size: 215 KiB |
|
@ -56,6 +56,11 @@ deploy on a platform that have a specific graphics API. Visit the
|
||||||
{Rendering via the Qt Rendering Hardware Interface}
|
{Rendering via the Qt Rendering Hardware Interface}
|
||||||
page on how to set the render path in QQuickWindow.
|
page on how to set the render path in QQuickWindow.
|
||||||
|
|
||||||
|
\section1 2D Graphics
|
||||||
|
|
||||||
|
Qt has multiple different APIs for drawing 2D graphics primitives. See the separate page about
|
||||||
|
\l{2D Graphics in Qt} for an overview of the possibilities here.
|
||||||
|
|
||||||
\section1 3D Graphics with Qt Quick 3D
|
\section1 3D Graphics with Qt Quick 3D
|
||||||
|
|
||||||
\l{Qt Quick 3D} is an add-on that provides a high-level API for creating 3D
|
\l{Qt Quick 3D} is an add-on that provides a high-level API for creating 3D
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
// Copyright (C) 2025 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page topics-graphics2d.html
|
||||||
|
\title 2D Graphics in Qt
|
||||||
|
\keyword topics-graphics2d
|
||||||
|
\brief Qt's 2D graphics features
|
||||||
|
\ingroup explanations-graphicsandmultimedia
|
||||||
|
|
||||||
|
Two-dimensional graphics is at the core of Qt's user interface capabilities. This page provides
|
||||||
|
an overview of the tools and APIs at your disposal for rendering your own 2D graphics. It also aims
|
||||||
|
to clarify the difference between APIs that perform similar tasks.
|
||||||
|
|
||||||
|
This is a high-level overview, focusing on the direct ways to render graphics primitives such as
|
||||||
|
circles, rectangles, complex shapes and images. For a low-level view of Qt graphics internals, see
|
||||||
|
the \l{Graphics}{graphics overview documentation}.
|
||||||
|
|
||||||
|
Qt also includes high-end \l{Qt Quick 3D}{3D rendering capabilities} with its own set of APIs and
|
||||||
|
tools. The focus in the following overview will be on two-dimensional graphics, so \l{Qt Quick 3D}
|
||||||
|
and related components will not be covered here.
|
||||||
|
|
||||||
|
\section1 Qt Quick
|
||||||
|
|
||||||
|
\l{Qt Quick} has the tools for rendering hardware-accelerated and animated 2D graphics. It serves
|
||||||
|
as the basis for the rich UI components in \l{Qt Quick Controls}.
|
||||||
|
|
||||||
|
The Qt Quick module provides essential primitives such as \l{Rectangle}{rectangles}, \l{Text}{text}
|
||||||
|
and \l{Image}{images}. These are typically the foundation of a two-dimensional user interface.
|
||||||
|
|
||||||
|
User interfaces in Qt Quick can be transformed and animated at a low performance overhead, and this
|
||||||
|
promise lies at the core of the module. The API is declarative, which allows Qt to optimize how
|
||||||
|
graphics are stored, rendered and how animation updates are managed.
|
||||||
|
|
||||||
|
\section2 Qt Quick Shapes
|
||||||
|
|
||||||
|
In addition to the basic primitives, Qt Quick has APIs for rendering more complex shapes. These can
|
||||||
|
be accessed by importing the \l{Qt Quick Shapes QML Types}{Qt Quick Shapes} module in your code.
|
||||||
|
|
||||||
|
Qt Quick Shapes allows you to construct arbitrary \l{ShapePath}{paths} from path operations such as
|
||||||
|
\l{PathMove}{move-to}, \l{PathLine}{line-to}, \l{PathCubic}{cubic-to} and \l{PathArc}{arc-to}.
|
||||||
|
|
||||||
|
Each path can have a stroke defined by a rich set of options. In addition, it can be filled with
|
||||||
|
either a solid color, a gradient, an image, or even another Qt Quick item.
|
||||||
|
|
||||||
|
\image 2dgraphics/tiger.png
|
||||||
|
|
||||||
|
The \l{Qt Quick Examples - Shapes}{Qt Quick Shapes example} shows how the classic GhostScript tiger
|
||||||
|
can be rendered using paths constructed with Qt Quick Shapes.
|
||||||
|
|
||||||
|
\section3 Curve renderer
|
||||||
|
|
||||||
|
By default, Qt Quick Shapes relies on multi-sampling for antialiasing. In addition, curves are
|
||||||
|
flattened to short line segments, and this can be visible if you zoom the shape. By setting the
|
||||||
|
\l{Shape} item's \l{Shape::preferredRendererType}{preferredRendererType} property to
|
||||||
|
\c{Shape.CurveRenderer}, a different renderer will be used internally. This curve renderer solves
|
||||||
|
the curves on the GPU itself and applies antialiasing without MSAA.
|
||||||
|
|
||||||
|
It comes at some extra cost to performance the first time the shape is rendered. After this,
|
||||||
|
however, the shape can be smoothly scaled and transformed without extra cost.
|
||||||
|
|
||||||
|
\section3 Other operations
|
||||||
|
|
||||||
|
In addition to the basic operations for building a path, Qt Quick Shapes also includes some
|
||||||
|
powerful convenience components.
|
||||||
|
|
||||||
|
\list
|
||||||
|
\li The \l{PathQuad} component can be used to add a quadratic curve to the path.
|
||||||
|
\li The \l{PathRectangle} component can be used to construct a rectangle, optionally with rounded
|
||||||
|
corners.
|
||||||
|
\li The \l{PathSvg} component can be used to construct a path using SVG's path syntax. (Note: this
|
||||||
|
component only provides a compact way to describe a path, it does not support the entire SVG
|
||||||
|
syntax.)
|
||||||
|
\li The \l{PathText} component can be used to add outlines from a font to the path. This comes in
|
||||||
|
addition to Qt Quick's \l{Text} component. It can be used for advanced effects, for instance
|
||||||
|
gradient fills and path operations such as subtracting the text from another shape.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\section2 Raster images
|
||||||
|
|
||||||
|
Raster images (or pixmaps) can be displayed in Qt Quick using the \l{Image} component. A set of
|
||||||
|
image formats are supported by default through the \l{Qt Gui} module (PNG, JPEG, BMP and GIF). In
|
||||||
|
addition, the \l{Qt Image Formats} module has plugins for loading other image formats. As long as
|
||||||
|
your application can access the plugin for a certain format, it can be loaded using the \l{Image}
|
||||||
|
component.
|
||||||
|
|
||||||
|
\section2 Vector images
|
||||||
|
|
||||||
|
A limitation of raster images is that they cannot be scaled or otherwise transformed without causing
|
||||||
|
some reduction of quality. For images that will be displayed at different sizes or with transforms,
|
||||||
|
it is usually preferable to use a vector image format instead.
|
||||||
|
|
||||||
|
The \l{VectorImage} component can be used to include scalable vector graphics directly in your
|
||||||
|
Qt Quick application. It currently supports the SVG format by default. By deploying a plugin with
|
||||||
|
your application, it can also be made to support the Lottie format. Note that this support is
|
||||||
|
currently considered experimental.
|
||||||
|
|
||||||
|
The \l{VectorImage} parses the document and creates a Qt Quick scene in memory that represents its
|
||||||
|
contents, using Qt Quick Shapes and other primitives. Therefore it will behave the same as if the
|
||||||
|
vector image had been written using Qt Quick.
|
||||||
|
|
||||||
|
The vector images can also be converted to QML ahead of time, using the \l{svgtoqml} and
|
||||||
|
\l{lottietoqml} tools. This creates the same representation of the vector image using Qt Quick
|
||||||
|
components. However, instead of creating the representation in memory, it is saved to a file.
|
||||||
|
Pregenerating the QML file means it can be precompiled as part of the application assets, which will
|
||||||
|
save some time when loading it.
|
||||||
|
|
||||||
|
\image 2dgraphics/weatherforecastexample.png
|
||||||
|
|
||||||
|
The \l{Weather Forecast Example} shows how \l{svgtoqml} can be used in an application. Weather
|
||||||
|
symbols, maps and icons are SVG files that have been converted to QML and loaded as items in the
|
||||||
|
application scene.
|
||||||
|
|
||||||
|
Similarly, the \l{lottietoqml} tool can be used to convert Lottie animations into QML.
|
||||||
|
|
||||||
|
\section2 Prerasterized vector images
|
||||||
|
|
||||||
|
For vector images that are only ever displayed at a single size, it is more efficient to rasterize
|
||||||
|
them into pixmaps ahead of time and show these using \l{Image}. Often, such images will be stored
|
||||||
|
as SVGs in the application source assets and then converted to PNGs (for instance) at predefined
|
||||||
|
sizes. This is typically done as part of the application build and packaging process.
|
||||||
|
|
||||||
|
Rendering an image is faster than rendering the complex shapes, so for static images this is the
|
||||||
|
optimal approach. However, for some applications it is not convenient to do this conversion at
|
||||||
|
build-time. If the application is targeting many different form factors, for instance, the list
|
||||||
|
of predefined sizes to cover them all may be very long and hard to predict. Since each prerendered
|
||||||
|
image consumes extra space in the application deployment, there is also a cost to pay for this
|
||||||
|
approach.
|
||||||
|
|
||||||
|
Qt therefore also supports rasterizing SVG files at a specific size when the image is loaded. This
|
||||||
|
can be done simply by loading the file through the regular \l{Image} component. The
|
||||||
|
\l{Image::sourceSize}{sourceSize} property can be used to control the rasterized size of the image.
|
||||||
|
|
||||||
|
Loading the SVG through \l{Image} is different from loading it through \l{VectorImage} in the
|
||||||
|
following ways:
|
||||||
|
\list
|
||||||
|
\li With \l{Image}, the image is rasterized on the CPU before it is loaded as a texture. So there
|
||||||
|
is an extra loading cost involved which depends on the target size of the rasterized image.
|
||||||
|
Subsequent rendering of the same image, however, will be as fast as if the image was pre-rasterized
|
||||||
|
and loaded as a pixmap.
|
||||||
|
\li Additionally, the rasterized image may consume more memory, depending on the complexity of the
|
||||||
|
vector image and the size of the rasterized data.
|
||||||
|
\li Scaling/transforming the \l{Image} has the same drawbacks as if it were loaded as a pixmap.
|
||||||
|
\li If the image has animations, then \l{Image} will only show the first frame.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
So as a general rule, using prerasterized vector images will be better when the image is not
|
||||||
|
animated and its size remains the same through-out the life time of the application. Whether the
|
||||||
|
images are rasterized on build-time by a third party tool, or at run-time when Qt loads the image
|
||||||
|
is a trade-off between load time and convenience/deployment size.
|
||||||
|
|
||||||
|
\image 2dgraphics/vectorimageexample.png
|
||||||
|
|
||||||
|
The \l{Vector Image Example} shows an SVG file displayed at different scales using \l{Image},
|
||||||
|
\l{VectorImage} and a QML file generated with \l{svgtoqml}. When displayed at its source size,
|
||||||
|
the rendering looks the same across the board, and the \l{Image} will be slightly faster to render.
|
||||||
|
At higher scales, the \l{Image} becomes blurry and pixelated, whereas the other approaches remain
|
||||||
|
sharp and true to the source.
|
||||||
|
|
||||||
|
\section2 Animated vector graphics
|
||||||
|
|
||||||
|
Animations are at the core of Qt Quick's offering. Many vector graphics animations can be run
|
||||||
|
without changing the geometries of items, and thus benefit well from Qt Quick's hardware-accelerated
|
||||||
|
renderer.
|
||||||
|
|
||||||
|
\l{VectorImage}, \l{svgtoqml} and \l{lottietoqml} support animations for a selected subset of
|
||||||
|
properties.
|
||||||
|
|
||||||
|
\image 2dgraphics/lottietoqmlexample.png
|
||||||
|
|
||||||
|
The \l{lottietoqml Example} shows how animated Lottie files can be converted to QML. As seen in
|
||||||
|
this screenshot, multiple animated images are laid out in a grid. They can each be zoomed without
|
||||||
|
scaling artifacts or loss of fidelity.
|
||||||
|
|
||||||
|
\section2 Effects
|
||||||
|
|
||||||
|
The support for post-processing effects is included as a core feature in Qt Quick. Any item can
|
||||||
|
be turned into a texture and the \l{ShaderEffect} component can be used to apply any effect to it.
|
||||||
|
|
||||||
|
In addition to this low-level support for effects, Qt Quick also has a few high-level components
|
||||||
|
to make the process easier.
|
||||||
|
|
||||||
|
The \l{MultiEffect} component allows applying one or more of a pre-defined set of common effects
|
||||||
|
to an item.
|
||||||
|
|
||||||
|
\image 2dgraphics/quickeffectmaker.png
|
||||||
|
|
||||||
|
For more complex use cases, the \l{Qt Quick Effect Maker} provides a visual tool where you can
|
||||||
|
string together pre-defined and custom effects and generate the shader code for use with
|
||||||
|
\l{ShaderEffect}.
|
||||||
|
|
||||||
|
\section1 QPainter
|
||||||
|
|
||||||
|
\l{QPainter} is the basis of \l{Qt Widgets}. It provides an imperative API for drawing complex
|
||||||
|
shapes and images with pixel-perfect antialiasing.
|
||||||
|
|
||||||
|
Shapes can be specified using \l{QPainterPath} and the renderer also directly supports primitives
|
||||||
|
such as text and images.
|
||||||
|
|
||||||
|
The \l{QPainter} is primarily a software renderer, and it is optimized for smaller, partial updates
|
||||||
|
of the screen. Thus it is a good fit for the traditional, desktop-style interfaces of
|
||||||
|
\l{Qt Widgets}, where most of the UI is static from frame to frame. Therefore, rendering large and
|
||||||
|
complex 2D scenes with it may be expensive, and it could be worth considering \l{Qt Quick Shapes}
|
||||||
|
instead.
|
||||||
|
|
||||||
|
On the other hand, the rendering quality is higher, so for many use cases it will still be
|
||||||
|
preferrable. When rendering an SVG image through \l{Image} as outlined previously, \l{QPainter}
|
||||||
|
will be the underlying renderer.
|
||||||
|
|
||||||
|
If pixel perfection is the goal, and updates are rare and/or confined to small regions, then
|
||||||
|
QPainter is a powerful tool. If it becomes a performance bottle neck, you may consider moving
|
||||||
|
to using \l{Qt Quick} and \l{Qt Quick Shapes} instead.
|
||||||
|
|
||||||
|
\section1 Higher-level components
|
||||||
|
|
||||||
|
Building on top of these basic graphics primitives, Qt also provides many specialized, high-level
|
||||||
|
components.
|
||||||
|
|
||||||
|
\l{Qt Quick Controls} is one such module. It provides a rich and stylable set of common user
|
||||||
|
interface components. Similarly, \l{Qt Widgets} provides the same for \l{QPainter}-based
|
||||||
|
applications.
|
||||||
|
|
||||||
|
In addition, \l{Qt Graphs} is a data visualization module. It provides many different components to
|
||||||
|
visualize data sets and graphs in a \l{Qt Quick} application. \l{Qt Graphs} supports both 2D and
|
||||||
|
3D graphs.
|
||||||
|
*/
|
Loading…
Reference in New Issue