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:
- 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).
- 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). - Use
QQuickItem
instead ofQQuickPaintedItem
to achieve better performance, but then without QPainter drawing paths, shapes and text would quite difficult and would require a lot of work using theQSG
classes.
I would like to know people's opinion on this, especially if they have implemented something like this in their own projects.