Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QMessageBox is not positioned correctly when shown during startup

QMessageBox is not positioned correctly when shown during startup

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 6 Posters 4.6k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mrjjM mrjj

    Hi
    I had same issue so i used

    void MainWindow::showEvent ( QShowEvent* ev ) {
      QMainWindow::showEvent ( ev );
      emit MainWindowLoaded();
    }
    

    The other classes then use the MainWindowLoaded signal to know mainwin should be up now.

    Q_ASSERT( connect ( this, SIGNAL ( MainWindowLoaded() ), this, SLOT ( WindowLoaded() ),
    Qt::ConnectionType ( Qt::QueuedConnection | Qt::UniqueConnection ) ));

    This is not perfect as the event might be sent multiple times etc but worked fine for my use case.

    full sample here
    https://stackoverflow.com/questions/14356121/how-to-call-function-after-window-is-shown

    l3u_L Offline
    l3u_L Offline
    l3u_
    wrote on last edited by
    #4

    @mrjj I also tried to put the code inside the MainWindow's showEvent at the end, but even this did not make the message box appear at the right position …

    mrjjM 1 Reply Last reply
    0
    • l3u_L l3u_

      Hi :-)

      I have a program that takes one command line parameter (the file to load). If something goes wrong while loading the file, a QMessageBox is shown. It's not placed correctly (not centered on the MainWindow), most probably because the show() process is not finished yet when the load function is called.

      Here's a minimalistic example for producing the problem (at least on Linux/KDE):

      main.cpp:

      #include "MainWindow.h"
      #include <QApplication>
      
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
          MainWindow mainWindow;
          mainWindow.show();
          mainWindow.loadTournament();
          return app.exec();
      }
      

      MainWindow.h:

      #include <QMainWindow>
      
      class MainWindow : public QMainWindow
      {
          Q_OBJECT
      
      public:
          explicit MainWindow();
          void loadTournament();
      };
      

      MainWindow.cpp:

      #include "MainWindow.h"
      #include <QMessageBox>
      
      MainWindow::MainWindow()
      {
          resize(900, 700);
      }
      
      void MainWindow::loadTournament()
      {
          QMessageBox::critical(this, tr("foo"), tr("bar"), QMessageBox::Ok);
      }
      

      I tried to add QApplication::processEvents(); before the load function call, but it doesn't change anything.

      I also tried to add

      QStringList arguments = QCoreApplication::arguments();
      if (arguments.count() > 1) {
          loadTournament(arguments[1]);
      }
      

      to the end of the main window's constructor, but the behavior is exactly the same, also with a QApplication::processEvents(); before.

      I then tried to use a QTimer with the following code added to the end of the constructor:

      QTimer::singleShot(0, this, &MainWindow::checkLoadTournament);
      

      and

      void MainWindow::checkLoadTournament()
      {
          QStringList arguments = QCoreApplication::arguments();
          if (arguments.count() > 1) {
              loadTournament(arguments[1]);
          }
      }
      

      added. This also produces the very same wrong placement of the QMessageBox.

      If I increase the QTimer wait value (to e. g. 100 msecs), it works. But this seems a bit hacky to me, because I can't be sure if the main window is actually shown within this period of time.

      Is there a way to either know if the main window showing and placement is done and finished correctly and wait for this to be done before showing the QMessageBox or to place it to the right position before?

      Thanks in advance for all help!

      Taz742T Offline
      Taz742T Offline
      Taz742
      wrote on last edited by
      #5

      @l3u_ said in QMessageBox is not positioned correctly when shown during startup:

      void MainWindow::loadTournament()
      {
      QMessageBox::critical(this, tr("foo"), tr("bar"), QMessageBox::Ok);
      }

      try replace this = 0;
      QMessageBox::critical(0, tr("foo"), tr("bar"), QMessageBox::Ok);

      Do what you want.

      l3u_L 1 Reply Last reply
      0
      • l3u_L l3u_

        @mrjj I also tried to put the code inside the MainWindow's showEvent at the end, but even this did not make the message box appear at the right position …

        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #6

        @l3u_
        hi
        but you do it directly in event func.
        Its not finished happening yet
        I do via eventloop and just tested
        with QMessageBox::critical does show centered.

        l3u_L 1 Reply Last reply
        1
        • Taz742T Taz742

          @l3u_ said in QMessageBox is not positioned correctly when shown during startup:

          void MainWindow::loadTournament()
          {
          QMessageBox::critical(this, tr("foo"), tr("bar"), QMessageBox::Ok);
          }

          try replace this = 0;
          QMessageBox::critical(0, tr("foo"), tr("bar"), QMessageBox::Ok);

          l3u_L Offline
          l3u_L Offline
          l3u_
          wrote on last edited by
          #7

          @Taz742 Well, setting 0 as parent causes (as I would expect it …) the message box to be displayed centered on the screen …

          1 Reply Last reply
          0
          • mrjjM mrjj

            @l3u_
            hi
            but you do it directly in event func.
            Its not finished happening yet
            I do via eventloop and just tested
            with QMessageBox::critical does show centered.

            l3u_L Offline
            l3u_L Offline
            l3u_
            wrote on last edited by
            #8

            @mrjj Okay, when doing it via a signal, I could know when the window is set up completely. But how could I do the actual function call? Using a timer that checks periodically if some variable is set to true by the slot called after the show event? I mean, I don't want to call the load function always when the window is shown, but only if it's requested on the command line!

            mrjjM 1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #9

              Hi,

              Just a quick note: never put any function all in a Q_ASSERT or a classic assert expression. The function will never be called in release mode. Store the result of the function and assert on that.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              2
              • l3u_L l3u_

                @mrjj Okay, when doing it via a signal, I could know when the window is set up completely. But how could I do the actual function call? Using a timer that checks periodically if some variable is set to true by the slot called after the show event? I mean, I don't want to call the load function always when the window is shown, but only if it's requested on the command line!

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #10

                @l3u_
                Hi
                Mine is like this

                ctor..
                Q_ASSERT( connect ( this, SIGNAL ( MainWindowLoaded() ), this, SLOT ( WindowLoaded() ),
                                      Qt::ConnectionType ( Qt::QueuedConnection | Qt::UniqueConnection ) ));
                
                void MainWindow::showEvent ( QShowEvent* ev ) {
                  QMainWindow::showEvent ( ev );
                  emit MainWindowLoaded();
                }
                
                // the slot do thestuff
                void MainWindow::WindowLoaded() {
                real stuff
                

                However, as m.sue says, one shot timer is might just be cleaner for you :)

                l3u_L 1 Reply Last reply
                0
                • mrjjM mrjj

                  @l3u_
                  Hi
                  Mine is like this

                  ctor..
                  Q_ASSERT( connect ( this, SIGNAL ( MainWindowLoaded() ), this, SLOT ( WindowLoaded() ),
                                        Qt::ConnectionType ( Qt::QueuedConnection | Qt::UniqueConnection ) ));
                  
                  void MainWindow::showEvent ( QShowEvent* ev ) {
                    QMainWindow::showEvent ( ev );
                    emit MainWindowLoaded();
                  }
                  
                  // the slot do thestuff
                  void MainWindow::WindowLoaded() {
                  real stuff
                  

                  However, as m.sue says, one shot timer is might just be cleaner for you :)

                  l3u_L Offline
                  l3u_L Offline
                  l3u_
                  wrote on last edited by
                  #11

                  @mrjj said in QMessageBox is not positioned correctly when shown during startup:

                  However, as m.sue says, one shot timer is might just be cleaner for you :)

                  I also think so, but what is the reason that the One-Shot-Timer with 0 delay does not change the result whereas the one with 100 ms delay causes the message box to be positionned correctly? Or asking the other way: what delay should I choose to be sure that the main window is always setup completely?

                  jsulmJ mrjjM 2 Replies Last reply
                  0
                  • l3u_L l3u_

                    @mrjj said in QMessageBox is not positioned correctly when shown during startup:

                    However, as m.sue says, one shot timer is might just be cleaner for you :)

                    I also think so, but what is the reason that the One-Shot-Timer with 0 delay does not change the result whereas the one with 100 ms delay causes the message box to be positionned correctly? Or asking the other way: what delay should I choose to be sure that the main window is always setup completely?

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #12

                    @l3u_ In my opinion the timer solution is in this case not very clean. As you already noticed you do not know how long it will take. The solution from @mrjj is is much cleaner.

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • l3u_L l3u_

                      @mrjj said in QMessageBox is not positioned correctly when shown during startup:

                      However, as m.sue says, one shot timer is might just be cleaner for you :)

                      I also think so, but what is the reason that the One-Shot-Timer with 0 delay does not change the result whereas the one with 100 ms delay causes the message box to be positionned correctly? Or asking the other way: what delay should I choose to be sure that the main window is always setup completely?

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #13

                      @l3u_
                      Well you can time it and find a good value.
                      or make it large enough that it will always be enough.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved