problem using the Qt library function 'QValueAxis::setRange'
-
@jsulm I am not able to obtain a stack trace. While running the example program in the debugger, the program "hangs" when the sequence of <Graph 1> button then <Graph 2> button is clicked. After several minutes of being "hung", the following message box appears:
The reason the program is "hanging" is because the Qt library function 'ChartValueAxisX::calculateLayout' is undesirably trying to create a QList with 1.0E+14 points on the stack. I tried to explain in my original post why this is a Qt library problem; the simple example illustrates the problem. -
@EricR
Nonetheless it would be interesting to very the stack trace. You have to (a) run it from debugger and (b) click OK on that dialog when it crashes. After that we are interested in seeing what it shows in stack view pane in debugger. (Especially after a "run out memory" which this might be, the backtrace can be nonsense. But it would still be interesting to see.)If you set a large range where it has to do a lot of ticks I guess that is a problem, even though it does not look like it's handled gracefully. But you are saying something like
setTickCount(10)
makes that not happen? So set your tick count small before setting a large range? -
@JonB Thanks for continuing to help. Much appreciated. Note that as reported in my original post, I have a workaround. I'm just trying to report a problem.
I did (a) run it from the debugger and (b) clicked <Ok> on the dialog message, but Qt was 'dead', couldn't do anything, even the Windows Task Manager could not kill it. I had to reboot to recover.
My example program does not 'want' to create an axis with zillions of axis tick marks. For 'graph 1' the example code is trying to set the number of major ticks to 10, and for 'graph 2' the example code is also trying to set the number of major ticks to 10. But because of the problem in the Qt library, it tries to create 1.0e+14 major ticks.
If I change the order as you suggested (setting the tickInterval BEFORE setting the 'range'), then I can make the same problem occur by doing the following:
void MainWindow::on_pushButton_1_clicked() { m_axisY->setTickInterval(1.0e3); m_axisY->setRange(0, 1.0e4); m_axisY->setTickAnchor(0); } void MainWindow::on_pushButton_2_clicked() { m_axisY->setTickInterval(1.0e-10); /* the program will CRASH while executing this instruction */ m_axisY->setRange(0, 1.0e-9); m_axisY->setTickAnchor(0); }
Above, 'Graph 1' will result in a range of (0, 1e4) with 10 major ticks, and then in 'Graph 2' the call to 'setInterval(1.0e-10)' will result in the Qt library trying to create 10e+14 major ticks (on the stack), even though the application code only want 10 major ticks.
The solution, as I mentioned in original post, is that the Qt library needs a function that can set the 'range', 'tickInterval', and 'tickAnchor' in one AUTONOMOUS operation/function to eliminate the problem; i.e. Qt library needs a function like the following:
void QValueAxis::setTicksDynamicInfo (qreal min, qreal max, qreal tickInterval, qreal tickAnchor);
That would prevent the Qt library from calling 'ChartValueAxisX::calculateLayout' too soon before all of the necessary properties have been set by the application code.
I'm sorry for taking up a lot of your time. I'm okay for now with my original work-around solution. I just think the issue should be fixed in the Qt library.
-
@EricR said in problem using the Qt library function 'QValueAxis::setRange':
I did (a) run it from the debugger and (b) clicked <Ok> on the dialog message, but Qt was 'dead', couldn't do anything, even the Windows Task Manager could not kill it. I had to reboot to recover.
:)
Above, 'Graph 1' will result in a range of (0, 1e4) with 10 major ticks, and then in 'Graph 2' the call to 'setInterval(1.0e-10)' will result in the Qt library trying to create 10e+14 major ticks (on the stack), even though the application code only want 10 major ticks.
I don't follow how the fact you have two different graphs affects the problem? That is confusing me. Why do you need two graphs to reproduce? If you need to set tick count or interval or whatever low before setting range high on any one graph then do so. But I haven't tried your code.
Are you saying no matter whether you do
setRange()
thensetTickInterval()
or the other way round either way you get too many ticks before you can change both, is that the issue?The solution, as I mentioned in original post, is that the Qt library needs a function that can set the 'range', 'tickInterval', and 'tickAnchor' in one AUTONOMOUS operation/function to eliminate the problem; i.e. Qt library needs a function like the following:
Then you have to report that at https://bugreports.qt.io/. It is a QtCharts issue.
-
@EricR said in problem using the Qt library function 'QValueAxis::setRange':
After several minutes of being "hung", the following message box appears:
That message is indicative of an invalid or null pointer. Attempting to allocate a huge block of memory, and failing to check success, could easily lead to this sort of problem. It seems odd that you call a method to change parameters on your Y axis and claim a crash in code called
ChartValueAxisX::calculateLayout()
@JonB said in problem using the Qt library function 'QValueAxis::setRange':
I don't follow how the fact you have two different graphs affects the problem? That is confusing me.
There is only one QChart. There are two push buttons labels (somewhat confusingly)
Graph 1
andGraph 2
. Both buttons trigger slots that notionally act on the Y axis of the single chart. -
@ChrisW67 said in problem using the Qt library function 'QValueAxis::setRange':
There are two push buttons labels (somewhat confusingly) Graph 1 and Graph 2.
Ah, I see! I looked at the names and thought we had two graphs, one affecting the other, somehow. I will have a look at the code....
-
@EricR said in problem using the Qt library function 'QValueAxis::setRange':
If I change the order as you suggested (setting the tickInterval BEFORE setting the 'range'), then I can make the same problem occur by doing the following:
m_axisY->setTickInterval(1.0e3); m_axisY->setRange(0, 1.0e4); m_axisY->setTickAnchor(0);
I do not get the behaviour/crash you say. If I copy & paste your two new orderings in
on_pushButton_1_clicked()
&on_pushButton_2_clicked()
from your last reply I can click either button and swap between them without problem, the axis getting drawn with appropriate ticks. (I do get your crash if I do not swap the order and use your original code.)And this would seem to correspond to the fact that the internal
calculateLayout()
you show callstickInterval()
when calculating for the new range, so that should be in place first. I admit it would look like a problem if it also calls this whensetTickInterval()
is called whilesetRange()
has not yet been called and is on an old range, but this did not seem to happen to me.I am using QT 5.15 supplied with Ubuntu 22.04 if it makes any difference..
-
@JonB Thanks for your awesome reply. I think you are right. It only causes a problem (in the original example) if in
on_pushButton_2_clicked
the code callssetRange
first and then callsetTickInterval
because (apparently) onlysetRange
callscalcuilateLayout
as you determined.I have submitted a bug report to Qt (QTBUG-124158). For now, I will mark this forum topic as 'solved' and then after the QTBUG is resolved I will come back to this forum topic and update it.
-