3

I'm writing a very simple test program that when a push button is clicked, a GraphicsView will display an image, a grid layout is used. I want the window size adjust automatically according to the image size. The code is similar to

// load image and setup scene
// ...
ui->graphicsView->show();
ui->graphicsView->updateGeometry();

// adjustSize();
adjustSize();

The problem is that when adjustSize() is called, the window doesn't resize to correct size, and I have to call adjustSize() twice or display a QMessageBox before calling adjustSize() to resize the window to correct size. And btw resize(sizeHint()) gives the same result

I wonder why this is happening and is there an elegant way to do it correctly? Many thanks.

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
lzhang3
  • 85
  • 1
  • 6
  • Closely related: https://stackoverflow.com/questions/73789953/how-to-auto-resize-a-pyside6-app-to-the-minimum-size-when-decreasing-a-pixmap. Check out `QTimer.singleShot`! – bers Sep 20 '22 at 21:33

1 Answers1

5

When you call the adjustSize(), none of the previous calls had any visible effects, since those effects are caused only when the event loop has been run. What you do by calling it multiple times is probably indirectly draining some events from the event loop, same with displaying a QMessageBox via exec() or a static method.

You need to invoke adjustSize from the event loop. Since it is not invokable, you need to make it so in your widget class (or in a helper class).

// Interface
class MyWidget : public QWidget {
  Q_OBJECT
  Q_INVOKABLE void adjustSize() { QWidget::adjustSize(); }
  ...
};

// Implementation
void MyWidget::myMethod() {
  // ...
  ui->graphicsView->show();
  ui->graphicsView->updateGeometry();

  QMetaObject::invokeMethod(this, "adjustSize", Qt::QueuedConnection);
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313