Important: Please read the Qt Code of Conduct -

Get QDialog size before showing it

  • Dear Qt users,
    I'm trying to position a QDialog according to user request (centered on screen, in a corner, etc) and I need to retrieve its width and height before actually showing it.

    I found someone with the same problem and he ended up with a dirty trick that involves some processEvents() that I really don't want to have in my code.
    @// BIG PAIN: We want to get the dialog box to caluclate its own size. But there is
    // no simple way to do this. The following seems to work, but only if processEvents
    // is called at least twice. God knows why:
    setAttribute (Qt::WA_DontShowOnScreen, true) ; // Prevent screen flicker
    show() ;

    QEventLoop EventLoop (this) ;
    for (int i = 0 ; i < 10 ; i++)
    if (!EventLoop.processEvents()) break ;

    hide() ;
    setAttribute (Qt::WA_DontShowOnScreen, false) ;@

    From what I read:
    [quote]From the code I've looked at and the Qt defect reports I know why you have to call processEvents: there is a lazy size evaluation, the code to produce a size is only called in response to certain events, like show and resize. I looked through the code and although the sizing functions do exist, there is no possibility to call them directly[/quote]
    Is that sill true?

  • Moderators

    according to the "docs of QWidget::updateGeometry()": i believe it's true.

    But why do you need to know the size beforehand? Can't you just listen to the resize event?
    If you just need to center it on the screen, do this in the showEvent() handler:
    void MyDialog::showEvent(QEvent* event)
    //do centering here, size should be already correct at this point

  • Hum, I did not try to subclass QDialog yet. If this is my only option, I will try that.

  • Moderators

    you can also go with an eventFilter on the dialog. When the showEvent comes in you will have to call the centering of the dialog delayed.
    E.g. with a singleshot timer:
    QTimer::singleShot(0, this, SLOT(centerDialogOnScreen()));

  • Hi all,

    I need this too but none of the exposed solutions actually work.

    bq. If you just need to center it on the screen, do this in the showEvent() handler

    I tried this and does not work in release build with qt 4.8.5. It does work on debug builds. Don't ask me why. :-(

    bq. QTimer::singleShot(0, this, SLOT(centerDialogOnScreen()));

    If you emit delayed then you will have a slight flickering (i already did this). This works in debug and release builds

    Does anyone know why the synchronous call does not work? I tried to look in Qt source code but not without a lot of success

Log in to reply