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. Choosing a window to show at app launch
QtWS25 Last Chance

Choosing a window to show at app launch

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 5 Posters 711 Views
  • 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.
  • F Offline
    F Offline
    fny82
    wrote on last edited by
    #1

    First off, forgive me for the potentially basic question. I'm still a bit new to Qt in general, and I suspect I'm over-complicating this issue. I'm working on a desktop program in Qt 5.7. There's MainWindow, which is the general UI, but a new QMainWindow has been added named ControllerWindow. The idea is that if the --controlmode argument is passed at runtime, the app will load and display ControllerWindow instead of MainWindow.

    The catch is that MainWindow has a method that needs to be called -- MainWindow::InitValues() -- which ControllerWindow does not have.

    What's the most "correct" way to handle this? I suppose the easy way is to do something like this, but I don't really like it, and feel like I'm an idiot blanking out on some obvious/simple/better approach:

    if (controlModeEnalbed) {
       ControllerWindow cw;
       cw.show();
       return a.exec();
    } else {
       MainWindow mw;
       mw.InitValues();
       mw.show();
       return a.exec();
    }
    

    It works, but I rather prefer the idea of a single point of return instead of that ugliness. Any recommendations? Thank you for your time!

    jsulmJ JonBJ 2 Replies Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi and welcome to the forums

      What about something like

        ControllerWindow cw;
        MainWindow mw;
        mw.InitValues(); // must call always anyway
        QWidget* ToShow = &mw; // assume mainwin
        if (controlModeEnalbed)  ToShow = &cw;
        ToShow->show();
        return a.exec();
      
      1 Reply Last reply
      2
      • F fny82

        First off, forgive me for the potentially basic question. I'm still a bit new to Qt in general, and I suspect I'm over-complicating this issue. I'm working on a desktop program in Qt 5.7. There's MainWindow, which is the general UI, but a new QMainWindow has been added named ControllerWindow. The idea is that if the --controlmode argument is passed at runtime, the app will load and display ControllerWindow instead of MainWindow.

        The catch is that MainWindow has a method that needs to be called -- MainWindow::InitValues() -- which ControllerWindow does not have.

        What's the most "correct" way to handle this? I suppose the easy way is to do something like this, but I don't really like it, and feel like I'm an idiot blanking out on some obvious/simple/better approach:

        if (controlModeEnalbed) {
           ControllerWindow cw;
           cw.show();
           return a.exec();
        } else {
           MainWindow mw;
           mw.InitValues();
           mw.show();
           return a.exec();
        }
        

        It works, but I rather prefer the idea of a single point of return instead of that ugliness. Any recommendations? Thank you for your time!

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

        @fny82

        // I assume here that both windows are derived from QMainWindow
        QMainWindow *window = nullptr;
        if (controlModeEnalbed) {
           window = new ControllerWindow();
        } else {
           window = new MainWindow();
           (dynamic_cast<MainWindow*>(window))->InitValues();
        }
        auto result = a.exec();
        delete window;
        return result;
        

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

        1 Reply Last reply
        0
        • F fny82

          First off, forgive me for the potentially basic question. I'm still a bit new to Qt in general, and I suspect I'm over-complicating this issue. I'm working on a desktop program in Qt 5.7. There's MainWindow, which is the general UI, but a new QMainWindow has been added named ControllerWindow. The idea is that if the --controlmode argument is passed at runtime, the app will load and display ControllerWindow instead of MainWindow.

          The catch is that MainWindow has a method that needs to be called -- MainWindow::InitValues() -- which ControllerWindow does not have.

          What's the most "correct" way to handle this? I suppose the easy way is to do something like this, but I don't really like it, and feel like I'm an idiot blanking out on some obvious/simple/better approach:

          if (controlModeEnalbed) {
             ControllerWindow cw;
             cw.show();
             return a.exec();
          } else {
             MainWindow mw;
             mw.InitValues();
             mw.show();
             return a.exec();
          }
          

          It works, but I rather prefer the idea of a single point of return instead of that ugliness. Any recommendations? Thank you for your time!

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

          @fny82
          Assuming your skeleton to be what you desire, you are saying that MainWindow::InitValues() only needs to be called when you are going to show MainWindow, not when you are going to show ControllerWindow, right?

          When controlModeEnabled you only need ControllerWindow to be created, and when not controlModeEnabled you only need MainWindow to be created, right?

          And I assume both your MainWindow & your ControllerWindow are derived (separately) from QMainWindow, right?

          To be fair, your existing code does implement this logic, so it's not too bad! Thought I probably wouldn't do it that way.

          @mrjj's principle works, but always calls MainWindow::InitValues(), and also always constructs & leaves in existence both instances when you only need one, right?

          There are many ways you could approach this slightly differently from yours or @mrjj's.

          If I take his approach I might suggest:

            QMainWindow *qmw;
            if (controlModeEnabled) {
                MainWindow *mw = new MainWindow;
                mw ->InitValues();
                qmw = mw;
            } else {
                ControllerWindow *cw = new ControllerWindow;
                qmw = cw;
            }
            qmw->show();
            # To avoid leakage from the `new` prior to exit you will need to `delete qmw` or similar
             # I don't do that code 'coz I'm using Python, but you should
             # I leave it as an exercise for you to do correctly!
            return a.exec();
          

          The point here is to new (on the heap) whichever (only) one you want, rather than messing about with local variables on the stack and their scope.

          Another approach would be to derive your own MyBaseMainWindow from QMainWindow, and then derive your two classes from MyBaseMainWindow. Your base MyBaseMainWindow could then have a virtual InitValues() which does nothing, and your MainWindow only need override that with its own code. Then you can always use your_derived_main_window->InitValues() at compile-time. If your two main window classes share other common code this can be nice.

          One other possibility without a base class to avoid the need for calling mw.InitValues(); which you don't like might be to execute it from within MainWindow::showEvent() when first showing. Depends how early you need the initializations.

          In both these alternatives you'd still want the news rather than local variables.

          1 Reply Last reply
          2
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by SGaist
            #5

            Hi,

            Since you need to call InitValues in all cases, why put it in your widget ? It looks like it could be a helper function in your main.cpp that you call as part of your application startup.

            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
            1
            • F Offline
              F Offline
              fny82
              wrote on last edited by
              #6

              Brilliant suggestions. I knew I was over-complicating this. Thank you so much for the feedback and suggestions in this thread. It was immensely helpful and allowed me to solve this problem. I used a version of JonB and jsulm's suggestions, where I used a pointer to get around the scope issue and cast it to run the init method in the event the control mode argument was not in use. This did the trick beautifully. :)

              Simplified example of what I ended up using:

              QMainWindow* startupWindow = nullptr;
              
              if (controlModeEnabled) {
                 startupWindow = new ControllerWindow();
                 startupWindow->show();
              } else {
                 startupWindow = new MainWindow();
                 (dynamic_cast<MainWindow*>(startupWindow))->InitValues();
                 startupWindow->show();
              }
              
              auto execResult = a.exec();
              delete startupWindow;
              
              return execResult;
              
              JonBJ 1 Reply Last reply
              0
              • F fny82

                Brilliant suggestions. I knew I was over-complicating this. Thank you so much for the feedback and suggestions in this thread. It was immensely helpful and allowed me to solve this problem. I used a version of JonB and jsulm's suggestions, where I used a pointer to get around the scope issue and cast it to run the init method in the event the control mode argument was not in use. This did the trick beautifully. :)

                Simplified example of what I ended up using:

                QMainWindow* startupWindow = nullptr;
                
                if (controlModeEnabled) {
                   startupWindow = new ControllerWindow();
                   startupWindow->show();
                } else {
                   startupWindow = new MainWindow();
                   (dynamic_cast<MainWindow*>(startupWindow))->InitValues();
                   startupWindow->show();
                }
                
                auto execResult = a.exec();
                delete startupWindow;
                
                return execResult;
                
                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @fny82 said in Choosing a window to show at app launch:

                startupWindow = new MainWindow();
                (dynamic_cast<MainWindow*>(startupWindow))->InitValues();

                I find this ugly/unwieldy! That's why I wrote:

                  MainWindow *mw = new MainWindow;
                  mw ->InitValues();
                  qmw = mw;
                

                Create an explicit MainWindow* variable first so as to use its method without casting, then assign it to your shared QMainWindow* variable.

                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