Question

I am developing a GUI in qt. i have a QWidget with four QPushButton inside a QHBoxLayout. Those buttons have an icon each. I need to override QWidget::resizeEvent(QResizeEvent* event) because i don't know exactly what size my window will be. Same thing for my buttons. This means that i have to resize icons too. I thought to place a :

button1->setIconSize(button1->size());

inside myWidget::resizeEvent(QResizeEvent* event) but when i start my application,myWidget::resizeEvent is called recursively.. I tried even setting icon with QtDesigner(eclipse plugin) but nothing.. the only thing that gives good result is setting a fixed size to buttons, but it is not what i need. code of resizeEvent:

void myWidget::resizeEvent(QResizeEvent* event) {

    this->QWidget::resizeEvent(event);
    ui.button1->setIconSize(ui.button1->size());
    ui.button2->setIconSize(ui.button2->size());
    ui.button3->setIconSize(ui.button3->size());
    ui.button4->setIconSize(ui.button4->size());

}

Why resizeEvent is called recursively with setIconSize ? Is there someone who experienced same problem? Suggestions to do the same thing without going through resizeEvent?

Was it helpful?

Solution

As your buttons are in a layout, you have the following infinite loop:

  1. Setting the icon size resizes the button.
  2. Resizing the buttons lets the layout relayout.
  3. Relayouting resizes the widget
  4. resizeEvent is called and sets the icon size
  5. Setting the icon size resizes the button.
  6. Continue with 2...

If you want buttons that match the button size, one way would be a custom QAbstractButton subclass that just paints a pixmap in a custom paintEvent, scaling the pixmap to widget size (which seems to be roughly what you want?). That won't give you the usual button look for free though (visual feedback when pressed, hover, focus frame, etc.).

OTHER TIPS

When you set the iconsize to the size of its container (label, frame), it goes over the border and causes your container to resize, leading to infinite recursion. If you used

ui.button1->setIconSize(ui.button1->(size()-0.01));

you'd have a barely-noticeable difference in your button, and you'd avoid infinite recursion.

There is a not so clean solution, but it is easy and will get the job done.

Depending on the amount of elements inside your QWidget (i.e. layouts containing layouts, etc.), there might be 2 or more automatic resizing operations after the user manually changes the size of the widget. (Thanks Frank Osterfeld for pointing out the problem)

You can add a counter inside your resizeEvent definition and only execute your code if your counter is a multiple of the number of automatic resize operations + 1 (you can find this by trial an error), and reseting it to 0 when your code is executed, so it also works when you maximize your widget.

I'm just a QT newbie, so take this approach with caution since there might be very good reasons not to use it, which I am not aware of.

void
MyWidget::resizeEvent(QResizeEvent *event) 
{
   if((ignore_resize % num_of_auto_ops) == 0)
   {

      this->QWidget::resizeEvent(event);
      ui.button1->setIconSize(ui.button1->size());
      ui.button2->setIconSize(ui.button2->size());
      ui.button3->setIconSize(ui.button3->size());
      ui.button4->setIconSize(ui.button4->size());

      ignore_resize = 0;
   }
   ignore_resize++;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top