QGraphicsView, many non-scaling labels. Best approach
-
Project:
I am using aQGraphicsView
to display a navmesh/triangulation of large map (250,000 x 500,000). For debugging purposes, I have some toggleable settings to show the labels of triangles, edges, and vertices. These labels really only make sense to be shown once I'm zoomed in at around the 500 x 500 level. Also, these labels should always have the same font size relative to the window (does not change on zoom). There are on the order of millions of labels across the entire map. I have the requirement to be able to read labels at very small scales (smaller than 0.01x0.01).What I initially had done:
Within theQGraphicsView
, the entire map is broken up into 2000x2000 regions. These regions were each an instance of a subclassedQGraphicsItem
(calledRegionGraphicsItem
, in my case). Inside thepaint()
function of theRegionGraphicsItem
, I was using the painter todrawText()
. I scaled the font size based on the "level of detail" that I was receiving from theQStyleOptionGraphicsItem
parameter given topaint()
. If the level of detail was below a certain value (too zoomed out), thepaint()
function would not calldrawText()
.This did not work well because when zoomed in very far (maybe around a scale of 10x10) the font scaling calculation led to the text behaving weirdly.
My second approach:
I subclassedQGraphicsSimpleTextItem
to create aNoScaleLabel
class. It simply overrides thepaint()
function to prevent the scaling of the painter. I add one of theseNoScaleLabel
objects to the scene for each label (meaning millions of items added to the scene). When I zoom in far enough, I would callsetVisible(true)
for all labels, andsetVisible(false)
when zoomed out beyond a certain level.This solved my scaling issue; the font looked great at extreme zoom levels. However, performance suffered heavily. Even though all labels are set to not-visible, there is a minute long lag initially when zooming out to view a large portion of the world. There is also noticeable lag when panning the map.
Question:
Is there a better option? I need a ton of things available in the scene, but I only need a small subset of them to be visible in the case when I'm zoomed in. Maybe it would make sense to add/remove the items from the scene rather than setting them as visible? But I would only want to add the ones that might be visible, not all million labels for the entire map. Is there something similar tovisible
that has better performance? -
What is ROI? Region of interest?
If I don't do any work for scaling, then as you zoom in, the font becomes super large. I want the font to always appear the same size, regardless of zoom.
-
What is ROI? Region of interest?
If I don't do any work for scaling, then as you zoom in, the font becomes super large. I want the font to always appear the same size, regardless of zoom.
@SandSnip3r Yes, Region of interest. You do not resize text items at all since font size does not change. You always keep these text items on the top of all items in QGraphicsView if they are visible. Simply move them in the view(their positions change) when ROI changes(zooming). Like they are floating on the view.