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. Is changing a QWizard into a QStackedWidget the best option?
Forum Updated to NodeBB v4.3 + New Features

Is changing a QWizard into a QStackedWidget the best option?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt 4.8.5qt 4.8qwizardqstackedwidget
12 Posts 2 Posters 5.5k Views 3 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.
  • M mrjj
    12 May 2016, 11:20

    Hi
    The Stackedwidget is super for such design.
    The widget it talks about is a page.
    so u get all the pages u want and on each page,
    u can have all the widgets u like.

    Normally the page is a plain
    qwidget but u can use own page if u need but
    often there is no need.

    ps. if you use UI files, you can visually manage all the pages. very handy.

    R Offline
    R Offline
    roseicollis
    wrote on 12 May 2016, 11:43 last edited by
    #3

    Hi @mrjj thank you for your reply. I'm really happy to know that QStackedWidget is the right way I have to take :D

    Now what I have is a QWizard that creates the QWizardpages with its behaviour:

    //QWizard .cpp constructor:
    WP1 *page1 = new WP1;
    setPage(Page1Mode, page1);
    
    // .h declaration
    enum {Page1Mode, Page2Mode, ...}
    

    So I imagine that now I need to have something like class MyStacked : public QStackedWidget and in its constructor something like:

    Page1Class *Page1 = new Page1Class();
    addWidget(Page1);
    

    am I right? So.. as this is my first contact with Qt I don't really know so much about it and its classes... you said: "Normally the page is a plain qwidget" ... So you mean that my pages will be something like class Page1: public QWidget ?? and there I can add my layouts and Qlabels and other QWidget as i had in my QWizardPages?

    Another thing? What about the tipical Next/Back buttons of the wizard configuration programs? As I said I don't need them all in every page so.. should I create them in every page of could I put them outside the QStackedWidget and make them general and just hide/ change their behaviour depending of the page shown?

    and a last question: With the wizard I could use the registerfield / set field functions to pass information between the QWizardPages so... how should I do it now ? Which will be the best method to avoid making global variables or a signal for every one? I'm talking that Page3 will need 5 different variables values from Page2 and other 6 differents from Page1 for example.

    Thank you!!!

    M 1 Reply Last reply 12 May 2016, 12:00
    0
    • R roseicollis
      12 May 2016, 11:43

      Hi @mrjj thank you for your reply. I'm really happy to know that QStackedWidget is the right way I have to take :D

      Now what I have is a QWizard that creates the QWizardpages with its behaviour:

      //QWizard .cpp constructor:
      WP1 *page1 = new WP1;
      setPage(Page1Mode, page1);
      
      // .h declaration
      enum {Page1Mode, Page2Mode, ...}
      

      So I imagine that now I need to have something like class MyStacked : public QStackedWidget and in its constructor something like:

      Page1Class *Page1 = new Page1Class();
      addWidget(Page1);
      

      am I right? So.. as this is my first contact with Qt I don't really know so much about it and its classes... you said: "Normally the page is a plain qwidget" ... So you mean that my pages will be something like class Page1: public QWidget ?? and there I can add my layouts and Qlabels and other QWidget as i had in my QWizardPages?

      Another thing? What about the tipical Next/Back buttons of the wizard configuration programs? As I said I don't need them all in every page so.. should I create them in every page of could I put them outside the QStackedWidget and make them general and just hide/ change their behaviour depending of the page shown?

      and a last question: With the wizard I could use the registerfield / set field functions to pass information between the QWizardPages so... how should I do it now ? Which will be the best method to avoid making global variables or a signal for every one? I'm talking that Page3 will need 5 different variables values from Page2 and other 6 differents from Page1 for example.

      Thank you!!!

      M Offline
      M Offline
      mrjj
      Lifetime Qt Champion
      wrote on 12 May 2016, 12:00 last edited by
      #4

      @roseicollis
      class MyStacked : public QStackedWidget
      That you only do if u need a subclass.
      else just use the base one.

      http://doc.qt.io/qt-5/qstackedwidget.html
      To insert u use
      http://doc.qt.io/qt-5/qstackedwidget.html#addWidget

      class Page1: public QWidget
      That you only need if u want a special page.
      Else u just
      new a QWidget and use for page. And add layout and stuff to it.
      You can use any widget as page.

      • Another thing? What about the tipical Next/Back buttons of the wizard configuration
        I would just put them outside and mainwindow controls the logic of next/prev and hide buttons.

      A more fancy version would be a custom composite control where it contains the logic inside but for 1 app. letting main handle it should be fine.

      -and a last question:
      I would have a Data class. and each page will save info to this class.
      So if page 5 read the data it will get what ever page 1 updated etc.
      No need to let the pages directly access each other.

      R 1 Reply Last reply 12 May 2016, 14:49
      0
      • M mrjj
        12 May 2016, 12:00

        @roseicollis
        class MyStacked : public QStackedWidget
        That you only do if u need a subclass.
        else just use the base one.

        http://doc.qt.io/qt-5/qstackedwidget.html
        To insert u use
        http://doc.qt.io/qt-5/qstackedwidget.html#addWidget

        class Page1: public QWidget
        That you only need if u want a special page.
        Else u just
        new a QWidget and use for page. And add layout and stuff to it.
        You can use any widget as page.

        • Another thing? What about the tipical Next/Back buttons of the wizard configuration
          I would just put them outside and mainwindow controls the logic of next/prev and hide buttons.

        A more fancy version would be a custom composite control where it contains the logic inside but for 1 app. letting main handle it should be fine.

        -and a last question:
        I would have a Data class. and each page will save info to this class.
        So if page 5 read the data it will get what ever page 1 updated etc.
        No need to let the pages directly access each other.

        R Offline
        R Offline
        roseicollis
        wrote on 12 May 2016, 14:49 last edited by
        #5

        @mrjj said:

        just use the base one.

        Then the base class of my app should be a QMainWindow where I create a QStackedWidget and add my QWidget pages or should I use another Base Class?

        class Page1: public QWidget
        That you only need if u want a special page. Else u just new a QWidget and use for page. And add layout and stuff to it.

        Yes but if I do it that means that if I need 30 pages I will have at least 30 layouts created with more than 100 different qwidgets all together which will be very ugly to see in code and difficult to understand to anyone that cames after me. So I think it will be better making a class for every page and create there all the QWidgets needed for that page... what do you think?

        M 1 Reply Last reply 12 May 2016, 14:54
        0
        • R roseicollis
          12 May 2016, 14:49

          @mrjj said:

          just use the base one.

          Then the base class of my app should be a QMainWindow where I create a QStackedWidget and add my QWidget pages or should I use another Base Class?

          class Page1: public QWidget
          That you only need if u want a special page. Else u just new a QWidget and use for page. And add layout and stuff to it.

          Yes but if I do it that means that if I need 30 pages I will have at least 30 layouts created with more than 100 different qwidgets all together which will be very ugly to see in code and difficult to understand to anyone that cames after me. So I think it will be better making a class for every page and create there all the QWidgets needed for that page... what do you think?

          M Offline
          M Offline
          mrjj
          Lifetime Qt Champion
          wrote on 12 May 2016, 14:54 last edited by
          #6

          @roseicollis
          Well if your application is of normal type then
          using QMainwindow as center seems good choice.
          You just place a QStacked in its UI and start adding pages.

          • 30 pages
            making a class for every page and create there all the QWidgets needed for that page... what do you think?

          Well I would add it all in UI file and there will be no need to see any of the code.

          But since I dont know how much processing each page does, its hard to say
          if your own sub class as page is better as u can then hook up signals etc internally.

          so depends on how much going on in each page.

          R 1 Reply Last reply 12 May 2016, 15:19
          1
          • M mrjj
            12 May 2016, 14:54

            @roseicollis
            Well if your application is of normal type then
            using QMainwindow as center seems good choice.
            You just place a QStacked in its UI and start adding pages.

            • 30 pages
              making a class for every page and create there all the QWidgets needed for that page... what do you think?

            Well I would add it all in UI file and there will be no need to see any of the code.

            But since I dont know how much processing each page does, its hard to say
            if your own sub class as page is better as u can then hook up signals etc internally.

            so depends on how much going on in each page.

            R Offline
            R Offline
            roseicollis
            wrote on 12 May 2016, 15:19 last edited by
            #7

            @mrjj I understand... the thing is that every widget I use (layouts, labels, pushbuttons, combobox...) I create them by code like QLabel lab1 = new QLabel(); because it's faster for me and I prefer using its functions for position and height/width than just drag and drop on the ui file (which normally I have all in blank or I just don't have them). I'll think about if I should put it in the ui or in the code...

            One thing: I've created a new project to test that. The base clase of the project is QMainWindow so in its constructor I've write:

                QStackedWidget *st = new QStackedWidget;
                Page1 *page1 = new Page1;
                st->addWidget(page1);
            
                QVBoxLayout *layout = new QVBoxLayout;
                   layout->addWidget(st);
                   setLayout(layout);
            

            And then I've created a Page1 like this:

            //.h file:
            class Page1 : public QWidget
            {
                Q_OBJECT
            public:
                explicit Page1(QWidget *parent = 0);
                ~Page1();
            private:
                Ui::Page1 *ui;
                QPushButton *_b1;
                QPushButton *_b2;
            };
            
            //.cpp file, constructor:
            Page1::Page1(QWidget *parent) :
                QWidget(parent),
                ui(new Ui::Page1)
            {
                ui->setupUi(this);
               _b1 = new QPushButton;
               _b2 = new QPushButton;
            
               _b1->setText(QString::fromUtf8("AAAA"));
               _b1->setMinimumSize(320,100);
               _b1->setMaximumSize(320,100);
            
               _b2->setText(QString::fromUtf8("BBBB"));
               _b2->setMinimumSize(320,100);
               _b2->setMaximumSize(320,100);
            
               _b1->setVisible(true);
               _b2->setVisible(true);
            }
            

            And when I run the program what I expect to see is a windows with 2 QPushButtons with texts AAAA and BBBB but instead of this what I get is 3 windows opened at the same time: One for MainWindow, One with the size of _b1 and just the this button and another with _b2 size and just this button on it....

            What am I missing here?

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mrjj
              Lifetime Qt Champion
              wrote on 12 May 2016, 15:24 last edited by
              #8

              @roseicollis said:
              Hi
              Code is also fine. But normally one use use layout so they can scale to mainwindow size and inserting into the UI directly works great. But letting the page new the widgets is also 100% valid and its mostly a matter of taste. (IMHO)

              _b1 = new QPushButton;

              There is a rule here u dont know. If you dont give a widget a parent it will automatically set window flag on it self and become a window :)
              So _b1 = new QPushButton(this); will make them be inside the page.

              R 1 Reply Last reply 12 May 2016, 15:51
              0
              • M mrjj
                12 May 2016, 15:24

                @roseicollis said:
                Hi
                Code is also fine. But normally one use use layout so they can scale to mainwindow size and inserting into the UI directly works great. But letting the page new the widgets is also 100% valid and its mostly a matter of taste. (IMHO)

                _b1 = new QPushButton;

                There is a rule here u dont know. If you dont give a widget a parent it will automatically set window flag on it self and become a window :)
                So _b1 = new QPushButton(this); will make them be inside the page.

                R Offline
                R Offline
                roseicollis
                wrote on 12 May 2016, 15:51 last edited by roseicollis 5 Dec 2016, 15:51
                #9

                @mrjj said:

                normally one use use layout so they can scale to mainwindow size and inserting into the UI directly works great.

                Ok so you mean I should create the layout in the UI file? And it auto scale to mainwindow or should I do something else?

                If you dont give a widget a parent it will automatically set window flag on it self and become a window :)

                Mmmm interesting... I understand it but if I put (this) for both buttons now its right that I don't have their 2 new windows but I don't see them also in the MainWindow window so thinking about what you said before, I tried adding (this) to QStackedWidget *st = new QStackedWidget; and now I see something in the MainWindow which is _b2 .... any idea why I don't see _b1? And another thing:
                I had to add a st->setMinimumSize(500,500);for my stacket widget... how could i tell him to take the parent's size, in this case MainWindow?

                I'm understanding a lot of the Qt behaviour, thank you so much for your explanations @mrjj

                M 1 Reply Last reply 12 May 2016, 16:01
                0
                • R roseicollis
                  12 May 2016, 15:51

                  @mrjj said:

                  normally one use use layout so they can scale to mainwindow size and inserting into the UI directly works great.

                  Ok so you mean I should create the layout in the UI file? And it auto scale to mainwindow or should I do something else?

                  If you dont give a widget a parent it will automatically set window flag on it self and become a window :)

                  Mmmm interesting... I understand it but if I put (this) for both buttons now its right that I don't have their 2 new windows but I don't see them also in the MainWindow window so thinking about what you said before, I tried adding (this) to QStackedWidget *st = new QStackedWidget; and now I see something in the MainWindow which is _b2 .... any idea why I don't see _b1? And another thing:
                  I had to add a st->setMinimumSize(500,500);for my stacket widget... how could i tell him to take the parent's size, in this case MainWindow?

                  I'm understanding a lot of the Qt behaviour, thank you so much for your explanations @mrjj

                  M Offline
                  M Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on 12 May 2016, 16:01 last edited by mrjj 5 Dec 2016, 16:58
                  #10

                  @roseicollis

                  • Ok so you mean I should create the layout in the UI file? And it auto scale to mainwindow or should I do something else?
                    No i just state the reason why using UI files often works as well as directly code and you
                    dont have to scroll around in all the "creation" code if handled by the UI.
                    --
                    I think ur b2 button is on top of b1
                    try b1->move(100,100)
                    --
                  • setMinimumSize(500,500);for my stacket widget... how could i tell him to take the parent's size, in this case MainWindow?

                  That what we use layouts for normally. It will scale all children to parent.
                  So in mainwin central u add widget , give it layout. then add Stacked to layout.
                  Now stacked follow main. Now u need to use layout in the pages so pages follow stacked that follow main. Sounds complicated but its not.
                  http://doc.qt.io/qt-5/examples-layouts.html

                  Will a sample help?

                  R 1 Reply Last reply 13 May 2016, 11:15
                  0
                  • M mrjj
                    12 May 2016, 16:01

                    @roseicollis

                    • Ok so you mean I should create the layout in the UI file? And it auto scale to mainwindow or should I do something else?
                      No i just state the reason why using UI files often works as well as directly code and you
                      dont have to scroll around in all the "creation" code if handled by the UI.
                      --
                      I think ur b2 button is on top of b1
                      try b1->move(100,100)
                      --
                    • setMinimumSize(500,500);for my stacket widget... how could i tell him to take the parent's size, in this case MainWindow?

                    That what we use layouts for normally. It will scale all children to parent.
                    So in mainwin central u add widget , give it layout. then add Stacked to layout.
                    Now stacked follow main. Now u need to use layout in the pages so pages follow stacked that follow main. Sounds complicated but its not.
                    http://doc.qt.io/qt-5/examples-layouts.html

                    Will a sample help?

                    R Offline
                    R Offline
                    roseicollis
                    wrote on 13 May 2016, 11:15 last edited by
                    #11

                    @mrjj said:

                    I think ur b2 button is on top of b1
                    try b1->move(100,100)

                    Totally right!

                    So in mainwin central u add widget , give it layout. then add Stacked to layout.
                    Now stacked follow main.

                    Isn't the same than what I already have? The difference I see is that you are adding first a widget to the mainwindow but I don't understand why...
                    My mainWindow code actually looks like:

                    MainWindow::MainWindow(QWidget *parent) :
                        QMainWindow(parent),
                        ui(new Ui::MainWindow)
                    {
                        ui->setupUi(this);
                        
                        QStackedWidget *st = new QStackedWidget(this);
                        st->setMinimumSize(800,800);
                    
                        Page1 *page1 = new Page1;
                        st->addWidget(page1);
                    
                        layout = new QVBoxLayout; //defined in .h file
                        layout->addWidget(st);
                        setLayout(layout);
                    }
                    

                    But then when I try to do layout()->addWidget(_b1); on Page1 and try to run the program it crashes at this point....

                    I've tried doing what you said, I think you mean this:

                        QWidget* centralWidget = new QWidget();
                        QVBoxLayout *layout = new QVBoxLayout;
                        layout->addWidget(st);
                        setCentralWidget(centralWidget);
                        centralWidget->setLayout(layout);
                        setFixedSize(600,600);
                    

                    But again the program crashes in Page1 constructor when I put layout()->addWidget(_b1); or parent-> layout()->addWidget(_b1);

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on 13 May 2016, 11:26 last edited by mrjj
                      #12

                      Hi
                      Main windows is a bit special since it has "central widget".
                      which there to allow to define areas around it
                      for Dock windows. That is why we insert widget first.
                      For all types of other widget we would insert directly.

                      QWidget* centralWidget = new QWidget();
                      QVBoxLayout *layout = new QVBoxLayout;
                      centralWidget->setLayout(layout);
                      layout->addWidget(st);
                      setCentralWidget(centralWidget);

                      seems fine.
                      For centralWidget , u can then use the Stacked.


                      My mainWindow code actually looks like:

                      MainWindow::MainWindow(QWidget *parent) :
                      QMainWindow(parent),
                      ui(new Ui::MainWindow)
                      {

                      setLayout(layout);
                      // that sets directly on mainwin. not sure it does what we think.

                      You can just single step and see the values to find out why u crash.
                      Sorry, i cant spot it. Running it helps.
                      I think u need a setCentral also.

                      That is the reason no 2 to why i like
                      UI file so much. no crashing as u can only insert legally when visually :)
                      And no code to try to spot bugs in.

                      I think u need
                      new widget
                      widget as central
                      new layout
                      layout to widget
                      inset stacked to that layout
                      and then the page stuff

                      1 Reply Last reply
                      0

                      12/12

                      13 May 2016, 11:26

                      • Login

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