0

I'm using Qt5 on Windows7.
In my current app I try to display and remove a number of push-buttons.

widget = new ButtonWidget(ui->frame); // frame is a QScrollArea
connect(ui->addBtns,    SIGNAL(clicked()), widget, SLOT(addButtons()));
connect(ui->deleteBtns, SIGNAL(clicked()), widget, SLOT(deleteButtons()));

And the ButtonWidget class is here:

ButtonWidget::ButtonWidget(QWidget * parent) : QWidget(parent)
{
   gridLayout = new QGridLayout(parent);
}

static QStringList texts{...}; // various content (see explanations below)

void ButtonWidget::addButtons()
{
    for(auto i = 0; i < texts.size(); i++)
    {
        gridLayout->addWidget(new QPushButton(texts[i], this), i / 5, i % 5);
    }
}

void ButtonWidget::deleteButtons()
{
    while(gridLayout->count())
    {
        delete gridLayout->itemAt(0)->widget();
    }
}

If I set QStringList texts{"1\nok"}; I get this:
enter image description here
...which is ugly (centered and expanded horizontally on all layout).

If I set QStringList texts{"1\nok",...,"24\nok"}; I get this:
enter image description here
...which is/seems quite ok.

And finally, if I set QStringList texts{"1\nok",...,"36\nok"}; I get this:
enter image description here
...which is very bad, garbled, etc.

So, the question: Is there any way to fix this, i.e. to disable somehow this "shrink-to-fit" on the layout? A default button size would be just fine.
I would like to take advantage of the vertical-scroll feature of the QScrollArea, not to stuff and cram all the buttons in the (limited) available space...

סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
  • Let us know if the duplicate question doesn't cover what you need. – Kuba hasn't forgotten Monica Apr 22 '16 at 12:43
  • @KubaOber: I adapted your code and it works, but... (as always there's a _but_) I am not able to group the buttons only 5 per row (as presented above...). Keeping like in your example, all buttons go on a single row... If I change to `new QVBoxLayout(this);` all buttons go on a single column (obviously)... Any idea what can I do...to get **5 buttons/row**? Thanks in advance! – סטנלי גרונן Apr 22 '16 at 17:00
  • Maybe it's not possible without having some sort of grid-layout...? So, I guess my question is not a duplicate after all... There are some similar aspects, but there are also some differences (my humble opinion). – סטנלי גרונן Apr 22 '16 at 17:04
  • Use a `QGridLayout` instead :) – Kuba hasn't forgotten Monica Apr 22 '16 at 18:23
  • The deuplicate question was using `QBoxLayout`, but the answers should apply to any layout. Just use the layout you want and you'll be set. If you want the buttons to reflow like text would, so that column count will change with resizing the `QScrollArea`, you should use the [`FlowLayout`](http://doc.qt.io/qt-5/qtwidgets-layouts-flowlayout-example.html) example. If you find out anything significant to add, feel free to add your own answer to the other question, too. – Kuba hasn't forgotten Monica Apr 22 '16 at 18:32
  • @KubaOber: I tried to use QGridLayout, but it seems `layout()->addWidget(new QPushButton(texts[i]), i / 5, i % 5);` **doesn't accept 3 parameters**... So, I'm kind of stuck: my code allows 5 buttons per row, but no vertical scroll bar, and your code provides scroll bar, but I can't make it display 5 buttons/row... Any (other) idea? I'll check `FlowLayout` in the meantime. – סטנלי גרונן Apr 23 '16 at 10:42
  • `layout()` returns a generic `QLayout*`. You must cast it to a `QGridLayout*`: `if (dynamic_cast(layout()) dynamic_cast(layout())->addWidget(...);` – Kuba hasn't forgotten Monica Apr 25 '16 at 13:04
  • Late, but I was assigned to other project... Well, back on rails: The idea is it doesn't work because it seems dynamic cast returns null pointer and the app crashes... Using `if` statement (like you suggested above) the app doesn't crash, but it does nothing, i.e. no buttons are added... – סטנלי גרונן May 05 '16 at 11:55
  • Well, the layout in question isn't a grid layout, then. IOW, figure out what objects you're really accessing, and which ones you should be accessing instead. – Kuba hasn't forgotten Monica May 05 '16 at 12:38
  • Pfff, damn it. It seems it was my mistake... I forgot to change `new QHBoxLayout(this);` to `new QGridLayout(this);`. It seems to work now, even if I am not 100% sure the code is correct and the methods to add/delete buttons are ok (add new buttons and delete existing buttons). Would it be ok if I post a new question with the related code and ask your opinion/advice on this matter? Thx in advance! – סטנלי גרונן May 05 '16 at 13:25
  • Sure, ask away, but search first to make sure it's not a duplicate. – Kuba hasn't forgotten Monica May 05 '16 at 16:47

2 Answers2

1

So, the question: Is there any way to fix this, i.e. to disable somehow this "shrink-to-fit" on the layout? A default button size would be just fine.

Of the top of my head, one can set a minimum size per button. One can calculate what the minimum size should be from the font (but first just play with setting the minimum size).

Here is a reference. You will notice that minimumSize takes precedence over layout. It might also change the SizePolicy, which you can also look at. I suggest you play with the designer, as it respects sizing and layouts. One can learn allot from it.

Also look at minimumSizeHint, as the layout interacts with this. See also MasterBLB's comments here

Werner Erasmus
  • 3,988
  • 17
  • 31
1

If you merely add child widgets to a QScrollArea, you won't get any scrolling, since these widgets are not managed by the area in any way. You need to set the widget using QScrollArea::setWidget instead:

widget = new ButtonWidget;
ui->frame->setWidget(widget);
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313