Hi,
I have searched through the existing questions on this form and have not found anything on this specific issue. I've spent quite a bit of time on this so ANY help would be greatly appriciated.
We have implemented an external legend in a qwtPlot as follows (I believe this is fairly standard implementation):
class AbstractPlotBase : public QwtPlot
{
Q_OBJECT
...
...
void AbstractPlotBase::setLegend( const LegendSettingOption& legendOption )
{
// Every time when set legend, removing the previous legend and
// inserting a new legend is to create a proper legend items
// configuration in a correction direction(horizontal/vertical).
// This way is also to ensure the legend size can be kept as minimum.
QRect legendRect(0,0,0,0);
if( legend() )
{
legendRect = legend()->contentsRect();
}
insertLegend( 0 );
if ( legendOption.isDisplayed() )
{
if ( legendOption.positionMode() == ExternalLegend )
{
if ( legend() )
{
insertLegend( NULL );
}
if ( _externalLegend == NULL )
{
_externalLegend = new Legend( this, true );
connect( _externalLegend, SIGNAL( legendClicked() ), this, SLOT( legendClickedSlot() ) );
connect( _externalLegend, SIGNAL( legendMoved() ), this, SLOT( legendMovedSlot() ) );
connect( this, SIGNAL( legendDataChanged( const QVariant &, const QList<QwtLegendData> & ) ), _externalLegend, SLOT( onLegendChanged( const QVariant &, const QList<QwtLegendData> & ) ) );
QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>( _externalLegend->contentsWidget()->layout() );
tl->setMaxColumns( 1 );
_externalLegend->move( ( width() - legendRect.width() ) * legendOption.hPosition(),
( height() - legendRect.height() ) * legendOption.vPosition() );
updateLegend(); // call before show()
_externalLegend->show();
}
}
else
{
delete _externalLegend;
_externalLegend = NULL;
if ( legend() == NULL || plotLayout()->legendPosition() != qwtLegendPosition( legendOption.positionMode() ) )
{
Legend* tempLegend = new Legend( this, false );
connect( tempLegend, SIGNAL( legendClicked() ), this, SLOT( legendClickedSlot() ) );
insertLegend( tempLegend, qwtLegendPosition( legendOption.positionMode() ) );
}
}
}
else
{
insertLegend( NULL );
delete _externalLegend;
_externalLegend = NULL;
}
}
where we have defined the following legend class:
class Legend : public QwtLegend
{
Q_OBJECT
public:
Legend(QWidget* parent, bool isExternal);
~Legend();
QPoint boundedPosition( const QPoint& pos, const QSize& UsedObjSize ) const;
void mousePressEvent( QMouseEvent* e );
void mouseMoveEvent( QMouseEvent* e );
void mouseReleaseEvent( QMouseEvent* e );
public slots:
void onLegendChanged( const QVariant& itemInfo, const QList<QwtLegendData>& data )
{
updateLegend( itemInfo, data );
}
signals:
void legendClicked();
void legendMoved();
private:
bool _isLegendSelectedForMoving;
QPoint _offsetPos;
bool _isExternal;
};
}
The resulting external legend behaves exactly as expected in all but one case. If we set the legend to external then add a new line to the plot, the legend is not resized. Instead it remains the same size and becomes a scroll box.
We therefore tried modifying the onLegendChanged(...) slot so as to manually resize the legend after updating, as follows:
public slots:
void onLegendChanged( const QVariant& itemInfo, const QList<QwtLegendData>& data )
{
updateLegend( itemInfo, data );
resize( sizeHint().width(), sizeHint().height() );
}
However, this does not work as the sizeHints being returned become invalid after the new line is added. Specifically, the sizeHint() becomes a QSize( 0, X ) value. We have tried overriding the legends sizeHint() and minimumSizeHint() to return contentsWidget()->sizeHint() but this shows the same behaviour. Thus it appears as though adding a new line to the plot corrupts the external legends contentsWidget(). Replacing onLegendChanged with the following extensive debug reporting equivalent:
void onLegendChanged( const QVariant& itemInfo, const QList<QwtLegendData>& data )
{
QList<QWidget *> widgetList = legendWidgets( itemInfo );
qDebug() << "-------------------------------" << endl;
qDebug() << "widgetList.size() = " << widgetList.size() << endl;
qDebug() << "data.size() = " << data.size() << endl;
qDebug() << "sizeHint before update = " << sizeHint() << endl;
updateLegend( itemInfo, data );
resize( sizeHint().width(), sizeHint().height() );
qDebug() << "sizeHint after update = " << sizeHint() << endl;
qDebug() << "contentsWidget()->sizeHint = " << contentsWidget()->sizeHint() << endl;
}
produces the following output (showing correct behaviour) when I switch from top right docked legend to an external legend:
Debug: -------------------------------
Debug: widgetList.size() = 0
Debug: data.size() = 0
Debug: sizeHint before update = QSize(-1, 0)
Debug: sizeHint after update = QSize(-1, 0)
Debug: contentsWidget()->sizeHint = QSize(-1, 0)
Debug: -------------------------------
Debug: widgetList.size() = 0
Debug: data.size() = 1
Debug: sizeHint before update = QSize(-1, 0)
Debug: sizeHint after update = QSize(76, 20)
Debug: contentsWidget()->sizeHint = QSize(76, 20)
Next, adding a new line to the plot produced the following:
Debug: -------------------------------
Debug: widgetList.size() = 1
Debug: data.size() = 1
Debug: sizeHint before update = QSize(76, 20)
Debug: sizeHint after update = QSize(76, 20)
Debug: contentsWidget()->sizeHint = QSize(76, 20)
Debug: -------------------------------
Debug: widgetList.size() = 1
Debug: data.size() = 0
Debug: sizeHint before update = QSize(76, 20)
Debug: sizeHint after update = QSize(-1, 0)
Debug: contentsWidget()->sizeHint = QSize(-1, 0)
Debug: -------------------------------
Debug: widgetList.size() = 0
Debug: data.size() = 1
Debug: sizeHint before update = QSize(-1, 0)
Debug: sizeHint after update = QSize(0, 0)
Debug: contentsWidget()->sizeHint = QSize(0, 0)
Debug: -------------------------------
Debug: widgetList.size() = 0
Debug: data.size() = 1
Debug: sizeHint before update = QSize(0, 0)
Debug: sizeHint after update = QSize(0, 6)
Debug: contentsWidget()->sizeHint = QSize(0, 6)
Debug: -------------------------------
Debug: widgetList.size() = 1
Debug: data.size() = 1
Debug: sizeHint before update = QSize(0, 6)
Debug: sizeHint after update = QSize(0, 6)
Debug: contentsWidget()->sizeHint = QSize(0, 6)
Debug: -------------------------------
Debug: widgetList.size() = 1
Debug: data.size() = 1
Debug: sizeHint before update = QSize(0, 6)
Debug: sizeHint after update = QSize(0, 6)
Debug: contentsWidget()->sizeHint = QSize(0, 6)
I therefore have two specific questions: do I need to resize the legend manually as shown, or have I missed something? If I do need to resize the legend, how do I correctly interrogate the widget size?
Thanks for taking the time to read,
Derek
.... I should add, I'm using qwt 6.1 and qt5![]()
Bookmarks