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. How to hide a QMainWindow until later?
Forum Updated to NodeBB v4.3 + New Features

How to hide a QMainWindow until later?

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 3 Posters 1.4k Views 2 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.
  • SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by
    #1

    I have created a splash window for my application, this works ok, however I want to hide the original main window until I am ready to display it, it has no ui associated with it, however it still appears even though I have called hide in the class constructor, here is a screenshot showing the new flash window which is shown on top of the original main window which is still appearing:
    Screenshot 2023-11-11 at 08.45.49.png
    Here is the original main window constructor:

    clsMainWnd::clsMainWnd(QWidget* pobjParent) : QMainWindow(pobjParent) {
    //Check that window doesn't already exist
        Q_ASSERT_X(clsMainWnd::mspobjAppWnd==nullptr, "clsMainWnd", "mspobjAppWnd");
    //Hide window until we want to show it
        hide();
    //Create splash window
        new splash(this);
    //Get desktop geometry
        clsMainWnd::msrctDesktop = screen()->geometry();
    //Save pointer to main window
        clsMainWnd::mspobjAppWnd = this;
    //Start socket server thread to listen to modules
    //This application is the socket server, when modules are started they
    //will send a message to this application via the server socket
        mspsckServer = new clsListener(clsListener::uint16NextPort(), this);
    

    Kind Regards,
    Sy

    JonBJ 1 Reply Last reply
    0
    • SPlattenS SPlatten

      I have created a splash window for my application, this works ok, however I want to hide the original main window until I am ready to display it, it has no ui associated with it, however it still appears even though I have called hide in the class constructor, here is a screenshot showing the new flash window which is shown on top of the original main window which is still appearing:
      Screenshot 2023-11-11 at 08.45.49.png
      Here is the original main window constructor:

      clsMainWnd::clsMainWnd(QWidget* pobjParent) : QMainWindow(pobjParent) {
      //Check that window doesn't already exist
          Q_ASSERT_X(clsMainWnd::mspobjAppWnd==nullptr, "clsMainWnd", "mspobjAppWnd");
      //Hide window until we want to show it
          hide();
      //Create splash window
          new splash(this);
      //Get desktop geometry
          clsMainWnd::msrctDesktop = screen()->geometry();
      //Save pointer to main window
          clsMainWnd::mspobjAppWnd = this;
      //Start socket server thread to listen to modules
      //This application is the socket server, when modules are started they
      //will send a message to this application via the server socket
          mspsckServer = new clsListener(clsListener::uint16NextPort(), this);
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @SPlatten
      Are you saying that if you comment out new splash(this); then this main window does not show?
      Have you tried moving the hide() to the caller which creates the clsMainWnd?
      Are you certain that nowhere else in your code does anything show() this main window?

      SPlattenS 1 Reply Last reply
      0
      • JonBJ JonB

        @SPlatten
        Are you saying that if you comment out new splash(this); then this main window does not show?
        Have you tried moving the hide() to the caller which creates the clsMainWnd?
        Are you certain that nowhere else in your code does anything show() this main window?

        SPlattenS Offline
        SPlattenS Offline
        SPlatten
        wrote on last edited by SPlatten
        #3

        @JonB , new splash is the new splash and is the once that shows on top in the screen shot, the window under it is empty and is the clsMainWnd without a ui, but still shows.

        This is the constructor from the splash class:

        splash::splash(QWidget *parent) : QMainWindow(parent)
                                        , ui(new Ui::splash) {
            //Modify the window to occupy full screen with no window dressing
            setWindowFlags(Qt::CustomizeWindowHint
                         | Qt::FramelessWindowHint
                         | Qt::WindowStaysOnTopHint);
            //Get desktop geometry
            QRect rctDesktop(screen()->geometry());
            //Set-up the user interface
            ui->setupUi(this);
            QString strTemp;
            strTemp = QString::asprintf("%dpx", rctDesktop.width());
            ui->lblWidthVal->setText(static_cast<const QString>(strTemp));
            strTemp = QString::asprintf("%dpx", rctDesktop.height());
            ui->lblHeightVal->setText(static_cast<const QString>(strTemp));
            //Set-up one second timer to perform house keeping functions
            QTimer::singleShot(REMOVE_SPLASH_TIME, this, &splash::onRemoveSplash);
        }
        

        Kind Regards,
        Sy

        JonBJ 1 Reply Last reply
        0
        • SPlattenS SPlatten

          @JonB , new splash is the new splash and is the once that shows on top in the screen shot, the window under it is empty and is the clsMainWnd without a ui, but still shows.

          This is the constructor from the splash class:

          splash::splash(QWidget *parent) : QMainWindow(parent)
                                          , ui(new Ui::splash) {
              //Modify the window to occupy full screen with no window dressing
              setWindowFlags(Qt::CustomizeWindowHint
                           | Qt::FramelessWindowHint
                           | Qt::WindowStaysOnTopHint);
              //Get desktop geometry
              QRect rctDesktop(screen()->geometry());
              //Set-up the user interface
              ui->setupUi(this);
              QString strTemp;
              strTemp = QString::asprintf("%dpx", rctDesktop.width());
              ui->lblWidthVal->setText(static_cast<const QString>(strTemp));
              strTemp = QString::asprintf("%dpx", rctDesktop.height());
              ui->lblHeightVal->setText(static_cast<const QString>(strTemp));
              //Set-up one second timer to perform house keeping functions
              QTimer::singleShot(REMOVE_SPLASH_TIME, this, &splash::onRemoveSplash);
          }
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @SPlatten
          Your "splash" screen is a QMainWindow, designed to stay on screen for a second, really? I cannot imagine why you would choose a QMainWindow here...! Per https://doc.qt.io/qt-6/qmainwindow.html#qt-main-window-framework a QMainWindow is used for support for a menu bar, toolbar, dock widgets, central widget and status bar. That is why one uses it. Which of these are required for your one-second splashscreen?

          There is also a QSplashScreen class intended for this, though I don't want to get into a debate over what you doubtless consider your reasons are.

          But that has (or should have) nothing to do with show/hide behaviour.

          I don't know whether what you are seeing is intentional or unavoidable. Can you afford to call new splash() (no this parent) instead, I assume that is the cause of seeing the main window behind the "splash" screen?

          SPlattenS 1 Reply Last reply
          1
          • JonBJ JonB

            @SPlatten
            Your "splash" screen is a QMainWindow, designed to stay on screen for a second, really? I cannot imagine why you would choose a QMainWindow here...! Per https://doc.qt.io/qt-6/qmainwindow.html#qt-main-window-framework a QMainWindow is used for support for a menu bar, toolbar, dock widgets, central widget and status bar. That is why one uses it. Which of these are required for your one-second splashscreen?

            There is also a QSplashScreen class intended for this, though I don't want to get into a debate over what you doubtless consider your reasons are.

            But that has (or should have) nothing to do with show/hide behaviour.

            I don't know whether what you are seeing is intentional or unavoidable. Can you afford to call new splash() (no this parent) instead, I assume that is the cause of seeing the main window behind the "splash" screen?

            SPlattenS Offline
            SPlattenS Offline
            SPlatten
            wrote on last edited by
            #5

            @JonB , I'm really not sure I follow what you are suggesting, presently the new splash class works correctly and does exactly what it is supposed to do, the clsMainWnd which has no ui associated with it is still showing even though hide has been called in the constructor.

            Kind Regards,
            Sy

            JonBJ 1 Reply Last reply
            0
            • SPlattenS SPlatten

              @JonB , I'm really not sure I follow what you are suggesting, presently the new splash class works correctly and does exactly what it is supposed to do, the clsMainWnd which has no ui associated with it is still showing even though hide has been called in the constructor.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @SPlatten
              As I wrote

              Can you afford to call new splash() (no this parent) instead

              You have statement:

              new splash(this);
              

              I am asking what behaviour is if you replace that line with

              new splash();
              

              Is that pretty clear? It's to investigate behaviour, cause of clsMainWnd being shown behind splashscreen.

              SPlattenS 2 Replies Last reply
              0
              • JonBJ JonB

                @SPlatten
                As I wrote

                Can you afford to call new splash() (no this parent) instead

                You have statement:

                new splash(this);
                

                I am asking what behaviour is if you replace that line with

                new splash();
                

                Is that pretty clear? It's to investigate behaviour, cause of clsMainWnd being shown behind splashscreen.

                SPlattenS Offline
                SPlattenS Offline
                SPlatten
                wrote on last edited by SPlatten
                #7

                @JonB , thank you, in an effort to see what is happening I've added the connection:

                    QObject::connect(this, &QMainWindow::showEvent, this, &clsMainWnd::onShowEvent);
                

                To my class constructor, although this results in:

                /Users/sy/XMLMPAM/clsMainWnd.cpp:5507: error: 'showEvent' is a protected member of 'QWidget'
                ../clsMainWnd.cpp:5507:42: error: 'showEvent' is a protected member of 'QWidget'
                    QObject::connect(this, &QMainWindow::showEvent, this, &clsMainWnd::onShowEvent);
                                                         ^
                ../../Qt/5.15.2/clang_64/lib/QtWidgets.framework/Headers/qwidget.h:654:18: note: must name member using the type of the current context 'clsMainWnd'
                    virtual void showEvent(QShowEvent *event);
                                 ^
                

                Kind Regards,
                Sy

                JonBJ 1 Reply Last reply
                0
                • JonBJ JonB

                  @SPlatten
                  As I wrote

                  Can you afford to call new splash() (no this parent) instead

                  You have statement:

                  new splash(this);
                  

                  I am asking what behaviour is if you replace that line with

                  new splash();
                  

                  Is that pretty clear? It's to investigate behaviour, cause of clsMainWnd being shown behind splashscreen.

                  SPlattenS Offline
                  SPlattenS Offline
                  SPlatten
                  wrote on last edited by SPlatten
                  #8

                  @JonB , if I try just:

                      new splash();
                  

                  Then the new splash window doesn't show at all, only the original which is empty.

                  Kind Regards,
                  Sy

                  JonBJ 1 Reply Last reply
                  0
                  • SPlattenS SPlatten

                    @JonB , if I try just:

                        new splash();
                    

                    Then the new splash window doesn't show at all, only the original which is empty.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #9

                    @SPlatten said in How to hide a QMainWindow until later?:

                    only the original which is empty

                    So in that case we can remove the splash screen from code? You are just reporting that creating a QMainWindow and going hide() in its constructor causes "a window with an empty UI" to be shown? Does not your caller which constructs the clsMainWnd go show() on it?

                    I would create a small, standalone test program which exemplifies what you are seeing. It is impossible to know what else might be going on in your code.

                    SPlattenS 1 Reply Last reply
                    1
                    • SPlattenS SPlatten

                      @JonB , thank you, in an effort to see what is happening I've added the connection:

                          QObject::connect(this, &QMainWindow::showEvent, this, &clsMainWnd::onShowEvent);
                      

                      To my class constructor, although this results in:

                      /Users/sy/XMLMPAM/clsMainWnd.cpp:5507: error: 'showEvent' is a protected member of 'QWidget'
                      ../clsMainWnd.cpp:5507:42: error: 'showEvent' is a protected member of 'QWidget'
                          QObject::connect(this, &QMainWindow::showEvent, this, &clsMainWnd::onShowEvent);
                                                               ^
                      ../../Qt/5.15.2/clang_64/lib/QtWidgets.framework/Headers/qwidget.h:654:18: note: must name member using the type of the current context 'clsMainWnd'
                          virtual void showEvent(QShowEvent *event);
                                       ^
                      
                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #10

                      @SPlatten said in How to hide a QMainWindow until later?:

                      QObject::connect(this, &QMainWindow::showEvent, this, &clsMainWnd::onShowEvent);

                      QWidget::showEvent() is not a signal (it is a Qt "event", any method they choose to use Event in its name is their convention, and they are not signals). You cannot connect() a slot to it.
                      You can, however, override it in your derived class.

                      1 Reply Last reply
                      2
                      • JonBJ JonB

                        @SPlatten said in How to hide a QMainWindow until later?:

                        only the original which is empty

                        So in that case we can remove the splash screen from code? You are just reporting that creating a QMainWindow and going hide() in its constructor causes "a window with an empty UI" to be shown? Does not your caller which constructs the clsMainWnd go show() on it?

                        I would create a small, standalone test program which exemplifies what you are seeing. It is impossible to know what else might be going on in your code.

                        SPlattenS Offline
                        SPlattenS Offline
                        SPlatten
                        wrote on last edited by
                        #11

                        @JonB , I'm trying to determine what is going on, the only place where clsMainWnd is created which is derived from QMainWindow is in main:

                        clsMainWnd w;
                        

                        And I've just found the location where show is being called, thank you for you assistance.

                        Kind Regards,
                        Sy

                        JonBJ 1 Reply Last reply
                        0
                        • SPlattenS SPlatten

                          @JonB , I'm trying to determine what is going on, the only place where clsMainWnd is created which is derived from QMainWindow is in main:

                          clsMainWnd w;
                          

                          And I've just found the location where show is being called, thank you for you assistance.

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by
                          #12

                          @SPlatten
                          Yep, usually when a program creates one instance of a QMainWindow (either on the heap or on the stack) it follows that by going mainWindow.show(). Which of course would undo the hide() you have put in its constructor.

                          As a tip: widget constructors should not show (or hide) themselves. The caller should be in charge of showing (or hiding) widgets.

                          1 Reply Last reply
                          2
                          • S Offline
                            S Offline
                            SimonSchroeder
                            wrote on last edited by
                            #13

                            No window shows itself by default. There is no need to add hide() into your constructor. You must be showing the window somewhere else (which is why @JonB suggested to use new splash() without this because this makes it a child of the main window and thus shows it with the main window).

                            The most basic main function looks like this:

                            int main(int argc, char *argv[])
                            {
                                QApplication app(argc,argv);
                                QMainWindow mw;
                                mw.show();
                                return app.exec();
                            }
                            

                            Are you sure you app does not include this mw.show() line? Instead you should call show() on your splash screen (which you don't seem to do).

                            SPlattenS 1 Reply Last reply
                            0
                            • S SimonSchroeder

                              No window shows itself by default. There is no need to add hide() into your constructor. You must be showing the window somewhere else (which is why @JonB suggested to use new splash() without this because this makes it a child of the main window and thus shows it with the main window).

                              The most basic main function looks like this:

                              int main(int argc, char *argv[])
                              {
                                  QApplication app(argc,argv);
                                  QMainWindow mw;
                                  mw.show();
                                  return app.exec();
                              }
                              

                              Are you sure you app does not include this mw.show() line? Instead you should call show() on your splash screen (which you don't seem to do).

                              SPlattenS Offline
                              SPlattenS Offline
                              SPlatten
                              wrote on last edited by
                              #14

                              For the record, this is all done now, here is the splash.cpp:

                              static const int REMOVE_SPLASH_TIME = 10000;
                              /**
                               * @brief splash::splash
                               * @param parent
                               */
                              splash::splash(QWidget *parent) : QMainWindow(parent)
                                                              , ui(new Ui::splash) {
                                  //Modify the window to occupy full screen with no window dressing
                                  setWindowFlags(Qt::CustomizeWindowHint
                                               | Qt::FramelessWindowHint
                                               | Qt::WindowStaysOnTopHint);
                                  //Get desktop geometry
                                  QRect rctDesktop(screen()->geometry());
                                  //Set-up the user interface
                                  ui->setupUi(this);
                                  QString strTemp;
                                  strTemp = QString::asprintf("%dpx", rctDesktop.width());
                                  ui->lblWidthVal->setText(static_cast<const QString>(strTemp));
                                  strTemp = QString::asprintf("%dpx", rctDesktop.height());
                                  ui->lblHeightVal->setText(static_cast<const QString>(strTemp));
                                  //Set-up one second timer to perform house keeping functions
                                  QTimer::singleShot(REMOVE_SPLASH_TIME, this, &splash::onRemoveSplash);
                              }
                              /**
                               * @brief splash::~splash
                               */
                              splash::~splash() {
                                  delete ui;
                              }
                              /**
                               * @brief splash::onRemoveSplash
                               * Removes the splash display when the timer expires
                               */
                              void splash::onRemoveSplash() {
                                  hide();
                              }
                              

                              Kind Regards,
                              Sy

                              JonBJ 1 Reply Last reply
                              0
                              • SPlattenS SPlatten

                                For the record, this is all done now, here is the splash.cpp:

                                static const int REMOVE_SPLASH_TIME = 10000;
                                /**
                                 * @brief splash::splash
                                 * @param parent
                                 */
                                splash::splash(QWidget *parent) : QMainWindow(parent)
                                                                , ui(new Ui::splash) {
                                    //Modify the window to occupy full screen with no window dressing
                                    setWindowFlags(Qt::CustomizeWindowHint
                                                 | Qt::FramelessWindowHint
                                                 | Qt::WindowStaysOnTopHint);
                                    //Get desktop geometry
                                    QRect rctDesktop(screen()->geometry());
                                    //Set-up the user interface
                                    ui->setupUi(this);
                                    QString strTemp;
                                    strTemp = QString::asprintf("%dpx", rctDesktop.width());
                                    ui->lblWidthVal->setText(static_cast<const QString>(strTemp));
                                    strTemp = QString::asprintf("%dpx", rctDesktop.height());
                                    ui->lblHeightVal->setText(static_cast<const QString>(strTemp));
                                    //Set-up one second timer to perform house keeping functions
                                    QTimer::singleShot(REMOVE_SPLASH_TIME, this, &splash::onRemoveSplash);
                                }
                                /**
                                 * @brief splash::~splash
                                 */
                                splash::~splash() {
                                    delete ui;
                                }
                                /**
                                 * @brief splash::onRemoveSplash
                                 * Removes the splash display when the timer expires
                                 */
                                void splash::onRemoveSplash() {
                                    hide();
                                }
                                
                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by
                                #15

                                @SPlatten
                                Now that you have resolved your question. I am still surprised why you would want anything derived from a QMainWindow, plus its menubars etc. that you have been asking about, as a "splash" screen, which is set to disappear after 10 seconds? I know you are working on something "unusual" and generic, but still don't see the use case.

                                SPlattenS 1 Reply Last reply
                                0
                                • JonBJ JonB

                                  @SPlatten
                                  Now that you have resolved your question. I am still surprised why you would want anything derived from a QMainWindow, plus its menubars etc. that you have been asking about, as a "splash" screen, which is set to disappear after 10 seconds? I know you are working on something "unusual" and generic, but still don't see the use case.

                                  SPlattenS Offline
                                  SPlattenS Offline
                                  SPlatten
                                  wrote on last edited by
                                  #16

                                  @JonB , I was using the splash ui in my application purely for experimentation, I now have proven that I can dynamically create menus that are specified in my XML files and I have subscribers that are connected to the menu signals, it all works really well.

                                  Kind Regards,
                                  Sy

                                  1 Reply Last reply
                                  1

                                  • Login

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