PDA

View Full Version : Automatically resizing custom QWidget based on runtime specifications



nicole.cpp
26th August 2013, 23:32
I have a custom QWidget that displays some number of QSliders, depending on the labels passed into its constructor:


NodeEditBox(QWidget* _parent, vector<string> _sliderLabels);

So, for example, the box would look like this if 4 labels "X", "Y", "Z", and "theta" were passed in:

9484

I want to automatically resize the NodeEditBox depending on the number of sliders it will have. One way that works is just doing this right in the beginning of the constructor body:


resize(450, 75*(_sliderLabels.size()));

...But it doesn't always scale quite right and can look sloppy (e.g., what works nicely for 3 sliders doesn't work for one.) Is there a way I can be more clean about it and just require that the NodeEditBox always displays all of its widgets?

wagmare
27th August 2013, 04:51
override resizeEvent of the window and use setGeometry(x,y, fixedWidth, sliderSize()) .

Santosh Reddy
27th August 2013, 05:15
Is there a way I can be more clean about it and just require that the NodeEditBox always displays all of its widgets?
If you are using a layout then this will be default behaviour, by default layouts will adjust such that all the widgets (1 slider/3 slliders) fit into the available space.

1. Show us the actual screen shot of the widget where 1 slider is looks sloppy.
2. By "sloppy" do you mean that widgets are not snugly fitted?
3. Where is this custom widget loaded? Onto to scroll area? or onto another layout? or onto another widget directly (without layout)?

ChrisW67
27th August 2013, 06:31
This may help. On the vertical layout the sliders are in:


layout->setSizeConstraint(QLayout::SetFixedSize);

and the widget's size will track the sizeHint() which is, in turn, derived from the size hints of the sliders. This will also lock the horizontal size but you can force a workable size with setMinimumSize() on the sliders.


class Widget: public QWidget {
Q_OBJECT
public:
explicit Widget(QWidget *p, const QStringList &labels): QWidget(p) {
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setSizeConstraint(QLayout::SetFixedSize);
foreach(const QString &label, labels) {
QSlider *s = new QSlider(Qt::Horizontal, this);
s->setMinimumWidth(200);
layout->addWidget(s);
}
setLayout(layout);
}
};

nicole.cpp
27th August 2013, 16:37
Here is what happens in a typical case with my current code: it works for 2 or 3, but obscures one (I'll worry about the giant set button later...ha ha). When I think about it, it makes sense; factoring in the top area makes all the difference:
948694879488

As for the constructor, it is like this. The m_nodeLabel is set by a different function called after construction:



18 NodeEditBox::NodeEditBox(QWidget* _parent, vector<string> _sliderLabels){
19
20 resize(450, 90*(_sliderLabels.size()));
21 setWindowTitle("Modify Node");
22
23 m_layout = new QVBoxLayout();
24
25 m_nodeLabel = new QLabel(this);
26 m_nodeLabel->setGeometry(QRect(10, 10, 67, 21));
27 m_layout->addWidget(m_nodeLabel);
28
29 for(size_t i = 0; i < _sliderLabels.size(); i++){
30 NodeEditSlider* s = new NodeEditSlider(this, _sliderLabels[i]);
31 m_sliders.push_back(s);
32 m_layout->addWidget(s);
33 }
34
35 m_setButton = new QPushButton(this);
36 m_setButton->setText("Set");
37 m_layout->addWidget(m_setButton);
38
39 this->setLayout(m_layout);
40 }



Here is the NodeEditSlider widget constructor. I made it on the QtDesigner and then pasted the code into my program and modified it as needed (removing retranslate UI business, etc...) :



3 NodeEditSlider::NodeEditSlider(QWidget* _parent, string _label){
4
5 m_slider = new QSlider(this);
6 m_slider->setGeometry(QRect(50, 10, 371, 20));
7 m_slider->setOrientation(Qt::Horizontal);
8
9 m_label = new QLabel(this);
10 m_label->setGeometry(QRect(10, 10, 41, 21));
11
12 QString label = QString::fromStdString(_label);
13 m_label->setText(label);
14
15 }




Added after 1 48 minutes: