The QML Canvas Element (2024)

The QML Canvas Element (1) By Jeff Tranter

Perhaps you have been trying to do more with QML than just using the basic elements like rectangles, text and images, or maybe you have been struggling to implement a user interface that doesn't map well into these basic elements. If so, the QML Canvas may be just the solution you are looking for. In this post, we'll look at Canvas (1), a powerful and useful QML element that is part of Qt Quick.

Introduction

The basic QML visual elements are quite low-level, consisting of things like images, rectangles and text. Often you can build your user interface by combining these basic building blocks, but sometimes you have a design that can't be easily made up from these elements. Prior to Qt version 5, if you wanted much more than colored rectangles, text or images, you needed to drop down into C++ and implement it using Qt's paint API. Starting with Qt Quick 2 in Qt 5.0, the new QML Canvas addresses this limitation by providing a QML element with full 2D drawing capability.

Rather than reinvent the wheel and design a new set of APIs for drawing, QML leverages the work of the HTML5 canvas. The good news is that, if you know the HTML5 Canvas, you already know more than ninetypercent of the QML Canvas element. The bad news is that, if you are one of those people avoiding learning how to program in JavaScript, you are going to need to write some JavaScript code in order to use the Canvas element.

More Details

The Canvas QML element has been available as part of Qt Quick 2 since Qt 5.0.0. The QML elements most relevant to using the canvas are Canvas (1) and Context2D (2). The Context2D element implements the W3C Canvas 2D Context API standard (3) with some enhanced features.

The API provides drawing primitives for arcs, Bézier curves, images, ellipses, rectangles, text, lines, quadratic curves and rounded rectangles.

As always, the Qt documentation provides full reference material for the elements. It also includes some tips for porting existing HTML5 Canvas code to QML. If you are not familiar with the HTML5 Canvas, I recommend that you check a few of the many excellent tutorials or references available on the Internet.

The Qt source code also comes with some examples which can be found in your Qt install directory under examples/quick/canvas/.

A Simple Example

Let's look at a simple programming example. Save the code example shown below to a QML file and then execute it using the qmlscene program. Thesample code illustrates a number of the drawing primitives.

// Simple example of QML Canvas elementimport QtQuick 2.0Canvas { width: 400 height: 400 onPaint: { // Get drawing context var context = getContext("2d"); // Make canvas all white context.beginPath(); context.clearRect(0, 0, width, height); context.fill(); // Fill inside with blue, leaving 10 pixel border context.beginPath(); context.fillStyle = "blue" context.fillRect(10, 10, width - 20, height - 20); context.fill(); // Draw a line context.beginPath(); context.lineWidth = 2; context.moveTo(30, 30); context.strokeStyle = "red" context.lineTo(width-30, height-30); context.stroke(); // Draw a circle context.beginPath(); context.fillStyle = "orange" context.strokeStyle = "red" context.moveTo(width/2+60, height/2); context.arc(width/2, height/2, 60, 0, 2*Math.PI, true) context.fill(); context.stroke(); // Draw some text context.beginPath(); context.strokeStyle = "lime green" context.font = "20px sans-serif"; context.text("Hello, world!", width/2, 50); context.stroke(); }}

Drawing is done with a 2D graphics context, obtained by calling the getContext() method. Depending on the graphics primitives used, drawing involves strokes or paths. You can learn more about these concepts from reading the HTML5 canvas documentation.

A screen shot of the above example running is shown below.

The QML Canvas Element (2)

A More Complex Example

A slightly more complex example is shown below. It illustrates the use of JavaScript code for programmatically drawing lines based on an algorithm, in this case the display of a number of closely spaced lines to generate a Moiré pattern.

import QtQuick 2.0/*Lines are drawn from x1,y1 to x2,y2 in four "phases" as below:From To Phasex1 y1 x2 y2 Number 0,0 w,0 1 w,0 w,h 2 w,h 0,h 3 0,h 0,0 4 done 5*/import QtQuick 2.0Canvas { id: canvas width: 400 height: 400 onPaint: { var ctx = getContext("2d"); var w = canvas.width; var h = canvas.height; var delta = 4; // Spacing between lines var phase = 1; var x1 = 0; var y1 = 0; var x2 = w; var y2 = 0; while (true) { ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); switch (phase) { case 1: x1 += delta; y2 += delta; if (x1 >= w || y2 >= h) { x1 = w; y2 = h; phase = 2; } break; case 2: y1 += delta; x2 -= delta; if (y1 >= w || x2 <= 0) { y1 = h; x2 = 0; phase = 3; } break; case 3: x1 -= delta; y2 -= delta; if (x1 <= 0 || y2 <= 0) { x1 = 0; x2 = 0; phase = 4; } break; case 4: y1 -= delta; x2 += delta; if (y1 <= 0 || x2 >= w) { y1 = 0; x2 = w; phase = 5; } break; case 5: return; } } }}

A screen shot of the program's output is shown below. You may find the program useful to modify and experiment with. It also illustrates the performance capabilities of Canvas and JavaScript. As written, it draws about 400 lines. You can modify it to draw more.

The QML Canvas Element (3)

Summary

With Qt Quick 2 and the Canvas element, you now have the ability to draw arbitrary graphics from within QML. The canvas APIs are fast and powerful - people have implemented complete graphics editing programs (4) with the HTML5 Canvas. You still have the option of using Qt's C++ APIs for painting, if desired, for performance, feature requirements, or just personal preference.

References

  1. Qt API Documentation for Canvas element, Qt Project web site, accessed April 21 2014, qt-project.org/doc/qt-5/qml-qtquick-canvas.html
  2. Qt API Documentation for Context2D element, Qt Project web site, accessed April 21 2014, qt-project.org/doc/qt-5/qml-qtquick-context2d.html
  3. W3C Description of the Canvas Element, World Wide Web Consortium (W3C) web site, accessed April 21 2014, www.w3.org/TR/2009/WD-html5-20090825/the-canvas-element.html
  4. iPaint: MS Paint-like On-line Painting Program Implemented Using HTML5, jswidget.com web site, accessed April 21 2014, www.jswidget.com/index-ipaint.html
The QML Canvas Element (2024)
Top Articles
Latest Posts
Article information

Author: Edmund Hettinger DC

Last Updated:

Views: 5875

Rating: 4.8 / 5 (78 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: Edmund Hettinger DC

Birthday: 1994-08-17

Address: 2033 Gerhold Pine, Port Jocelyn, VA 12101-5654

Phone: +8524399971620

Job: Central Manufacturing Supervisor

Hobby: Jogging, Metalworking, Tai chi, Shopping, Puzzles, Rock climbing, Crocheting

Introduction: My name is Edmund Hettinger DC, I am a adventurous, colorful, gifted, determined, precious, open, colorful person who loves writing and wants to share my knowledge and understanding with you.