A Better Canvas

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Image:qt-logo_new.png Image:qq-title-article.png
Qt Quarterly | Выпуск 19 | Документация

by Andreas Aardal Hanssen

Qt 4.2 introduces Graphics View, a new framework for managing a largenumber of graphical shapes on a 2D canvas. This technology makes fulluse of Qt 4's powerful paint engine architecture, and is areplacement for Qt 3's QCanvas. The Graphics View API is very similarto QCanvas's, making it straightforward to port existingQCanvas-based code to use Graphics View.


Many of you are probably familiar with QCanvas.With collision detection, transformations (like zooming and rotation), andsupport for managing millions of items efficiently, QCanvas has found its way into all kinds ofapplications, including games, charting, vector drawing, and imagingapplications. When participating in events and trade shows, our engineers havebeen positively surprised as customers have shown us how they use QCanvas as the core of their applications.

While many of the core features of QCanvas(notably collision detection and advanced transformations) were tailoredspecifically for the framework itself, these features became part of Qt 4'spaint system, Arthur. With Arthur's powerful rendering architecture at hand,we decided it was time to revamp the canvas and provide a brand newgraphics shape framework that could fully exploit the potential of Qt 4.


One of the most noticeable improvements in the new API lies in thecoordinate system: We can now support real number coordinates toadd a new level of precision to QGraphicsView's visualizationcapabilities, especially when zooming far in on a detailed scene. Thisgreatly simplifies having to deal with data from external sources,such as topological data, which typically use real coordinates.

In addition, the canvas is no longer restricted to positivecoordinates only. Unlike QCanvasItems, QGraphicsItems canreside at a position with negative coordinates, such as (-100, -50).When you construct a scene, you pass a rectangle (i.e., a QRectF) defining its position in the plane to QGraphicsScene's constructor. QGraphicsView will automatically adapt itsscrollbars so you can navigate across the scene. For example:

QGraphicsScene scene(QRectF(-1000, -1000, 2000, 2000));
QGraphicsView view(&scene);

A long awaited feature that we couldn't easily implement for QCanvas is being able to transform individual items. Whereas in QCanvas each item's coordinates were aligned with the canvas'scoordinate system, each QGraphicsItem can now store a local matrixwhich you can use to rotate, scale, shear, or translate the item.


For example, to change the orientation for a text item, you can nowsimply rotate the text item directly:

QGraphicsTextItem *text = scene.addText(tr("Some Text"));

To the item itself, its coordinate system appears to be completelyunchanged. So for those of you who write custom items, you do not needto worry about what transformation applies to the item as you handlemouse events and painting. The Graphics View framework automaticallyhandles all such transformations for you.

And this brings us to another new feature in Graphics View. In Qt 3, QCanvasItems were all top-level items, andtheir geometries were relative to the canvas. In contrast, QGraphicsItem allows you tocreate composite items, or stack items on top of each other. Like QWidget, QGraphicsItem allows items to contain otheritems, and child items' geometries are relative to their parents. You can,for example, create a framed pixmap item by using composition:

QPixmap pixmap("picture.png");
QGraphicsPixmapItem *pixmap = scene.addPixmap(pixmap);
QGraphicsRectItem *frame = scene.addRect(
        -2, -2, pixmap.width() + 2, pixmap.height() + 2);

And here's the best part: Even transformations are relative to theparent. If you scale or rotate the frame item, the pixmap child willfollow.

Item composition can be used in a variety of ways, especiallyconsidering how QGraphicsItems do not cliptheir children like widgets do. You can use parent--child item relationshipsto link limbs together for a robot arm, or even for linking planetstogether in a solar system scene, bringing a new level of relativetransformations into play. Item composition pushes Qt 4's renderingarchitecture to its limits, and makes it fun and easy to managecomplex graphical scenes.

When managing a large scene, the graphics subsystem has twochallenges: Determining the geometry and locality of items quickly,and rendering a large number of items at the same time. To speed upitem discovery, e.g., when hovering the mouse over a group of items, QCanvas provided an index based on partitioning the canvas into amatrix of fixed-size chunks. With QGraphicsScene, the indexing isoptional and handled internally, by default using a binary spacepartitioning (BSP) tree.

Even with fast item discovery, QGraphicsViewis sometimes forced to render a large number of items. This is usually the casewhen zooming out, viewing a whole scene from a distance. QGraphicsView provides each item withlevel-of-detail information when it is drawn, allowing the items to easilydetermine how they can simplify their shape when viewed from a distance.Simplifying items' drawing can dramatically increase performance.

For the ultimate performance, QGraphicsViewcan render using OpenGL. Just use a QGLWidget foryour view's viewport. As a custom item author, you then have the option ofusing QPainter's set of highly-optimized functions,or drawing directly to the GL context using OpenGL calls.

With the old QCanvas, improved item interaction wasalways one of the top feature requests. To interact with items, you wouldcreate a small subclass of QCanvasView andtranslate mouse events to the scene using the view's world matrix whenreimplementing the mouse event handlers. Because different items treat mouseinteraction differently, the view could easily end up maintaining item-specificlogics.

Although you can still use this approach with Graphics View, thesimpler approach is to reimplement mouse event handlers in the itemsthemselves. The framework includes an event propagationarchitecture that provides interaction capabilities for the items onthe scene. Items can handle key events, mouse press, move,release, and double-click events, and they can also track mousemovement.


Finally, I would like to mention the powerful text edit controlprovided by the QGraphicsSimpleTextItem and QGraphicsTextItemclasses. The simple text item is optimized for drawing plain text fastand with low memory overhead. To display formatted text, you can usethe QGraphicsTextItem which provides arich set of functions giving you full control over the text document as wellas its rendering. You can even make the text item editable!

Copyright © 2006 Trolltech Trademarks