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. Easy switching between Widgets with PushButtons

Easy switching between Widgets with PushButtons

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 4 Posters 12.6k 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.
  • L Offline
    L Offline
    Lunarix
    wrote on 3 May 2017, 06:13 last edited by
    #5

    @Taz742
    Hello, thanks for the reply.
    Do you mean:

    void Widget::on_pusha_clicked()
    {   this->close();
        widget2* a = new widget2();
        a->show();
    
    }
    

    But then I'd create a new instance everytime this function is called.

    @Eligijus
    Hello,
    I looked for this, but the "go back to menu" button should not be always at the same position.
    I tried it. But how should the child widget tell the stackedwidget that he should change setCurrentIndex? I was not able to do it. Can post my code if that helps.
    Thank you for your help

    T E 2 Replies Last reply 3 May 2017, 06:17
    0
    • L Lunarix
      3 May 2017, 06:13

      @Taz742
      Hello, thanks for the reply.
      Do you mean:

      void Widget::on_pusha_clicked()
      {   this->close();
          widget2* a = new widget2();
          a->show();
      
      }
      

      But then I'd create a new instance everytime this function is called.

      @Eligijus
      Hello,
      I looked for this, but the "go back to menu" button should not be always at the same position.
      I tried it. But how should the child widget tell the stackedwidget that he should change setCurrentIndex? I was not able to do it. Can post my code if that helps.
      Thank you for your help

      T Offline
      T Offline
      Taz742
      wrote on 3 May 2017, 06:17 last edited by Taz742 5 Mar 2017, 06:17
      #6

      @Lunarix
      widget is parent widget2 ?

      Do what you want.

      1 Reply Last reply
      0
      • L Offline
        L Offline
        Lunarix
        wrote on 3 May 2017, 06:21 last edited by
        #7

        @Taz742
        Im not sure if I set any parent dependencies.
        Widget is the menu called by the main.

        widget2 is the "settings" screen, which can return to the menu Widget.

        T 1 Reply Last reply 3 May 2017, 06:32
        0
        • L Lunarix
          3 May 2017, 06:21

          @Taz742
          Im not sure if I set any parent dependencies.
          Widget is the menu called by the main.

          widget2 is the "settings" screen, which can return to the menu Widget.

          T Offline
          T Offline
          Taz742
          wrote on 3 May 2017, 06:32 last edited by
          #8

          @Lunarix
          Try This:

          form.h
          #ifndef FORM_H
          #define FORM_H
          
          #include <QWidget>
          #include "mainwindow.h"
          
          class MainWindow;
          
          namespace Ui {
          class Form;
          }
          
          class Form : public QWidget
          {
              Q_OBJECT
          
          public:
              explicit Form(QWidget *parent = 0);
              ~Form();
          
              MainWindow *wind;
          
          private slots:
              void on_pushButton_clicked();
          
          private:
              Ui::Form *ui;
          };
          
          #endif // FORM_H
          
          
          form.cpp
          
          #include "form.h"
          #include "ui_form.h"
          
          Form::Form(QWidget *parent) :
              QWidget(parent),
              ui(new Ui::Form)
          {
              ui->setupUi(this);
          
              wind = new MainWindow();
          }
          
          Form::~Form()
          {
              delete ui;
          }
          
          void Form::on_pushButton_clicked()
          {
              delete this;
          
              wind->show();
          }
          
          mainwindow.h
          
          #ifndef MAINWINDOW_H
          #define MAINWINDOW_H
          
          #include <QMainWindow>
          #include "form.h"
          
          class Form;
          
          namespace Ui {
          class MainWindow;
          }
          
          class MainWindow : public QMainWindow
          {
              Q_OBJECT
          
          public:
              explicit MainWindow(QWidget *parent = 0);
              ~MainWindow();
              Form *wid;
          
          private slots:
              void on_pushButton_clicked();
          
          private:
              Ui::MainWindow *ui;
          };
          
          #endif // MAINWINDOW_H
          
          mainwindow.cpp
          
          #include "mainwindow.h"
          #include "ui_mainwindow.h"
          #include "form.h"
          
          MainWindow::MainWindow(QWidget *parent) :
              QMainWindow(parent),
              ui(new Ui::MainWindow)
          {
              ui->setupUi(this);
          }
          
          MainWindow::~MainWindow()
          {
              delete ui;
          }
          
          void MainWindow::on_pushButton_clicked()
          {
              this->hide();
          
              wid = new Form();
          
              wid->show();
          }
          
          
          

          Do what you want.

          1 Reply Last reply
          0
          • L Offline
            L Offline
            Lunarix
            wrote on 3 May 2017, 06:40 last edited by
            #9

            @Taz742
            Thanks for the help. This looks good - but if I add some output in the constructor i see that there are instances created every time i click on a button.

            I just do not want to have 10000 hidden widgets - or will they get deleted and free memory?

            T 1 Reply Last reply 3 May 2017, 06:52
            0
            • L Lunarix
              3 May 2017, 06:40

              @Taz742
              Thanks for the help. This looks good - but if I add some output in the constructor i see that there are instances created every time i click on a button.

              I just do not want to have 10000 hidden widgets - or will they get deleted and free memory?

              T Offline
              T Offline
              Taz742
              wrote on 3 May 2017, 06:52 last edited by
              #10

              @Lunarix
              Can you write the entire code? And what exactly do you need to explain?

              Do what you want.

              1 Reply Last reply
              0
              • L Offline
                L Offline
                Lunarix
                wrote on 3 May 2017, 06:56 last edited by
                #11

                I use your code and just added the cout line so I see everytime a new instance is created.

                Form::Form(QWidget *parent) :
                    QWidget(parent),
                    ui(new Ui::Form)
                {
                    ui->setupUi(this);
                
                    wind = new MainWindow();
                    std::cout << "Form created"<< std::endl;
                
                }
                

                and it happens everytime i press on a button. So aren't there 10 hidden widgets open after 10 clicks?

                J 1 Reply Last reply 3 May 2017, 07:16
                0
                • L Lunarix
                  3 May 2017, 06:56

                  I use your code and just added the cout line so I see everytime a new instance is created.

                  Form::Form(QWidget *parent) :
                      QWidget(parent),
                      ui(new Ui::Form)
                  {
                      ui->setupUi(this);
                  
                      wind = new MainWindow();
                      std::cout << "Form created"<< std::endl;
                  
                  }
                  

                  and it happens everytime i press on a button. So aren't there 10 hidden widgets open after 10 clicks?

                  J Offline
                  J Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on 3 May 2017, 07:16 last edited by
                  #12

                  @Lunarix Then don't create the instance in on_pusha_clicked(). You can create the instance once for example in the constructor:

                  Widget::Widget()
                  {
                  ...
                      widget2* a = new widget2();
                  ...
                  }
                  

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

                  1 Reply Last reply
                  1
                  • L Offline
                    L Offline
                    Lunarix
                    wrote on 3 May 2017, 07:30 last edited by
                    #13

                    @jsulm
                    Hello, but somehow then the code does not work at all.

                    mainwindow.cpp

                    #include "mainwindow.h"
                    #include "ui_mainwindow.h"
                    #include "form.h"
                    #include <iostream>
                    
                    MainWindow::MainWindow(QWidget *parent) :
                        QMainWindow(parent),
                        ui(new Ui::MainWindow)
                    {
                        ui->setupUi(this);
                        std::cout << "Main created"<< std::endl;
                          //  wid = new Form(); either here
                    }
                    
                    MainWindow::~MainWindow()
                    {
                        delete ui;
                    }
                    
                    void MainWindow::on_pushButton_clicked()
                    {
                        this->hide();
                    
                        wid = new Form(); // or here 
                    
                        wid->show();
                    }
                    
                    

                    But if I use the first, then nothing happens on starting the programm.
                    If i use

                    widget2* a = new widget2();
                    

                    in both constructor then the terminal prints that the MainWindow is created forever (so a loop there).

                    J 1 Reply Last reply 3 May 2017, 07:34
                    0
                    • L Lunarix
                      3 May 2017, 07:30

                      @jsulm
                      Hello, but somehow then the code does not work at all.

                      mainwindow.cpp

                      #include "mainwindow.h"
                      #include "ui_mainwindow.h"
                      #include "form.h"
                      #include <iostream>
                      
                      MainWindow::MainWindow(QWidget *parent) :
                          QMainWindow(parent),
                          ui(new Ui::MainWindow)
                      {
                          ui->setupUi(this);
                          std::cout << "Main created"<< std::endl;
                            //  wid = new Form(); either here
                      }
                      
                      MainWindow::~MainWindow()
                      {
                          delete ui;
                      }
                      
                      void MainWindow::on_pushButton_clicked()
                      {
                          this->hide();
                      
                          wid = new Form(); // or here 
                      
                          wid->show();
                      }
                      
                      

                      But if I use the first, then nothing happens on starting the programm.
                      If i use

                      widget2* a = new widget2();
                      

                      in both constructor then the terminal prints that the MainWindow is created forever (so a loop there).

                      J Offline
                      J Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on 3 May 2017, 07:34 last edited by
                      #14

                      @Lunarix Sorry I have no idea what you are doing!
                      "in both constructor" - what constructors do you mean and why in both?!
                      How is it possible that MainWindow is created in a loop? How and where do you create it?
                      Creating and showing a widget is actually a simple task.

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

                      1 Reply Last reply
                      0
                      • L Lunarix
                        3 May 2017, 06:13

                        @Taz742
                        Hello, thanks for the reply.
                        Do you mean:

                        void Widget::on_pusha_clicked()
                        {   this->close();
                            widget2* a = new widget2();
                            a->show();
                        
                        }
                        

                        But then I'd create a new instance everytime this function is called.

                        @Eligijus
                        Hello,
                        I looked for this, but the "go back to menu" button should not be always at the same position.
                        I tried it. But how should the child widget tell the stackedwidget that he should change setCurrentIndex? I was not able to do it. Can post my code if that helps.
                        Thank you for your help

                        E Offline
                        E Offline
                        Eligijus
                        wrote on 3 May 2017, 08:03 last edited by
                        #15

                        @Lunarix said in Easy switching between Widgets with PushButtons:

                        @Taz742
                        Hello, thanks for the reply.
                        Do you mean:

                        void Widget::on_pusha_clicked()
                        {   this->close();
                            widget2* a = new widget2();
                            a->show();
                        
                        }
                        

                        But then I'd create a new instance everytime this function is called.

                        @Eligijus
                        Hello,
                        I looked for this, but the "go back to menu" button should not be always at the same position.
                        I tried it. But how should the child widget tell the stackedwidget that he should change setCurrentIndex? I was not able to do it. Can post my code if that helps.
                        Thank you for your help

                        You have to ask yourself if you really need to use different classes for pages. If not then moving through pages is quite straight forward

                        connect(ui->pushButton, &QPushButton::released, [this]{ ui->stackedWidget->setCurrentIndex(1); });
                        

                        if you need to use different classes for pages then you would need to access parent widget

                        qobject_cast<QStackedWidget *>(parentWidget())->setCurrentIndex(1);
                        

                        or make connections from class object where you create page objects.

                        L 1 Reply Last reply 3 May 2017, 11:49
                        2
                        • E Eligijus
                          3 May 2017, 08:03

                          @Lunarix said in Easy switching between Widgets with PushButtons:

                          @Taz742
                          Hello, thanks for the reply.
                          Do you mean:

                          void Widget::on_pusha_clicked()
                          {   this->close();
                              widget2* a = new widget2();
                              a->show();
                          
                          }
                          

                          But then I'd create a new instance everytime this function is called.

                          @Eligijus
                          Hello,
                          I looked for this, but the "go back to menu" button should not be always at the same position.
                          I tried it. But how should the child widget tell the stackedwidget that he should change setCurrentIndex? I was not able to do it. Can post my code if that helps.
                          Thank you for your help

                          You have to ask yourself if you really need to use different classes for pages. If not then moving through pages is quite straight forward

                          connect(ui->pushButton, &QPushButton::released, [this]{ ui->stackedWidget->setCurrentIndex(1); });
                          

                          if you need to use different classes for pages then you would need to access parent widget

                          qobject_cast<QStackedWidget *>(parentWidget())->setCurrentIndex(1);
                          

                          or make connections from class object where you create page objects.

                          L Offline
                          L Offline
                          Lunarix
                          wrote on 3 May 2017, 11:49 last edited by Lunarix 5 Mar 2017, 12:46
                          #16

                          @Eligijus
                          Your secound idea works great!
                          I've one last question:
                          If I am in the settings screen and if I make changes in a QComboBox there, let's say a number in the menu should change.
                          So how can I get the data from the settings class to the menu class when I use QStackedWidgets?
                          here is my code:

                          settings.cpp

                          void settings::on_pushButton_clicked()
                          {
                              int data = ui->comboBox->currentIndex();
                              qobject_cast<QStackedWidget *>(parentWidget())->setCurrentIndex(2);
                              qobject_cast<QStackedWidget *>(parentWidget())->settingToGame(data); // This does not work atm
                          }
                          

                          and in mainwindow.h (which has the QStackedWidgets)

                          #include <QtGui>
                          #include "form.h"
                          #include "settings.h"
                          #include "game.h"
                          
                          class Form;
                          class settings;
                          class game;
                          
                          class myMainWindow : public QMainWindow
                          {
                            Q_OBJECT
                          public:
                          
                            myMainWindow():QMainWindow() //Construktor
                            {
                               QWidget* centralWidget = new QWidget();
                               centralWidget->setFixedSize(825,620);
                               m_pStackedWidget = new QStackedWidget();
                               myForm = new Form();
                               Ez_settings = new settings();
                               my_game = new game();
                          
                               m_pStackedWidget->addWidget(myForm); // 0
                               m_pStackedWidget->addWidget(Ez_settings); // 1
                               m_pStackedWidget->addWidget(my_game); // 2
                               //m_pStackedWidget->setFixedSize(480,300);
                          
                               QVBoxLayout *layout = new QVBoxLayout;
                          
                               layout->addWidget(m_pStackedWidget);
                          
                               setCentralWidget(centralWidget);
                               setWindowTitle("Die Siedler von Catan");
                               centralWidget->setLayout(layout);
                               //setFixedSize(800,600);
                          
                            };
                            ~myMainWindow(){ // Destruktor
                          
                            };
                          private:
                            QStackedWidget* m_pStackedWidget;
                            Form*    myForm;
                            settings* Ez_settings;
                            game * my_game;
                          
                          public:
                          
                            void settingToGame(int data){
                                  my_game->data = data;
                          
                            }
                          
                          };
                            }
                          

                          and my_game is a widget which is accessed with setCurrentIndex(2) and has a public variable data.

                          if I change

                          qobject_cast<QStackedWidget *>(parentWidget())->settingToGame(data);
                          

                          to

                          qobject_cast<myMainWindow *>(parentWidget())->settingToGame(data);
                          

                          "The program has unexpectedly finished."

                          So how to get the data there?

                          Thanks for the help! Already helped me a lot
                          Lunarix

                          1 Reply Last reply
                          0
                          • L Offline
                            L Offline
                            Lunarix
                            wrote on 3 May 2017, 12:53 last edited by Lunarix 5 Mar 2017, 12:54
                            #17

                            OK - so now I use

                            qobject_cast<game *>(parentWidget())->settingToGame(data);
                            

                            and I have the settingToGame now in the game class:

                            void game::settingToGame(int data){
                            std::cout << data <<std::endl; // works
                            std::cout << mydata <<std::endl; // crash
                                  this->mydata = data; // crash
                            

                            But this crashes. I can access data, but not view/change mydata which is in the game.h as public: int mydata; and in the constructor mydata=0 declared.
                            Why can't I get the mydata there?

                            1 Reply Last reply
                            0
                            • E Offline
                              E Offline
                              Eligijus
                              wrote on 3 May 2017, 13:03 last edited by
                              #18

                              Well if you want to transfer data between objects that come from one root object then only way to do it is through signals and slots or callbacks.
                              I have made small example that should clear your questions. https://github.com/Ravenghost/ExampleQt
                              Also I don't recommend adding another class for every page like shown in my example (Segment class) just stick to one class(RootWidget) because it makes things way too complicated as you will see from my example. But if you really need to use multiple classes for pages then do something like I did and put QStackedWidget inside QStackedWidget.

                              1 Reply Last reply
                              2
                              • L Offline
                                L Offline
                                Lunarix
                                wrote on 3 May 2017, 14:38 last edited by
                                #19

                                @Eligijus
                                Thanks for the code. I'll have a look.
                                I understand that many classes cause many problems - So:

                                If I use 1 class: Can I change the whole .ui if I press a button so it looks completly different (e.a. menu and game screen). But it all is in one class and then has different buttons for each .ui ?

                                E 1 Reply Last reply 4 May 2017, 05:53
                                0
                                • L Lunarix
                                  3 May 2017, 14:38

                                  @Eligijus
                                  Thanks for the code. I'll have a look.
                                  I understand that many classes cause many problems - So:

                                  If I use 1 class: Can I change the whole .ui if I press a button so it looks completly different (e.a. menu and game screen). But it all is in one class and then has different buttons for each .ui ?

                                  E Offline
                                  E Offline
                                  Eligijus
                                  wrote on 4 May 2017, 05:53 last edited by Eligijus 5 Apr 2017, 05:54
                                  #20

                                  @Lunarix Of course that's how adding pages to QStackedWidget looks in QtCreator:
                                  img

                                  1 Reply Last reply
                                  4
                                  • L Offline
                                    L Offline
                                    Lunarix
                                    wrote on 4 May 2017, 06:02 last edited by
                                    #21

                                    @Eligijus
                                    Thank you so much!
                                    You solved all my problems so far. I did not know I could set up everything in the .ui file directly.
                                    Thanks a lot, and have a nice day! :)

                                    1 Reply Last reply
                                    0

                                    14/21

                                    3 May 2017, 07:34

                                    • Login

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