[May Day Creation] Draw a circle in QML, Qt Quick /Qt

Draw a circle in Qt Quick

There are various ways to draw circles in Qt Quick. Here are some main methods:

  1. use Canvaselement

  2. Use Shapesthe module :

    a. PathArcUse PathLinea combination of and elements to draw a complete circle.

    b. Draw an oval using PathEllipsethe element and set it to a circle.

  3. Use Rectanglethe element to draw a rounded rectangle and set the corner radius to half the width and height.

The following are examples of these methods:

  1. Use Canvasthe element :
    Canvas {
        id: canvas
        anchors.fill: parent
    
        onPaint: {
            var ctx = getContext('2d');
            ctx.reset();
    
            // 绘制圆形
            ctx.beginPath();
            ctx.arc(width / 2, height / 2, width / 2, 0, 2 * Math.PI);
            ctx.fillStyle = 'lightblue';
            ctx.fill();
            ctx.strokeStyle = 'black';
            ctx.stroke();
            ctx.closePath();
        }
    }
    
  2. Use Shapesthe module :
    1. PathArcUse PathLinea combination of and elements to draw a complete circle.
      import QtQuick 2.15
      import QtQuick.Shapes 1.15
      
      Shape {
          anchors.fill: parent
          ShapePath {
              strokeWidth: 2
              fillColor: "lightblue"
              strokeColor: "black"
      
              Path {
                  startX: width / 2
                  startY: height / 2
                  PathLine {
                      x: width
                      y: height / 2
                  }
                  PathArc {
                      x: width / 2
                      y: height / 2
                      radiusX: width / 2
                      radiusY: height / 2
                      useLargeArc: true
                  }
                  PathLine {
                      x: width / 2
                      y: height / 2
                  }
              }
          }
      }
      
      
    2. Use PathEllipsethe element to draw an ellipse and set it to a circle.
      import QtQuick 2.15
      import QtQuick.Shapes 1.15
      
      Shape {
          anchors.fill: parent
          ShapePath {
              strokeWidth: 2
              fillColor: "lightblue"
              strokeColor: "black"
      
              Path {
                  startX: width / 2
                  startY: height / 2
                  PathEllipse {
                      x: 0
                      y: 0
                      width: parent.width
                      height: parent.height
                  }
              }
          }
      }
      
    3. Use Rectanglethe element to draw a rounded rectangle and set the corner radius to half the width and height.
      Rectangle {
          anchors.fill: parent
          color: "lightblue"
          border.color: "black"
          border.width: 2
          radius: Math.min(width, height) / 2
      }
      

The above are the main methods of drawing circles in Qt Quick. Note that some methods may be more suitable for specific situations, for example, when you need to use different methods, you can choose the appropriate drawing method according to the specific needs and scenarios of the application. Here are some suggestions:

  1. CanvasA good choice if you need graphics that update dynamically or use animation . It provides rich drawing and animation functions, and can easily implement custom interaction and animation effects.
  2. If you need to create graphics declaratively in QML code, and need tight integration with other Qt Quick components, then Shapesa module might be a better choice. ShapesCan take advantage of hardware acceleration well and can be easily used with other Qt Quick types.
  3. For a simple static circle, it's probably easiest to use Rectanglethe element to create a rounded rectangle. This method is suitable for simple application scenarios, such as drawing circular buttons or icons. Note, however, Rectanglethat the corner radius of a is limited by its size, so it may not be able to draw a perfect circle in some cases.

In a real project, you may need to weigh these approaches based on factors such as performance, maintainability, and code conciseness. For example, if performance is a key factor, then using Shapesa module might be a good choice since it takes advantage of hardware acceleration. If code readability and conciseness are key, then using Rectangleor Shapesmodules may be more appropriate.

expand knowledge

Canvas module introduction

Canvasis an element of Qt Quick that provides a way to draw graphics in QML via JavaScript and the 2D drawing API. CanvasAllows you to create and manipulate vector graphics, bitmap images, and text. It provides a large number of drawing functions, such as paths, colors, fills, strokes, gradients, modes and transformations, etc. CanvasAnimation and interaction are also supported, making it ideal for creating custom animations and visualizations.

Here are some Canvasof the main features of :

  1. Flexibility : CanvasProvides rich drawing functions, enabling you to create various graphics, such as lines, rectangles, circles, ellipses, polygons, etc. Plus, you can beautify your graphics with styles like gradients, patterns, and shadows.
  2. Animation and Interaction : CanvasSupports animation and user interaction. You can use requestAnimationFrame()the function to implement animations, or MouseAreato respond to user actions with and other input handlers.
  3. Performance : Despite Canvasusing JavaScript for drawing, it is still quite performant. This is due to Canvasthe use of Qt Quick Scene Graph, an efficient rendering framework. Also, you can further improve performance by updating only the areas that need to be redrawn in the onPainthandler .
  4. Integration with QML syntax : CanvasCan be used together with other QML elements, enabling you to easily create and manage graphics in your QML application. For example, you can use anchorsand layoutsto position and Canvasresize a , or to implementstates complex interactions and animations.transitions

Here is a simple Canvasexample showing how to draw a rectangle with a line and a gradient fill:

import QtQuick 2.15

Canvas {
    id: canvas
    width: 300
    height: 200

    onPaint: {
        var ctx = getContext('2d');
        ctx.reset();

        // 创建线性渐变
        var gradient = ctx.createLinearGradient(0, 0, width, height);
        gradient.addColorStop(0, 'red');
        gradient.addColorStop(1, 'blue');

        // 绘制带有渐变填充的矩形
        ctx.fillStyle = gradient;
        ctx.fillRect(50, 50, 200, 100);

        // 绘制矩形的描边
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 2;
        ctx.strokeRect(50, 50, 200, 100);
    }
}

In this example, we first create a linear gradient, then use fillRectthe function to draw a rectangle with the gradient fill. Next, we use strokeRectthe function to add a black stroke to the rectangle. The entire drawing process is done in the onPaintevent handler.

This simple example shows how to use the 2D drawing API in Qt Quick's CanvasElements to create custom graphics. In addition to rectangles, you can use other functions Canvasin to draw circles, ellipses, polygons, curves, and more complex shapes. What's more, you can create animation effects Canvasin , respond to user interaction, and use advanced features such as layers and composition modes.

CanvasThe main advantage of is its flexibility and customizability. You can use to Canvascreate almost any kind of custom graphics, and you can easily integrate them with other Qt Quick elements and functions. However, if you need simple static graphics, Rectangleit Shapesmay be easier and more efficient to use Qt Quick's other graphical elements, such as and modules.

All in all, Canvasa powerful drawing tool suitable for creating complex custom graphics, animations and visualizations in QML. To take full advantage Canvasof the features of , see the Qt documentation for more information on the 2D drawing API.

Shapesmodule introduction

Shapesmodule is a submodule of Qt Quick for declaratively creating vector graphics in QML. ShapesProvides a set of flexible, composable elements that enable you to create various complex graphics, such as lines, curves, rectangles, circles, ellipses, polygons, etc. ShapesThe module utilizes Qt Quick Scene Graph and hardware acceleration, so it has high performance.

ShapesThe main features of the module are as follows:

  1. Declarative syntax : ShapesModules allow you to create and manage graphs using a concise QML syntax. This makes the code easy to write, read and maintain. For example, you can use nested QML elements to define complex graphics.
  2. Composability : ShapesThe module provides a set of basic graphic elements, such as ShapePath, PathLine, PathArcand PathCurve, etc. , that you can combine together to create more complex graphics.
  3. Style and Appearance : ShapesThe module supports various styles such as fill, stroke, gradient, pattern, etc. This allows you to easily create visually rich graphics.
  4. Performance : Since Shapesthe module takes advantage of Qt Quick Scene Graph and hardware acceleration, it has high performance. This makes it Shapessuitable for creating complex visualizations and animations.
  5. Integration with other Qt Quick elements : ShapesModules can be tightly integrated with other Qt Quick elements, enabling you to easily create and manage graphics in your application. For example, you can use anchorsand layoutsto position and resize shapes, or statesto transitionsimplement complex interactions and animations.

Here is a simple Shapesexample of how to create a circle with stroke and fill:

import QtQuick 2.15
import QtQuick.Shapes 1.15

Shape {
    anchors.fill: parent
    ShapePath {
        strokeWidth: 2
        fillColor: "lightblue"
        strokeColor: "black"
        startX: width / 2
        startY: height / 2
        PathArc {
            x: width / 2
            y: height / 2
            radiusX: width / 2
            radiusY: height / 2
            useLargeArc: true
        }
    }
}

In this example, we use Shapethe element as the container, and then add a ShapePathelement inside it. ShapePathelement defines a path that creates a circle using PathArcthe element . We also set the fill color, stroke color and stroke width to customize the appearance of the circle. startXThe and startYproperties determine the starting point of the path, while radiusXthe and radiusYproperties determine the radius of the circle. useLargeArcproperty is set to trueto ensure a complete circle is drawn.

ShapesModules can create not only simple graphics, but also complex composite graphics. For example, you can create custom graphics by combining multiple ShapePathelements and various path commands such as PathLine, , andPathArc . PathCurvePlus, you can beautify your graphics with styles like gradients, patterns, and shadows.

Here's a slightly more complex example created using Shapesthe module that demonstrates how to draw a pentagram with a gradient fill and bezier curves:

import QtQuick 2.15
import QtQuick.Shapes 1.15

Shape {
    anchors.fill: parent

    ShapePath {
        fillColor: Qt.linearGradient(0, 0, width, height, "red", "blue")
        strokeColor: "black"
        strokeWidth: 2

        Path.moveTo(width / 2, 0)
        for (var i = 1; i < 5; ++i) {
            var angle = i * 2 * Math.PI / 5 - Math.PI / 2;
            var x = width / 2 + width / 2 * Math.cos(angle);
            var y = height / 2 + height / 2 * Math.sin(angle);
            Path.lineTo(x, y);
        }
        Path.close();
    }
}

In this example, we first use Qt.linearGradient()the function to create a linear gradient from red to blue, and then use fillColorthe property to apply it to the fill of the pentagram. Next, we use Path.moveTo()the function to move the path to the first vertex of the pentagram, and then use forthe loop and Path.lineTo()function to connect the remaining vertices. Finally, we use Path.close()the function to close the path to complete the drawing of the pentagram.

Draw a circle in Qt Widgets

In a Qt Widgets application, you can use the QPainter class to draw graphics, including circles, on a QWidget or QGraphicsScene. QPainter provides rich drawing functions, such as drawing basic graphics, using gradients and modes, setting stroke styles, etc.

Here is a simple example of drawing a circle on a QWidget:

  1. First, create a custom class that inherits from QWidget. In this example, we named it CircleWidget.
#include <QWidget>

class CircleWidget : public QWidget
{
    
    
    Q_OBJECT

public:
    explicit CircleWidget(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent *event) override;
};
  1. Next, in the implementation file, include the necessary headers and implement the CircleWidgetconstructor and paintEventmethod.
#include "circlewidget.h"
#include <QPainter>

CircleWidget::CircleWidget(QWidget *parent) : QWidget(parent)
{
    
    
}

void CircleWidget::paintEvent(QPaintEvent *event)
{
    
    
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    // 设置填充颜色和描边颜色
    painter.setBrush(Qt::lightGray);
    painter.setPen(Qt::black);

    // 计算圆形的矩形边界
    QRectF circleRect(10, 10, width() - 20, height() - 20);

    // 绘制圆形
    painter.drawEllipse(circleRect);
}

In paintEventthe method , we first create a QPainter object and enable antialiasing. Next, we use setBrushthe and setPenmethods to set the fill and stroke colors. Then, we calculate the rectangular bounds of the circle so that it fits the size of the current window. Finally, we use drawEllipsethe method to draw the circle.

  1. Used in your main window or other QWidgets CircleWidget.
#include "circlewidget.h"

// ...

auto circleWidget = new CircleWidget(this);
circleWidget->setGeometry(50, 50, 200, 200);

This example demonstrates how to create a simple custom QWidget in a Qt Widgets application that draws a circle in its paintEventmethod . You can customize this example to your needs, such as changing the color, size, or position of the circles, or adding other graphics and effects.

Comparison of the two methods

Qt Widgets and QML provide different methods for drawing circles (or other graphics) in Qt applications. Each method has its pros and cons, and depending on your needs and type of application, you can choose the method that works best for you.

  1. Qt Widgets draw circles :

    In a Qt Widgets application, you can use the QPainter class to draw graphics on QWidgets. QPainter provides rich drawing functions, such as drawing basic graphics, using gradients and modes, setting stroke styles, etc.

    Advantages :

    • For traditional QWidget-based desktop applications.
    • QPainter provides a wealth of drawing functions, including graphics, text, images, etc.
    • QPainter can be used to draw QWidget or QPixmap, so graphics can be displayed on the screen or saved as image files.
      Disadvantages :
    • More C++ code needs to be written, which can lead to increased complexity and difficulty in maintenance.
    • QPainter does not directly support hardware acceleration, so performance may be lower in some cases.
    • Not suitable for mobile devices or cross-platform applications, as Qt Widgets is mainly aimed at desktop environments.
  2. QML draws a circle :

    In a QML application, you can use the Qt Quick Shapes or Qt Quick Canvas modules to create vector graphics declaratively in QML. These modules take advantage of the Qt Quick Scene Graph and hardware acceleration and thus have high performance.

    Advantages :

    • For modern applications across platforms and mobile devices.
    • It is easy to write, read and maintain using the concise QML syntax.
    • Complex visualizations and animations can be easily created, tightly integrated with other Qt Quick elements.
    • High performance due to the use of Qt Quick Scene Graph and hardware acceleration.
      Disadvantages :
    • Not available for traditional QWidget-based desktop applications.
    • Need to learn and master QML syntax and Qt Quick related concepts.

Depending on your needs and the type of application, you can choose the method that works best for you. If you are developing a traditional QWidget-based desktop application, it may be more appropriate to use QPainter to draw graphics on the QWidget. Instead, if you are developing a cross-platform or modern application on mobile devices, then using QML and the Qt Quick Shapes or Qt Quick Canvas modules may be a better fit.

Guess you like

Origin blog.csdn.net/qq_21438461/article/details/130464717