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. QStackedWidget: How to check if the next widget should be shown
QtWS25 Last Chance

QStackedWidget: How to check if the next widget should be shown

Scheduled Pinned Locked Moved Solved General and Desktop
qstackedwidgetqstackedwidgets
25 Posts 4 Posters 3.5k 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.
  • H Offline
    H Offline
    hobbyProgrammer
    wrote on last edited by
    #1

    I've made an application with a stacked widget. In the MainWindow the widgets are set. The first widget is a login page, after a succesfull login I'd like to show the second page. How can I check inside the MainWindow if the login was succesfull? (Both widgets are classes with ui's) I also promoted the widgets of the stackedWidget to these classes.

    this is my code:

    MainWindow.cpp

    #include "mainwindow.h"
    #include "loginwidget.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        ui->stackedWidget->setCurrentIndex(0);
        
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    loginWidget.cpp

    #include "loginwidget.h"
    #include "ui_loginwidget.h"
    
    LoginWidget::LoginWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::LoginWidget)
    {
        ui->setupUi(this);
    }
    
    LoginWidget::~LoginWidget()
    {
        delete ui;
    }
    
    bool LoginWidget::loginSuccesfull()
    {
        QString username = ui->lineEdit_2->text();
        QString password = ui->lineEdit->text();
        
        if(username == "Test" && password == "Test123")
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    

    AfterLoginScreen (currently a non-functional widget)

    #include "afterloginscreen.h"
    #include "ui_afterloginscreen.h"
    
    AfterLoginScreen::AfterLoginScreen(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::AfterLoginScreen)
    {
        ui->setupUi(this);
    }
    
    AfterLoginScreen::~AfterLoginScreen()
    {
        delete ui;
    }
    
    JonBJ 1 Reply Last reply
    0
    • H hobbyProgrammer

      @jsulm I'm not sure, but I don't think so.

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

      @hobbyProgrammer said in QStackedWidget: How to check if the next widget should be shown:

      but I don't think so

      Then it can't work.
      Use new Qt5 connect syntax to be sure signal/slot are really connected:

      connect(login, &LoginWidget::loginSuccesfull, this, &MainWindow::showApp);
      

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

      H 1 Reply Last reply
      2
      • H hobbyProgrammer

        I've made an application with a stacked widget. In the MainWindow the widgets are set. The first widget is a login page, after a succesfull login I'd like to show the second page. How can I check inside the MainWindow if the login was succesfull? (Both widgets are classes with ui's) I also promoted the widgets of the stackedWidget to these classes.

        this is my code:

        MainWindow.cpp

        #include "mainwindow.h"
        #include "loginwidget.h"
        #include "ui_mainwindow.h"
        
        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
            , ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
            ui->stackedWidget->setCurrentIndex(0);
            
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        

        loginWidget.cpp

        #include "loginwidget.h"
        #include "ui_loginwidget.h"
        
        LoginWidget::LoginWidget(QWidget *parent) :
            QWidget(parent),
            ui(new Ui::LoginWidget)
        {
            ui->setupUi(this);
        }
        
        LoginWidget::~LoginWidget()
        {
            delete ui;
        }
        
        bool LoginWidget::loginSuccesfull()
        {
            QString username = ui->lineEdit_2->text();
            QString password = ui->lineEdit->text();
            
            if(username == "Test" && password == "Test123")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        

        AfterLoginScreen (currently a non-functional widget)

        #include "afterloginscreen.h"
        #include "ui_afterloginscreen.h"
        
        AfterLoginScreen::AfterLoginScreen(QWidget *parent) :
            QWidget(parent),
            ui(new Ui::AfterLoginScreen)
        {
            ui->setupUi(this);
        }
        
        AfterLoginScreen::~AfterLoginScreen()
        {
            delete ui;
        }
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #2

        @hobbyProgrammer said in QStackedWidget: How to check if the next widget should be shown:

        How can I check inside the MainWindow if the login was succesfull? (

        Call your LoginWidget::loginSuccesfull()!

        If you mean, how do you get a reference to the login widget to call loginWidget->loginSuccesfull(), either keep a reference to the loginWidget at the time you create it/put it into the QStackedWidget, or use something like

        loginWidget = qobject_cast<LoginWidget*>(ui->stackedWidget.widget(1))
        
        H 1 Reply Last reply
        4
        • JonBJ JonB

          @hobbyProgrammer said in QStackedWidget: How to check if the next widget should be shown:

          How can I check inside the MainWindow if the login was succesfull? (

          Call your LoginWidget::loginSuccesfull()!

          If you mean, how do you get a reference to the login widget to call loginWidget->loginSuccesfull(), either keep a reference to the loginWidget at the time you create it/put it into the QStackedWidget, or use something like

          loginWidget = qobject_cast<LoginWidget*>(ui->stackedWidget.widget(1))
          
          H Offline
          H Offline
          hobbyProgrammer
          wrote on last edited by
          #3

          @JonB Oh I'm sorry, it should happen on a pushbutton (when it's pressed, it checks if the login was good)

          So like this:

          bool LoginWidget::loginSuccesfull()
          {
              QString username = ui->lineEdit_2->text();
              QString password = ui->lineEdit->text();
          
              if(username == "Test" && password == "Test123")
              {
                  return true;
              }
              else
              {
                  return false;
              }
          }
          
          void LoginWidget::on_pushButton_clicked()
          {
              loginSuccesfull();
          }
          

          but how do I check the value of loginSuccesfull() in the mainwindow?

          JonBJ 1 Reply Last reply
          0
          • H hobbyProgrammer

            @JonB Oh I'm sorry, it should happen on a pushbutton (when it's pressed, it checks if the login was good)

            So like this:

            bool LoginWidget::loginSuccesfull()
            {
                QString username = ui->lineEdit_2->text();
                QString password = ui->lineEdit->text();
            
                if(username == "Test" && password == "Test123")
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            
            void LoginWidget::on_pushButton_clicked()
            {
                loginSuccesfull();
            }
            

            but how do I check the value of loginSuccesfull() in the mainwindow?

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

            @hobbyProgrammer
            There is no point invoking a function from on_pushButton_clicked() which just returns true or false without acting on the return result.

            There are many ways to achieve what you want. I'll just say that it would be easier if you chose to make the login page a modal dialog instead of one of the stacked widgets. That's a different interface, I don't know how you feel about that.

            If you want to keep the login in stacked widget as now: Probably, stop loginSuccessfull() from being a function returning a boolean. Instead, in the false case have it show the user an error message. In the true case, one of:

            • Have it switch back to some other window by calling QStackedWidget::setCurrentIndex(0) (it will have to have access to ui->stackedWidget).
            • Have it raise a signal to indicate successful logon, and the main window will have a slot for that so that the ui->stackedWidget->setCurrentIndex(0) can be done in the main window.

            Ah, I see at present there is only one stacked widget, the login one, so the first alternative may not make sense. If you want your main window code to know about the login result, use the signal/slot mechanism.

            H 1 Reply Last reply
            2
            • JonBJ JonB

              @hobbyProgrammer
              There is no point invoking a function from on_pushButton_clicked() which just returns true or false without acting on the return result.

              There are many ways to achieve what you want. I'll just say that it would be easier if you chose to make the login page a modal dialog instead of one of the stacked widgets. That's a different interface, I don't know how you feel about that.

              If you want to keep the login in stacked widget as now: Probably, stop loginSuccessfull() from being a function returning a boolean. Instead, in the false case have it show the user an error message. In the true case, one of:

              • Have it switch back to some other window by calling QStackedWidget::setCurrentIndex(0) (it will have to have access to ui->stackedWidget).
              • Have it raise a signal to indicate successful logon, and the main window will have a slot for that so that the ui->stackedWidget->setCurrentIndex(0) can be done in the main window.

              Ah, I see at present there is only one stacked widget, the login one, so the first alternative may not make sense. If you want your main window code to know about the login result, use the signal/slot mechanism.

              H Offline
              H Offline
              hobbyProgrammer
              wrote on last edited by
              #5

              @JonB alright, so I should include the mainWindow.ui file aswell instead of only the loginWidget.ui?

              JonBJ 1 Reply Last reply
              0
              • H hobbyProgrammer

                @JonB alright, so I should include the mainWindow.ui file aswell instead of only the loginWidget.ui?

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

                @hobbyProgrammer
                No, for your case I would suggest LoginWidget::loginSuccesfull() on success should raise a signal, and MainWindow should place a slot on that signal to receive it.

                I'm sorry but I don't have time to write this all out for you, maybe someone else will. Have you read https://doc.qt.io/qt-5/signalsandslots.html, which is the core of how Qt uses signals & slots?

                H 2 Replies Last reply
                0
                • JonBJ JonB

                  @hobbyProgrammer
                  No, for your case I would suggest LoginWidget::loginSuccesfull() on success should raise a signal, and MainWindow should place a slot on that signal to receive it.

                  I'm sorry but I don't have time to write this all out for you, maybe someone else will. Have you read https://doc.qt.io/qt-5/signalsandslots.html, which is the core of how Qt uses signals & slots?

                  H Offline
                  H Offline
                  hobbyProgrammer
                  wrote on last edited by
                  #7

                  @JonB Thanks. That's very helpful!

                  1 Reply Last reply
                  0
                  • JonBJ JonB

                    @hobbyProgrammer
                    No, for your case I would suggest LoginWidget::loginSuccesfull() on success should raise a signal, and MainWindow should place a slot on that signal to receive it.

                    I'm sorry but I don't have time to write this all out for you, maybe someone else will. Have you read https://doc.qt.io/qt-5/signalsandslots.html, which is the core of how Qt uses signals & slots?

                    H Offline
                    H Offline
                    hobbyProgrammer
                    wrote on last edited by hobbyProgrammer
                    #8

                    @JonB so should it be something like this?

                        connect(ui->stackedWidget->indexOf(0), SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                    

                    I might be close, but it's not working yet. Do you see what I am doing wrong?

                    I also tried this:

                        Login *login = ui->stackedWidget->indexOf(0);
                        
                        connect(login, SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                    
                    JonBJ 1 Reply Last reply
                    0
                    • H hobbyProgrammer

                      @JonB so should it be something like this?

                          connect(ui->stackedWidget->indexOf(0), SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                      

                      I might be close, but it's not working yet. Do you see what I am doing wrong?

                      I also tried this:

                          Login *login = ui->stackedWidget->indexOf(0);
                          
                          connect(login, SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                      
                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #9

                      @hobbyProgrammer
                      Whatever else might be wrong, QStackedWidget::indexOf() is totally the wrong way round. As I wrote earlier, you will need to use QStackedWidget::widget(), and if you need a reference to it being a LoginWidget to access members of that class you will want something like:

                      loginWidget = qobject_cast<LoginWidget*>(ui->stackedWidget.widget(0))
                      
                      H 1 Reply Last reply
                      1
                      • JonBJ JonB

                        @hobbyProgrammer
                        Whatever else might be wrong, QStackedWidget::indexOf() is totally the wrong way round. As I wrote earlier, you will need to use QStackedWidget::widget(), and if you need a reference to it being a LoginWidget to access members of that class you will want something like:

                        loginWidget = qobject_cast<LoginWidget*>(ui->stackedWidget.widget(0))
                        
                        H Offline
                        H Offline
                        hobbyProgrammer
                        wrote on last edited by
                        #10

                        @JonB thank you.

                            LoginWidget *login = qobject_cast<LoginWidget*>(ui->stackedWidget->widget(0));
                        
                            connect(login, SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                        

                        I currently get these errors (as loginSuccesfull is a public bool method):

                        QObject::connect: No such signal LoginWidget::loginSuccesfull() in ..\stackedLogin\mainwindow.cpp:14
                        QObject::connect:  (sender name:   'page')
                        QObject::connect:  (receiver name: 'MainWindow')
                        

                        whenever I change loginSuccesfull() to a signal instead of public bool I get these errors:

                        LNK2005:"public: bool _thiscall LoginWidget::loginSuccesfull(void)......" and LNK1169: one or more multiply defined symbols found

                        J.HilkJ JonBJ 2 Replies Last reply
                        0
                        • H hobbyProgrammer

                          @JonB thank you.

                              LoginWidget *login = qobject_cast<LoginWidget*>(ui->stackedWidget->widget(0));
                          
                              connect(login, SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                          

                          I currently get these errors (as loginSuccesfull is a public bool method):

                          QObject::connect: No such signal LoginWidget::loginSuccesfull() in ..\stackedLogin\mainwindow.cpp:14
                          QObject::connect:  (sender name:   'page')
                          QObject::connect:  (receiver name: 'MainWindow')
                          

                          whenever I change loginSuccesfull() to a signal instead of public bool I get these errors:

                          LNK2005:"public: bool _thiscall LoginWidget::loginSuccesfull(void)......" and LNK1169: one or more multiply defined symbols found

                          J.HilkJ Online
                          J.HilkJ Online
                          J.Hilk
                          Moderators
                          wrote on last edited by
                          #11

                          @hobbyProgrammer

                          A Signal must not have a definition, only a declaration.

                          The definition is made automatically in generated code by moc


                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                          Q: What's that?
                          A: It's blue light.
                          Q: What does it do?
                          A: It turns blue.

                          H 1 Reply Last reply
                          3
                          • H hobbyProgrammer

                            @JonB thank you.

                                LoginWidget *login = qobject_cast<LoginWidget*>(ui->stackedWidget->widget(0));
                            
                                connect(login, SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                            

                            I currently get these errors (as loginSuccesfull is a public bool method):

                            QObject::connect: No such signal LoginWidget::loginSuccesfull() in ..\stackedLogin\mainwindow.cpp:14
                            QObject::connect:  (sender name:   'page')
                            QObject::connect:  (receiver name: 'MainWindow')
                            

                            whenever I change loginSuccesfull() to a signal instead of public bool I get these errors:

                            LNK2005:"public: bool _thiscall LoginWidget::loginSuccesfull(void)......" and LNK1169: one or more multiply defined symbols found

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

                            @hobbyProgrammer
                            In some shape or form you have not changed over the code to how signals/slots are declared and work in Qt. There are lots of example to read. You will need correct Qt declarations using signals & slots in your header files, and loginSuccesfull() won't be some bool function, it will emit the signal.

                            I will leave others to help you with this, I don't even do Qt in C++.

                            1 Reply Last reply
                            0
                            • J.HilkJ J.Hilk

                              @hobbyProgrammer

                              A Signal must not have a definition, only a declaration.

                              The definition is made automatically in generated code by moc

                              H Offline
                              H Offline
                              hobbyProgrammer
                              wrote on last edited by
                              #13

                              @J-Hilk alright, but how would I check if the login is correct if there's no function definition?

                              J.HilkJ JonBJ 2 Replies Last reply
                              0
                              • H hobbyProgrammer

                                @J-Hilk alright, but how would I check if the login is correct if there's no function definition?

                                J.HilkJ Online
                                J.HilkJ Online
                                J.Hilk
                                Moderators
                                wrote on last edited by J.Hilk
                                #14

                                @hobbyProgrammer

                                the idea would be, that you emit the signal, as soon as your function verifies, that the login was successful !

                                void LoginWidget::on_pushButton_clicked()
                                {
                                       QString username = ui->lineEdit_2->text();
                                        QString password = ui->lineEdit->text();
                                    
                                        if(username == "Test" && password == "Test123")
                                        {
                                             emit loginSuccessful();
                                        }
                                }
                                

                                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                Q: What's that?
                                A: It's blue light.
                                Q: What does it do?
                                A: It turns blue.

                                1 Reply Last reply
                                3
                                • H hobbyProgrammer

                                  @J-Hilk alright, but how would I check if the login is correct if there's no function definition?

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

                                  @hobbyProgrammer
                                  Subject to @J-Hilk suggesting an alternative, as I wrote earlier retain your loginSuccesfull() as the slot for the pushbutton click. Have it emit a signal you define on successful validation of the widgets, the signal is a separate thing from your function which you must define as per the Qt/C++ rules.

                                  EDIT OK, @J-Hilk's code is the same thing, it's just that he has defined the pushbutton slot as on_pushButton_clicked() and the signal as logInSuccessful, so there is no longer any (non-signal) function named loginSuccesfull().

                                  H 1 Reply Last reply
                                  0
                                  • JonBJ JonB

                                    @hobbyProgrammer
                                    Subject to @J-Hilk suggesting an alternative, as I wrote earlier retain your loginSuccesfull() as the slot for the pushbutton click. Have it emit a signal you define on successful validation of the widgets, the signal is a separate thing from your function which you must define as per the Qt/C++ rules.

                                    EDIT OK, @J-Hilk's code is the same thing, it's just that he has defined the pushbutton slot as on_pushButton_clicked() and the signal as logInSuccessful, so there is no longer any (non-signal) function named loginSuccesfull().

                                    H Offline
                                    H Offline
                                    hobbyProgrammer
                                    wrote on last edited by
                                    #16

                                    @JonB alright, so using that code and these lines:

                                        LoginWidget *login = qobject_cast<LoginWidget*>(ui->stackedWidget->widget(0));
                                        connect(login, SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                                    

                                    should result in showApp to happen anytime the login was succesfull?

                                    JonBJ 1 Reply Last reply
                                    0
                                    • H hobbyProgrammer

                                      @JonB alright, so using that code and these lines:

                                          LoginWidget *login = qobject_cast<LoginWidget*>(ui->stackedWidget->widget(0));
                                          connect(login, SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                                      

                                      should result in showApp to happen anytime the login was succesfull?

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

                                      @hobbyProgrammer
                                      I'm hoping so! Did you try it?

                                      H 1 Reply Last reply
                                      0
                                      • JonBJ JonB

                                        @hobbyProgrammer
                                        I'm hoping so! Did you try it?

                                        H Offline
                                        H Offline
                                        hobbyProgrammer
                                        wrote on last edited by
                                        #18

                                        @JonB yes and it didn't work. I tried debugging but I can't seem to find what's going wrong. It hits the code where the emit loginSuccessfull() is set, but it doesn't go to the SLOT where it's connected to and it ends in :

                                        while (!d->exit.loadAcquire())
                                                processEvents(flags | WaitForMoreEvents | EventLoopExec);
                                        
                                        jsulmJ 1 Reply Last reply
                                        0
                                        • H hobbyProgrammer

                                          @JonB yes and it didn't work. I tried debugging but I can't seem to find what's going wrong. It hits the code where the emit loginSuccessfull() is set, but it doesn't go to the SLOT where it's connected to and it ends in :

                                          while (!d->exit.loadAcquire())
                                                  processEvents(flags | WaitForMoreEvents | EventLoopExec);
                                          
                                          jsulmJ Offline
                                          jsulmJ Offline
                                          jsulm
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #19

                                          @hobbyProgrammer Did you make sure

                                          connect(login, SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                                          

                                          succeeded? And is this "login" the one you're actually showing?

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

                                          H 1 Reply Last reply
                                          1
                                          • jsulmJ jsulm

                                            @hobbyProgrammer Did you make sure

                                            connect(login, SIGNAL(loginSuccesfull()), this, SLOT(showApp()));
                                            

                                            succeeded? And is this "login" the one you're actually showing?

                                            H Offline
                                            H Offline
                                            hobbyProgrammer
                                            wrote on last edited by
                                            #20

                                            @jsulm
                                            it should be since I'm doing this:

                                                LoginWidget *login = qobject_cast<LoginWidget*>(ui->stackedWidget->widget(0));
                                            
                                            jsulmJ 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