Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

qt resize window after widget remove

Tags:

c++

qt

I'm adding widget in layout

ui->horizontalLayout->addWidget(tabwidget);

and qmainwindow resizes itself. But then I do

tabwidget->setVisible(false);
qs = sizeHint();
resize(qs);

I get the size like tabwidget was not removed from window.

I've made new button

void MainWindow::on_pushButton_2_clicked()
{
    qs = sizeHint();
    resize(qs);
}

and it gives correct size.

Seems I need some update function but I can't find it. Please advice

like image 695
quux Avatar asked Dec 18 '12 22:12

quux


2 Answers

This is caused by a long-time internal Qt issue (I remember experiencing it first with Qt3). The top widget needs to receive an event to truly update its geometry, and know its boundaries. This event seems to be always received after the resize event generated by the layout, and therefore it is always too late to shrink the widget.

The solution posted in the accepted answer works. However a simpler solution posted below also works, when added after the layout :

layout()->removeWidget( widget );

QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
resize( sizeHint() );

Basically all we need is to let the event loop run and deliver the necessary events so the top widget geometry is updated before resize() is run.

Note that this code might have side effects if you have multiple threads running, or there are events delivered to your slots. Hence it is safer not to have any code in this function after resize().

like image 53
George Y. Avatar answered Sep 28 '22 09:09

George Y.


If the button slot gives you the correct result then you can always call the sizeHint() and subsequent resize() in a slot which is called by a single shot timer:

void MainWindow::fixSize()
{
    QSize size = sizeHint();
    resize(size);
}

void MainWindow::methodWhereIHideTheTabWidget()
{
    tabwidget->setVisible(false);
    QTimer::singleShot(0, this, SLOT(fixSize()));
}

This timer is set to zero delay. This means that the slot will be called immediatelly when the program returns to the main loop and hopefully after the internal widget state gets updated. If this doesn't resolve your problem you may try replacing zero with 1.

like image 25
ZalewaPL Avatar answered Sep 28 '22 09:09

ZalewaPL