open new QMainWindow and close the old one, by keeping QApplication alive.



  • Hi all,
    I’m quite new in Qt world.. so thank you in advance to everyone will help me.
    The question is simple:
    I would like to understand how I can open a new QMainWindow (and close the old one) by keeping the QApplication alive. In the specific a give you my real example.
    I have a “login” QMainWindow with a button. When this button is pressed, the login window should disappear and a new QMainWindow appears.

    So, this is the main:

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Login w;
        w.show();
        return a.exec();
    }
    

    This is the code in the slot ButtonPressed (I defined Market *m in “login.h” as private pointer)

        {
            this->close();
            m=new Market (this);
            m->show();
        }
    

    The issue I get is when the second window appears and the first disappears, the QApplication seems to close. The window is visible, but for example I don’t see the program in Windows taskbar. I'm sure that there is a better mode to program it.
    The same issue I found if I use this.hide() or this.setVisible(false);

    Which is the correct way to implement this?

    I hope I was clear.
    Thank you again. ;)

    P.S.: I don't want to use a QDialog window or something similar. This problem will occur if I want open a third window and close the second one by pressing a button in the second window..



  • int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    a.setQuitOnLastWindowClosed(false);
        Login w;
        w.show();
        return a.exec();
    }
    

    Then you'll have to call QApplication::quit when you want to actually finish



  • @VRonin
    thnak you for your support Ronin,
    I've already tried this solution, but the problem was still present..


  • Moderators

    @FranciscoSantiago said:

    The issue I get is when the second window appears and the first disappears, the QApplication seems to close. The window is visible, but for example I don’t see the program in Windows taskbar. I'm sure that there is a better mode to program it.
    The same issue I found if I use this.hide() or this.setVisible(false);

    what drove you to the conclusion that the app closes? Did your executable finished? Meaning that QApp's exec() returns?
    This shouldn't happen when you just hide the widgets.
    When you close the widgets you need to call setQuitOnLastWindowClosed(false) on the QApp.


  • Qt Champions 2016

    Hello @FranciscoSantiago ,
    You can set the QGuiApplication::quitOnLastWindowClosed property to false. This way, exec will not return when the main window's closed. However in this case you should also take care to call QCoreApplication::quit when appropriate.

    Here's an example:

    class LoginWindow : public QMainWindow
    {
        // ...
    signals:
        void loginSuccessful();
        void loginFailed();
    }
    
    class MainWindow : public QMainWindow
    {
         // ...
    signals:
        void closed();
    
    protected:
        void closeEvent(QCloseEvent * event)
        {
            QMainWindow::closeEvent(event);
    
            if (event->isAccepted())
                emit closed();
        }
    }
    
    int main(int argc, char ** argv)
    {
        QApplication app(argc, argv);
        app.setQuitOnLastWindowClosed(false);
    
        LoginWindow loginWindow;
        MainWindow mainWindow;
    
        // If login is successful, emit LoginWindow::loginSuccessful
        // This would both close the login window and open the main one
        QObject::connect(&loginWindow, &LoginWindow::loginSuccessful, &loginWindow, &QMainWindow::close);
        QObject::connect(&loginWindow, &LoginWindow::loginSuccessful, &mainWindow, &QMainWindow::show);
    
        // If login failed, just close the login window
        QObject::connect(&loginWindow, &LoginWindow::loginFailed, &loginWindow, &QMainWindow::close);
    
        // If login failed, or the main window was closed, quit the application
        // This is needed, because we explicitly set the QGuiApplication::quitOnLastWindowClosed property to false.
        QObject::connect(&mainWindow, &MainWindow::closed, &app, &QCoreApplication::quit);
        QObject::connect(&loginWindow, &LoginWindow::loginFailed, &app, &QCoreApplication::quit);
    
        login.show();
        return QApplication::exec();
    }
    

    Alternatively, you can set the Qt::WA_QuitOnClose attribute to false for your login window. However I advise against it because if you don't handle the closing of the login window properly your application will be left hanging (i.e. running without GUI). At least in the above example the application quitting is made explicit.

    Kind regards.



  • @raven-worx
    Hi raven,
    Maybe I was not clear. I'm not sure that the app closes itself. The only abnormal behavior that I see is that when the first window is running, the bar in my Windows taskbar is present, but when the second window runs and the first one is close, I'm not able to see the bar..and if I reduce to icon the window I'll see a very small icon (maybe the smallest achievable) in the bottom right corner of my screen..

    Thank you anyway



  • @kshegunov
    this is a very interesting advice.
    As soon as I try it, I will inform you.

    Thank you man! ;)


  • Moderators

    @FranciscoSantiago said:

    The only abnormal behavior that I see is that when the first window is running, the bar in my Windows taskbar is present, but when the second window runs and the first one is close, I'm not able to see the bar.

    try to create m=new Market (this); without a parent. This should give you the icon in the taskbar for this window back.
    Also you may want to set the Qt::WA_DeleteOnClose attribute on this window, to make sure it will be deleted once it is closed.

    So you may want to change your code to this:

    {
            this->close();
            m=new Market;
               m->setWindowFlags( Qt::Window );
               m->setAttribute( Qt::WA_DeleteOnClose, true );   //delete itself on closing
               QObject::connect( m, SIGNAL(destroyed(QObject*)), this, SLOT(show()) );  //in case you want to show the login window again once the window is closed
            m->show();
        }
    

    and if I reduce to icon the window I'll see a very small icon (maybe the smallest achievable) in the bottom right corner of my screen..

    you mean the system tray icon? This has to be explicitly set. This happens in the Market class implementation?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.