Qt World Summit: Submit your Presentation

Implementing an infinite zoomable canvas in Qt

  • Hi, I am working on a project which requires an infinite surface to draw (splines and text) which also need to be scalable. The requirements for the "surface" are:

    • being able to scroll and move around the surface
    • being able to dynamically resize its height (potentially to infinity but realistically up to 200000 "pixels")
    • fixed width
    • being able to draw vector paths, text and images
    • scalable (using pinch to zoom. Also when the scale is changed all the vectors should be rendered at the new scale.
    • being able to partially update regions of the surface

    Looking at Qt, I have listed 3 main options to achieve this, but I am not entirely sure which of them would suit my needs best (or even if there is another alternative I have missed:

    1. QGraphicsView, which would easily provide me with a scrollable viewport and has several built-in rendering strategies in order to achieve my goals (especially this https://doc.qt.io/qt-5/qgraphicsview.html#ViewportUpdateMode-enum). This would also automatically provide me with the tools to flick and resize the content. The only problem is that this class is part of Qt Widgets and I would really like to use QML).
    2. Use QQuickPaintedItem as the viewport of my surface and dynamically paint it as the use scrolls and zooms. This would require me to update the viewport from QML (maybe with a combination of Flickable and PinchArea). However, I am not really sure if scrolling would be smooth enough with this option as the I would need redraw the item quite a lot to achieve 60fps. The situation could be mitigated by storing the already drawn regions in some QImage objects and then draw them when required (essentially a custom tile-based rendering solution which would require a lot of time of to implement properly).
    3. Use QQuickItem instead of QQuickPaintedItem to achieve better performance, but then without QPainter drawing paths, shapes and text would quite difficult and would require a lot of work using the QSG classes.

    I would like to know people's opinion on this, especially if they have implemented something like this in their own projects.

Log in to reply