PDA

View Full Version : QGraphicsScene coordinate space larger than INT_MAX, but QGraphicsView scroll broken



cgomez116
19th October 2011, 17:46
I have an application where the coordinate space of the QGraphicsScene can and will be much smaller/larger than INT_MIN, INT_MAX (−2,147,483,648, +2,147,483,647, see http://en.wikipedia.org/wiki/Limits.h), i.e. the scene will contain many items with coordinate positions with qreal (double) values much smaller/larger than the INT_MIN, INT_MAX.

But the QGraphicsView inherits QAbstractScrollView, and the scroll bars are limited to an integer range of INT_MIN to INT_MAX, see: http://doc.trolltech.com/4.5/qgraphicsview.html


"QGraphicsView can be used to visualize a whole scene, or only parts of it. The visualized area is by default detected automatically when the view is displayed for the first time (by calling QGraphicsScene::itemsBoundingRect()). To set the visualized area rectangle yourself, you can call setSceneRect(). This will adjust the scroll bars' ranges appropriately. Note that although the scene supports a virtually unlimited size, the range of the scroll bars will never exceed the range of an integer (INT_MIN, INT_MAX). When the scene is larger than the scroll bars' values, you can choose to use translate() to navigate the scene instead.":(

Has anybody actually figured out how to use translate() to accomplish scrolling in a scene where the coordinate space is larger than (INT_MIN, INT_MAX)? Or do I need to create my own custom scroll bars that use qint64 ranges instead of int ranges?

This seems to me to be a big blunder in GraphicsView implementation, as allowing the scene to contain items with qreal (double) coordinates, but the view can only scroll int coordinates is a huge limitation.

In any case, any suggestions are appreciated, and if someone has already encountered this and has a solution they wouldn't mind sharing (either the algorithm or example code :-) it would be greatly appreciated. :)

For those who are curious the application involves graphing space/time data with time on the x coordinate, where the times and time ranges will routinely be > than INT_MAX (the time base is in picoseconds). If every time tick is 10 pixels wide, then I am in fact limited to a range of INT_MAX/10 (214,748,364) time units. Thats not a lot of time in a picosecond time base!

achernov
15th December 2011, 18:21
I've also faced this limitation when try to paint waveform from sound file which can be of unpredictable length and samplerate.

I've also tried some workarounds with translate() method as referenced but I think it's for another case: if you have several areas covered by (INT_MIN, INT_MAX) then you e.g. can scroll the whole 1st region, switch to second region, scroll it whole and so on. So you don't have continuous scroll range as in case of int64 scrollbar limits, but you can cover the whole range by a number of jumps.

I'm still thinking how to workaround this strange limitation but no good idea so far.. Very annoying detail and it seems so unlikely that it's fixed in some near future.

cgomez116
25th December 2011, 02:54
Due to the importance of this for my application, I ended up creating QScrollBar64 and QAbstractScrollArea64 classes (based on the original QScrollBar and QAbstractScrollArea classes, the basic gist was to change int to qint64), and then enhancing QGraphicsView to use the QAbstractScrollArea64 as its base class. I put these changes into a patch series (quilt). Currently these patches are based on a stock Qt 4.5.3 X11 source, and I plan to port them to a newer Qt4 at some point. Also I thought about submitting the patch series back to the Trolls, they could at least see it as a proof of concept. It was quite straightforward, and I had no problems implementing this enhancement, so it should be as easy or easier for the Trolls to do this enhancement to the official Qt4 source, if/when they get the time.

amleto
25th December 2011, 16:34
If every time tick is 10 pixels wide, then I am in fact limited to a range of INT_MAX/10 (214,748,364) time units. Thats not a lot of time in a picosecond time base!

wow, is more than 2 HUNDRED MILLION data points not enough!?

If someone is interested in time scales of seconds, then it's very unusual that they will care about details at picosecond and vice versa.

cgomez116
25th December 2011, 17:05
Actually 200 million isn't large enough because the nature of the data is that it may be very sparse and yet the precision is still desired, and large ranges must be viewed to properly analyze the dataset relationships.

Events may occur millions of picoseconds apart, and there are millions of events, and to visualize the trends of the sparse data it is nessary to graph large ranges of the data. Of course users can zoom in/out on the data and view different ranges simultaneously thanks to the qgraphicsscene and qgraphicsview model/view like architecture.

In any case I was able to solve the problem of supporting 64 bit view/scroll ranges in the qgraphicsview by enhancing it. Of course a 64 bit integer view/scroll won't represent the full dynamic range of the scene which uses doubles for coordinates, but 64 bit integers are more than enough for my purposes.

I'm just a bit surprised that the trolls didn't notice the large dynamic range discrepteny between scene coordinate (doubles, qreal) and the view (int). Other than this though, I still have the highest respect and admiration for the wonderful job that has been done in creating the Qt library, it is generally very well thought out and implemented.

Oh well, until if and when they do officially add 64 bit int scroll/view, I'll maintain my patch series for the qt source.

amleto
25th December 2011, 19:23
you'll have to proved the qt source code, with your patch, for any application that you distribute. That is, unless you have a commercial license.

You could just have had buttons to translate the view by a range (int_max - int_min). or by a few multiples of the range.

cgomez116
25th December 2011, 21:36
We do have a commercial licence, but for this application, its for internal use only, so that is not a concern. If we did distribute this application, and we didn't have a commercial license, we would gladly distribute the patches to the Qt4 source. After all, they are quite straightforward and simple and I hope that TrollTech will eventually enhance the GraphicsView to use a 64 bit scroll/view range, to better match with double coordinates uses on the GraphicsScene.

Regarding the translate "trick", that doesn't actually work for our use-model. Our uses want and need to zoom and view the entire dataset, which will often contains millions of events, where the span from the first event to the last event is greater than 32 bits. For instance when the user wants to zoom out and view then entire dataset (or even subsets of the dataset that don't fit in the 32 bit integer range) then the translate "trick" is no longer applicable. The translate trick only works as long as the view only contains a subset of the range you want to view that happens to fit in 32 bit range, and if you zoom out beyond that range the large coordinates (doubles) actually confuse the QGraphicsView and the view is erratic.

Added after 1 3 minutes:

The patch series I created for this includes 64 bit versions of QAbstractSlider, QScrollbar, and QAbstractScrollArea, namely new classes called QAbstractSlider64, QScrollBar64, QAbstractScrollArea64, and a modified QGraphicsView which derives from QAbstractScrollArea64 (instead of QAbstractScrollArea), and uses QScrollBar64 and qint64 in the appropriate places.

I will look into submitting this patch series to TrollTech.

By the way, there was an enhancement bug filed on this back in 2007 (not by me), but the bug was closed as Out-of-scope in 2009, see: Qt bug: 1003 (https://bugreports.qt.nokia.com/browse/QTBUG-1003)

Here is the last comment on that bug:


Thiago Macieira added a comment - 27/Dec/09 4:23 PM
This report is now too old. If you need this issue fixed, please vote for it and let us know by way of comments, or clone the issue.

I will probably end up cloning this bug and submitting my patch series with it. Perhaps the TrollTech folks can see how easy the enhancement was and decide to put it into the official release.

supertwang
14th March 2013, 01:37
@cgomez116,

That sounds like a good architectural approach to solving the problem. I am running into the exact same issue with an x axis of time, and wanting to be able to pan forward and backward billions of years, while at the same time supporting zooming down to the nanosecond (at any time.)

Would you be willing to share your modified 64bit classes with me? It'd save me having to dig in and do the same thing. I'm quite surprised this hasn't been fixed in the distro. While it may not be a common issue, it seems to have arisen often enough in the research I've been doing trying to solve it.

Thanks for the design hint, and would very much appreciate sharing your work.

Cheers,
ST

anupam
3rd July 2013, 07:27
Have you got the hint how to create the QabstractArea64 class??

sumitbeniwal
2nd July 2014, 11:21
I am facing same problem related to range of QScrollBar. Actually i have to set range of QScrollBar from 0 to max int64_t .
please give me any idea how to customize QScrollBar so that it support the range to max int64_t.
i need this because i have to work with a big size document(2 TB or more).
thanks