Results 1 to 10 of 10

Thread: QwtLegend: different behaviour when inserting a legend after/before adding curves

  1. #1
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Exclamation QwtLegend: different behaviour when inserting a legend after/before adding curves

    I have an application that plots curves in a QwtPlot object. Now, I would like, at will, to show/hide the legend for that QwtPlot object. For this, I am doing something like:

    Qt Code:
    1. void GraphPanelPlotWidget::setLegend(const bool &pLegend)
    2. {
    3. // Show/hide our legend
    4.  
    5. if (pLegend != legend())
    6. insertLegend(pLegend?new QwtLegend(this):0);
    7. }
    To copy to clipboard, switch view to plain text mode 

    As expected, it does create/destroy the legend as requested. However, here are two slightly different scenarios (through my application's GUI):
    1. I show the legend and then create and plot some curves; and
    2. I create and plot some curves and then show the legend.


    I would expect both scenarios to yield the exact same result. Yet, although the first scenario gives me what I would expect, i.e.

    Screen Shot 2017-11-16 at 18.06.07.jpg

    The second scenario doesn't. Instead of the legend itself, I only have some blank space:

    Screen Shot 2017-11-16 at 18.04.47.jpg

    I had a look at the various Qwt examples, including the 'legends' one, and what I am doing in terms of showing/hiding (or, rather, inserting/removing) the legend is no different. So, why am I getting a different behaviour for my two scenarios, not least since in the 'legends', we may have some curves and no legend, and then decide to show the legend and it will indeed show it right, but... not in my case...!? I am clearly missing something, but I can see what it is.

    Thanks in advance to anyone who can help me with this...

  2. #2
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QwtLegend: different behaviour when inserting a legend after/before adding curves

    Guess GraphPanelPlotWidget is some sort of container - not the plot widget. Then what happens when doing:
    Qt Code:
    1. insertLegend(pLegend?new QwtLegend(nullptr):0);
    To copy to clipboard, switch view to plain text mode 
    Uwe

  3. #3
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QwtLegend: different behaviour when inserting a legend after/before adding curves

    Sorry, my bad. I should have made it clear that GraphPanelPlotWidget actually inherits from QwtPlot. Anyway, I thought I would still try your suggestion, but as expected it didn't make any difference (in fact, if I am not mistaken, it should now leak when 'hiding' the legend since its parent is not a QwtPlot object anymore).

  4. #4
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QwtLegend: different behaviour when inserting a legend after/before adding curves

    Well then I would need to see a small compile demo to check what's going on.

    Uwe

  5. #5
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QwtLegend: different behaviour when inserting a legend after/before adding curves

    Well, that's the thing: I tried to generate a small example that reproduces my problem, but I to no avail. In fact, I am not surprised that I can't reproduce it since I believe the problem is most likely at my end. It's just that I have tried various things at my end and can't seem to fix it. So, I am, here, merely trying to get some further ideas for me to try...

  6. #6
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QwtLegend: different behaviour when inserting a legend after/before adding curves

    Ok, I have found out why I am having the behaviour I described above. It has to do with my calling QWidget::setUpdatesEnabled() on my QwtPlot object. Indeed, I customise quite a few things in my QwtPlot object, so I thought I would temporarily prevent it from updating itself. In other words, I have something like this:

    Qt Code:
    1. myPlot->setUpdatesEnabled(false);
    2. ...
    3. myPlot->insertLegend(addLegend?new QwtLegend(myPlot):0);
    4. ...
    5. myPlot->setUpdatesEnabled(true);
    To copy to clipboard, switch view to plain text mode 

    This can easily be reproduced in the simpleplot example:

    Qt Code:
    1. #include <qapplication.h>
    2. #include <qwt_plot.h>
    3. #include <qwt_plot_curve.h>
    4. #include <qwt_plot_grid.h>
    5. #include <qwt_symbol.h>
    6. #include <qwt_legend.h>
    7.  
    8. int main( int argc, char **argv )
    9. {
    10. QApplication a( argc, argv );
    11.  
    12. QwtPlot plot;
    13. plot.setUpdatesEnabled(false);
    14. plot.setTitle( "Plot Demo" );
    15. plot.setCanvasBackground( Qt::white );
    16. plot.setAxisScale( QwtPlot::yLeft, 0.0, 10.0 );
    17. plot.insertLegend( new QwtLegend() );
    18.  
    19. QwtPlotGrid *grid = new QwtPlotGrid();
    20. grid->attach( &plot );
    21.  
    22. QwtPlotCurve *curve = new QwtPlotCurve();
    23. curve->setTitle( "Some Points" );
    24. curve->setPen( Qt::blue, 4 ),
    25. curve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
    26.  
    27. QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse,
    28. QBrush( Qt::yellow ), QPen( Qt::red, 2 ), QSize( 8, 8 ) );
    29. curve->setSymbol( symbol );
    30.  
    31. QPolygonF points;
    32. points << QPointF( 0.0, 4.4 ) << QPointF( 1.0, 3.0 )
    33. << QPointF( 2.0, 4.5 ) << QPointF( 3.0, 6.8 )
    34. << QPointF( 4.0, 7.9 ) << QPointF( 5.0, 7.1 );
    35. curve->setSamples( points );
    36.  
    37. curve->attach( &plot );
    38. plot.setUpdatesEnabled(true);
    39.  
    40. plot.resize( 600, 400 );
    41. plot.show();
    42.  
    43. return a.exec();
    44. }
    To copy to clipboard, switch view to plain text mode 

    So, is that behaviour 'normal'? I mean, I would really like to be able to make calls to QWidget::setUpdatesEnabled() whenever I see fit, so how can I go about it without messing up my legend?

  7. #7
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Lightbulb Re: QwtLegend: different behaviour when inserting a legend after/before adding curves

    Ok, I have 'fixed' it. In the end, the 'problem' is with QwtLegendLabel::setData(). Indeed, it disables updates, but then only reenables them if it was originally enabling them. Now, because my application temporarily disable them at some point, QwtLegendLabel doesn't reenable updates, hence the 'blank' legend I mentioned in my original message.

    To address this issue, I had to something like:

    Qt Code:
    1. class MyLegend : public QwtLegend
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. explicit MyLegend(QWidget *pParent) :
    7. QwtLegend(pParent)
    8. {
    9. }
    10.  
    11. protected:
    12. virtual void updateWidget(QWidget *pWidget,
    13. const QwtLegendData &pLegendData)
    14. {
    15. QwtLegend::updateWidget(pWidget, pLegendData);
    16.  
    17. pWidget->setUpdatesEnabled(true);
    18. }
    19. };
    To copy to clipboard, switch view to plain text mode 

    I wish I didn't have to do this, but at least my application is now working as expected.

  8. #8
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QwtLegend: different behaviour when inserting a legend after/before adding curves

    On my box ( Linux/X11 Qt-5.9.1 ) disabling the updates of the plot leads to not painting anything at all - f.e the simpleplot example comes with an empty window frame.
    But this is the expected behavior: if you explicitly disable automatic updates you have to call update manually and of course you need to know what to update.

    But does disabling updates totally make sense in your case ? Usually only repainting of the canvas should be expensive and if you really have unwanted replots - triggered by update - it might be better to disable updates for the canvas only. Or maybe introducing your own flag, that could be handled in YourPlot::replot().

    Uwe

  9. #9
    Join Date
    Mar 2010
    Posts
    319
    Thanks
    1
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QwtLegend: different behaviour when inserting a legend after/before adding curves

    On my box ( Linux/X11 Qt-5.9.1 ) disabling the updates of the plot leads to not painting anything at all - f.e the simpleplot example comes with an empty window frame.
    But this is the expected behavior: if you explicitly disable automatic updates you have to call update manually and of course you need to know what to update.
    Note that in 'my' version of the simpleplot example, I reenable updates by calling setUpdatesEnabled(true) on the QwtPlot object, which results in update() being automatically called on the QwtPlot object. Thus, on Ubuntu 16.04 and with Qt 5.9.3, I am getting the expected result when it comes to the plot, just not the legend (which is 'blank').

    But does disabling updates totally make sense in your case ? Usually only repainting of the canvas should be expensive and if you really have unwanted replots - triggered by update - it might be better to disable updates for the canvas only. Or maybe introducing your own flag, that could be handled in YourPlot::replot().
    I appreciate what you are saying, but there are two cases where I am currently calling setUpdatesEnabled():
    1. I need to customise a plot by modifying several of its properties (line, symbols, colours, etc.). Here, I agree that your approach would work.
    2. I need to customise a 'big' widget that can contain one or several plots (among other things). Because that widget is relatively 'heavy', I call setUpdatesEnabled() on it to disable updates, so that I can do my customisation. Once I am done with my customisation, I reenable updates on my 'big' widget. If I wasn't to do that, I could risk some parts of my widget flashing, which is really ugly in some cases.


    So, although my first case could easily be addressed (using, for example, the approach you described), my second case is much more complex and not worth spending time on it since calling setUpdatesEnabled() to disable and then reenable updates works fine, just not when a QwtPlot object's legend... but I have now got it to work by 'manually' reenabling updates on my QwtPlot object's legend items.

  10. #10
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QwtLegend: different behaviour when inserting a legend after/before adding curves

    I need to customise a plot by modifying several of its properties (line, symbols, colours, etc.).
    Well, update() only schedules a paint event ( in opposite to repaint what has an immediate effect ). So as long as you don't return to event loop you usually don't win anything by disabling updates.
    Also the plot canvas usually has a backing store and as long as the size of the canvas is not changing and you don't invalidate the backing store ( by replot ) manually nothing expensive will happen.

    I need to customise a 'big' widget that can contain one or several plots (among other things). Because that widget is relatively 'heavy', I call setUpdatesEnabled() on it to disable updates, so that I can do my customisation. Once I am done with my customisation, I reenable updates on my 'big' widget.
    Instead of calling the final update you could call replot on your plots. If you don't want to do this you could try to send QEvent::LayoutRequest to the plots instead. Those events will let the plots recalculate their layout - what should be the missing part to give your legend item a proper geometry. But as soon as you have a different layout, the size of the plot canvas changes and ...

    Uwe

Similar Threads

  1. Hide QwtLegend after inserting it???
    By freeman_w in forum Qwt
    Replies: 5
    Last Post: 12th October 2020, 14:38
  2. Replies: 5
    Last Post: 26th June 2015, 16:00
  3. Replies: 8
    Last Post: 29th July 2011, 15:54
  4. Weird QwtLegend Behaviour
    By BettaUseYoNikes in forum Qwt
    Replies: 1
    Last Post: 19th July 2011, 08:28
  5. Replies: 3
    Last Post: 3rd June 2011, 15:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.