QwtPlot is broken (size constraints disregarded)
I've been breaking my head over this. My application works fine until I add QwtPlot. It seems like QwtPlot likes to be 200x200 no matter what. Stretch factors don't seem to work with it, size hints don't seem to affect it, size policies have no effect... This widget is broken and I don't know how to fix it.
Here are some examples!
QwtPlot resizes as it pleases, disregarding layout constraints.
Open QtDesigner, add an MDI area, add two sub-windows and add two QwtPlots in each (with layouts, so everything resizes when stretching the window). When switching between the two tabs, the QwtPlot will decide to resize to 200x200 and push the other plot out of view:
https://youtu.be/pXkut7SwKxY
The same is true if you build this structure in code. The following video shows the same issue in my application:
https://youtu.be/-oMESWIeEhM
QwtPlot doesn't obey stretch factors (or it acts weirdly). This next video requires some explanation: I want the plot at the very bottom to have a fixed Y size. The other two plots at the top should scale evenly when the window is resized. This works fine when QwtPlot is not added to the layout. When I add QwtPlot, it no longer does what it should. Notice how the plot at the top actually stretches larger than the one in the middle. Why? Why is this happening?
https://youtu.be/MBIITNObzzg
Things I've tried
Setting row stretch factors does not fix the second issue. QwtPlot ignores these.
Setting the size policy to "Minimum" (or anything else for that matter) has no effect on QwtPlot. It doesn't care.
Manually calling resize() on the main window whenever a subwindow is activated doesn't help. QwtPlot will resize however it sees fit.
I'm out of ideas and would really appreciate some help here.
https://i.imgflip.com/18y94a.jpg
Re: QwtPlot is broken (size constraints disregarded)
A plot widget never changes its geometry on its own. In general the geometries are the job for the layout - not the elements being inside of the layout.
The elements inside of the layout provide some hints ( sizePolicy(), sizeHint() ) and that's it. So if your layout code assigns a bad geometry to its elements you have to fix your layout code.
Uwe
1 Attachment(s)
Re: QwtPlot is broken (size constraints disregarded)
I'm not sure I understand. If I add any other widget (let's say QPushButton) in place of QwtPlot, all of the widgets resize correctly as expected. If, however, I use QwtPlot, that's when things start behaving wrong. So it must have something to do with QwtPlot. Or have I misunderstood what you mean?
Have you tried the thing I explained in QtDesigner with the two mdi subwindows? That shows the exact behaviour I'm talking about. I've attached a ui file for convenience: Attachment 12066
Switch between the mdi tabs and you'll see that the QwtPlot resizes to something it shouldn't.
Also stretch the window on the Y axis and observe how the plots unevenly stretch. Why is this happening?
If you replace the QwtPlot widgets with any other widget it works.
[EDIT] OK so this is really strange. I re-opened the ui file and now I can't resize the window any smaller than 200x400. It seems you have to create the QwtPlot widgets in a window that is smaller than the initial 200x200 plot widget size.
Either way, the resize behaviour of QwtPlot isn't doing what it's supposed to and I don't think it's due to my layout code.
Re: QwtPlot is broken (size constraints disregarded)
I have come closer to the actual problem.
If I add widgets to my layout in the constructor, everything works (even with QwtPlot). If I add my widgets to the layout later on (e.g. after loading a file) that's when the layout constraints are ignored.
What do you think could be causing this?
Re: QwtPlot is broken (size constraints disregarded)
Alright I have an example that reproduces the problem I'm having.
layoutproblem.h
Code:
#ifndef LAYOUTPROBLEM_H
#define LAYOUTPROBLEM_H
#include <QWidget>
class QMdiArea;
class LayoutProblem
: public QWidget{
Q_OBJECT
public:
explicit LayoutProblem
(QWidget *parent
= 0);
virtual ~LayoutProblem();
private slots:
void createUI();
private:
QMdiArea* mdiArea_;
};
#endif // LAYOUTPROBLEM_H
layoutproblem.cpp
Code:
#include "layoutproblem.h"
#include <QVBoxLayout>
#include <QGridLayout>
#include <QMdiArea>
#include <QTimer>
#include <QTabWidget>
#include <QApplication>
#include <qwt_plot.h>
LayoutProblem
::LayoutProblem(QWidget *parent
) : mdiArea_(new QMdiArea)
{
layout()->addWidget(mdiArea_);
mdiArea_->setViewMode(QMdiArea::TabbedView);
resize(200, 200);
QTimer::singleShot(500,
this,
SLOT(createUI
()));
// createUI();
}
LayoutProblem::~LayoutProblem()
{
}
void LayoutProblem::createUI()
{
for(unsigned i = 0; i != 3; ++i)
{
window
->layout
()->addWidget
(new QwtPlot);
window
->layout
()->addWidget
(new QwtPlot);
tab
->addTab
(window,
"tab " + QString::number(i
));
mdiArea_->addSubWindow(tab);
tab->showMaximized();
}
}
int main(int argc, char *argv[])
{
LayoutProblem w;
w.show();
return a.exec();
}
Run this code and you will notice that you can scale the widget much smaller than the minimum size hint. Next, try commenting the QTimer line and call createUI() directly:
Code:
// QTimer::singleShot(500, this, SLOT(createUI()));
createUI();
Re-run the code and now everything works as expected.
How can I add widgets to my layouts dynamically without Qt ignoring the minimum size hints?
Re: QwtPlot is broken (size constraints disregarded)
Quote:
Originally Posted by
TheComet
Alright I have an example that reproduces the problem I'm having.
Sorry, but your problem is a general layout issue - obviously unrelated to Qwt. Better create a new request ( replacing QwtPlot by a standard QWidget ) in the programming section.
Uwe
Re: QwtPlot is broken (size constraints disregarded)
2 Attachment(s)
Re: QwtPlot is broken (size constraints disregarded)
Quote:
Originally Posted by
Uwe
Sorry, but your problem is a general layout issue - obviously unrelated to Qwt. Better create a new request ( replacing QwtPlot by a standard QWidget ) in the programming section.
No, there is definitely a problem with Qwt as well. If I set the row stretch factors to "1, 1, 0" (I want the widget at the very bottom to always have minimum height), QwtPlot doesn't obey.
The stretch factors work fine with any Qt widget. Here's a QPushButton:
Attachment 12079
The stretch factors DON'T work with QwtPlot:
Attachment 12078
QwtPlot tries to resize to 200x200 and disregards the stretch factors. Am I doing something wrong?
qwtplotproblem.h
Code:
#ifndef QWTPLOTPROBLEM_H
#define QWTPLOTPROBLEM_H
#include <QWidget>
class QwtPlotProblem
: public QWidget{
Q_OBJECT
public:
explicit QwtPlotProblem
(QWidget *parent
= 0);
~QwtPlotProblem();
private slots:
void createUI();
};
#endif // QWTPLOTPROBLEM_H
qwtplotproblem.cpp
Code:
#include "qwtplotproblem.h"
#include <QGridLayout>
#include <QPushButton>
#include <QTimer>
#include "qwt_plot.h"
QwtPlotProblem
::QwtPlotProblem(QWidget *parent
) :{
// QTimer::singleShot(500, this, SLOT(createUI()));
createUI();
}
QwtPlotProblem::~QwtPlotProblem()
{
}
void QwtPlotProblem::createUI()
{
plot->setMinimumSize(40, 40);
layout()->addWidget(plot);
plot->setMinimumSize(40, 40);
layout()->addWidget(plot);
plot->setMinimumSize(40, 40);
layout()->addWidget(plot);
l->setRowStretch(0, 1);
l->setRowStretch(1, 1);
l->setRowStretch(2, 0);
}
Re: QwtPlot is broken (size constraints disregarded)
Quote:
No, there is definitely a problem with Qwt as well. If I set the row stretch factors to "1, 1, 0" (I want the widget at the very bottom to always have minimum height), QwtPlot doesn't obey.
There is no "obeying": if you ( or your layout ) set a geometry to a plot it has this geometry, if you set the geometry being below the minimum size hint things will be cut off. That's it - the plot widget doesn't refuse any geometries.
Your problem seems to be, that the geometries calculated by your layout are not those you want to have. But this is again unrelated to Qwt - it is your layout code.
Quote:
Here's a QPushButton:
A pushbutton has different size hints - the hints for a plot depend on the space, that is needed to display the labels.
I recommend to spend some time on trying to understand how the QLayout system works: f.e. your layout first distributes the width/height according to the size hints of the widgets - what are different values. Only when there is more space available it decides according to the stretch factors ( and size policies ) how to distribute the rest.
To make it short: overload QwtPlot::sizeHint() returning something else and see how it works.
Uwe
Re: QwtPlot is broken (size constraints disregarded)
Quote:
Originally Posted by
Uwe
To make it short: overload QwtPlot::sizeHint() returning something else and see how it works.
Thanks, this is the solution I went with.
Code:
protected:
virtual QSize sizeHint
() const { return QSize(1,
1);
} };
In conjunction with:
Code:
MyPlot* plot = new MyPlot;
plot->setMinimumSize(X, Y); // replace X and Y with something suitable