Important: Please read the Qt Code of Conduct -

SetGeometry weirdness

  • I have a base class for all my window widgets. I'm implementing a mechanism to retain/restore the last window position. It's implemente in the base class so that this features works on all windows in the system (don't worry, windows are distinguished in persistance using a unique keyword).

    Its destructor retains its geometry using QSettings.
    Its constructor reads those settings, and sets the geometry (first time it just centers the window...)
    All windows are constructed from a *.ui file

    I noticed that when geometry is read and set in the constructor only the X,Y portion of it is respected. Width and Height are ignored and revert to what's 'default' in the *.ui file.

    The interesting thing is that after i "setGeometry()" i read it again just to verify, and indeed the height and width are just as I indicated. The reverting of the width and height is done during the show of the window, not its construction.

    How do I get around that?

  • When you first call show(), the widget starts calculating its size needs. That overrides your manually set geometry. You can set the geometry in a reimplementation of your show() event or using a single shot timer or some other way to defer your call to a later time.

  • We have a similar setup (base class for state-saving windows/dialogs). The straight forward way never worked out for us (this was some years ago, at 4.0/4.1 ages, it might be better now). This is the basic setup:

    • create to bool attributes, saving if the geometry was already restored or saved
    • override showEvent()
      ** if the event is not spontaneous and the geometry was not restored, restore it (and set the bool to true)
      ** call base class' showEvent (eg. QDialog::showEvent())
    • override hideEvent()
      ** if the event is not spontaneous call saveGeometryPrivate()
      ** call the base class' implementation
    • override closeEvent()
      ** call saveGeometryPrivate() (always)
      ** call the base class' implementation
    • probably reimplement slots accpet() and reject() on a QDialog and call saveGeometryPrivate() there
    • in saveGeometryPrivate() do nothing if the isSaved bool is true, otherwise actually save the geometry ("QWidget::saveGeometry() ": is sufficient) and probably other states (you might consider splitter positions, item view column widths and the like) and finally set your bool to true

    We save the state using QSettings as storage engine and the "path" based on the objectName() of the window.

  • Much thanks Volker. I implemented something similar to override my problem but not nearly as detailed as your solution.

Log in to reply