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. How to change QWizard default buttons in each QWizardPage
QtWS25 Last Chance

How to change QWizard default buttons in each QWizardPage

Scheduled Pinned Locked Moved Solved General and Desktop
qt4.8.5qwizardqwizardpagebutton custom s
16 Posts 3 Posters 8.7k 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.
  • jsulmJ Offline
    jsulmJ Offline
    jsulm
    Lifetime Qt Champion
    wrote on last edited by
    #5

    Can you post the stack trace?

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

    R 1 Reply Last reply
    0
    • R roseicollis

      @jsulm O.o ermmmm... wow! yes, I used that function on the constructor the first time I create the buttons_layout but forgot it there in the function .... what a Stupid mistake... BUT now, putting it like you said it makes my program crashes.

          QList<QWizard::WizardButton> button_layout;
          button_layout.clear();
          qDebug() << " 1";
          button_layout <<QWizard::Stretch << QWizard::CustomButton1 << QWizard::CustomButton2 << QWizard::NextButton << QWizard::FinishButton;
          qDebug() << " 2 ";
          setButtonLayout(button_layout);
          qDebug() << " 3";
      

      If I run it with that code it prints 1 2 and then crashes in the setButtonLayout() function with a nice The program has unexpectedly finished.

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #6

      @roseicollis

      BaseWizard *bz;
      bz->ChangeButtons();
      

      Is this exactly how you use your wizard? If that's the case bz is just a wild pointer and doesn't actually reference any object.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      1
      • jsulmJ jsulm

        Can you post the stack trace?

        R Offline
        R Offline
        roseicollis
        wrote on last edited by
        #7

        @jsulm said:

        stack trace?

        How can I get it?

        @kshegunov Well I put the funcion on my BaseWizard and was trying to call it from a QWizardPage like that thinking it was correct... how should I do it instead?

        kshegunovK 1 Reply Last reply
        0
        • jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #8

          You should get it if you execute your app from QtCreator and it crashes.

          You did not initialize the pointer, so it is showing to nirvana:

          BaseWizard *bz;
          bz->ChangeButtons();
          

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

          R 1 Reply Last reply
          0
          • R roseicollis

            @jsulm said:

            stack trace?

            How can I get it?

            @kshegunov Well I put the funcion on my BaseWizard and was trying to call it from a QWizardPage like that thinking it was correct... how should I do it instead?

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by kshegunov
            #9

            @roseicollis
            Well, you have to operate on an object. If the way shown is the exact excerpt of the code you'll always get a segmentation fault, because in ChangeButtons() you dereference this by calling setButtonLayout(). You can use instead:

            BaseWizard * bz = dynamic_cast<BaseWizard *>(wizard());
            

            or any other way that actually provides you with the valid wizard object.

            Kind regards.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • jsulmJ jsulm

              You should get it if you execute your app from QtCreator and it crashes.

              You did not initialize the pointer, so it is showing to nirvana:

              BaseWizard *bz;
              bz->ChangeButtons();
              
              R Offline
              R Offline
              roseicollis
              wrote on last edited by
              #10

              @jsulm Well in the Compile output it says that exit normally (if that is what you mean, if not, can you point me where can I find or see the stack trace?

              @kshegunov said:

              BaseWizard * bz = dynamic_cast<BaseWizard *>(wizard());

              Annd.... DING DING DING! We have a winner here! Yes, this absollutely solves my problem. Thank you so much! I love a little with all that about casts... why can't you just do something like BaseWizard *bz = new BaseWizard() ? why do you have to use a cast and moreover, dynamic_cast ?

              kshegunovK 1 Reply Last reply
              0
              • R roseicollis

                @jsulm Well in the Compile output it says that exit normally (if that is what you mean, if not, can you point me where can I find or see the stack trace?

                @kshegunov said:

                BaseWizard * bz = dynamic_cast<BaseWizard *>(wizard());

                Annd.... DING DING DING! We have a winner here! Yes, this absollutely solves my problem. Thank you so much! I love a little with all that about casts... why can't you just do something like BaseWizard *bz = new BaseWizard() ? why do you have to use a cast and moreover, dynamic_cast ?

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by kshegunov
                #11

                @roseicollis
                Firstly you'll need the wizard your page belongs to, this is the one you're trying to modify, that's why I suggested using the wizard() method. But that method (naturally) gives you a pointer to the base class (QWizard). Because you're trying to typecast a pointer down in the hierarchy and not up (which is always safe) your best bet is to do that with dynamic_cast. This ensures that if the object you receive is not from that hierarchy branch, or you pass a NULL pointer as argument, or your object can't be cast downwards (meaning that it actually is a base class object), the cast will return NULL. This provides you with a safe way to cast object pointers. The most clean approach is to use qobject_cast which works pretty much the same way, but for that you need your class to be declared as a metatype to Qt, which I was not sure you had done.

                Kind regards.

                Read and abide by the Qt Code of Conduct

                R 1 Reply Last reply
                0
                • kshegunovK kshegunov

                  @roseicollis
                  Firstly you'll need the wizard your page belongs to, this is the one you're trying to modify, that's why I suggested using the wizard() method. But that method (naturally) gives you a pointer to the base class (QWizard). Because you're trying to typecast a pointer down in the hierarchy and not up (which is always safe) your best bet is to do that with dynamic_cast. This ensures that if the object you receive is not from that hierarchy branch, or you pass a NULL pointer as argument, or your object can't be cast downwards (meaning that it actually is a base class object), the cast will return NULL. This provides you with a safe way to cast object pointers. The most clean approach is to use qobject_cast which works pretty much the same way, but for that you need your class to be declared as a metatype to Qt, which I was not sure you had done.

                  Kind regards.

                  R Offline
                  R Offline
                  roseicollis
                  wrote on last edited by roseicollis
                  #12

                  @kshegunov

                  but for that you need your class to be declared as a metatype to Qt, which I was not sure you had done.

                  Neither do I :PWhat do you mean with metatype and how do you declare it? I just use to code making it works and if it does not, then I search on the internet and try to learn what it does but all that you mentioned its far away from my knowlegde...but I want to learn it all so that's why I ask it :) Thank you so much!

                  One more thing: I have my BaseWizard class like that:

                    #include "WPn"// include of all the wizardpages I have   (in the .cpp)
                    class BaseWizard : public QWizard
                  

                  And the BasePAge like this:

                     #include "basewizard.h" //(in the .cpp)
                     class BasePage : public QWizardPage
                  

                  And every QWizardPage like this:

                    #include "basewizard.h" // in .cpp
                    #include "basepage.h"   // in .cpp
                    class WP1 : public BasePage
                  

                  So now I'm trying to call in basewizard's constructor a function from basepage, but still have the same problem and don't know how to do it really, I've tried with something like:

                        BasePage *bp = dynamic_cast<BasePage *>( new QWizardPage()); // really not sure how to writte it sorry)
                        bp->SetSubTitleStyle();
                  

                  I know that as basewizard is not including basepage it is not possible (and I can't include it because its BaseWizard the one included on BasePage. So...How could I do that?

                  I need that because when you use setStyleSheet() on QT, it keeps the last one, it doesn't merge them or something like that so I have a general css for labels set in BaseWizard and I want one label (common in all wp) to have another style. I've also tried putting the Wizard style on basepage instead of basewizard but then the program crashes.. I do it putting that in the constructor of basepage:

                  BaseWizard * bz = dynamic_cast<BaseWizard *>(wizard());
                  bz->setStyleSheet("QWizard{background-color: black);}"
                                    "QComboBox:focus, QLineEdit:focus{ background-color: #dddddd; }"
                                    "QPushButton{ font-weight: bold; }"
                                    "QPushButton:focus{background-color: #8888a8); color:orange;}"
                                    "QLabel{font-weight: bold;color:orange}");
                  
                      SetSubTitleStyle(); //function that chagnes the common label css
                  
                  kshegunovK 1 Reply Last reply
                  0
                  • R roseicollis

                    @kshegunov

                    but for that you need your class to be declared as a metatype to Qt, which I was not sure you had done.

                    Neither do I :PWhat do you mean with metatype and how do you declare it? I just use to code making it works and if it does not, then I search on the internet and try to learn what it does but all that you mentioned its far away from my knowlegde...but I want to learn it all so that's why I ask it :) Thank you so much!

                    One more thing: I have my BaseWizard class like that:

                      #include "WPn"// include of all the wizardpages I have   (in the .cpp)
                      class BaseWizard : public QWizard
                    

                    And the BasePAge like this:

                       #include "basewizard.h" //(in the .cpp)
                       class BasePage : public QWizardPage
                    

                    And every QWizardPage like this:

                      #include "basewizard.h" // in .cpp
                      #include "basepage.h"   // in .cpp
                      class WP1 : public BasePage
                    

                    So now I'm trying to call in basewizard's constructor a function from basepage, but still have the same problem and don't know how to do it really, I've tried with something like:

                          BasePage *bp = dynamic_cast<BasePage *>( new QWizardPage()); // really not sure how to writte it sorry)
                          bp->SetSubTitleStyle();
                    

                    I know that as basewizard is not including basepage it is not possible (and I can't include it because its BaseWizard the one included on BasePage. So...How could I do that?

                    I need that because when you use setStyleSheet() on QT, it keeps the last one, it doesn't merge them or something like that so I have a general css for labels set in BaseWizard and I want one label (common in all wp) to have another style. I've also tried putting the Wizard style on basepage instead of basewizard but then the program crashes.. I do it putting that in the constructor of basepage:

                    BaseWizard * bz = dynamic_cast<BaseWizard *>(wizard());
                    bz->setStyleSheet("QWizard{background-color: black);}"
                                      "QComboBox:focus, QLineEdit:focus{ background-color: #dddddd; }"
                                      "QPushButton{ font-weight: bold; }"
                                      "QPushButton:focus{background-color: #8888a8); color:orange;}"
                                      "QLabel{font-weight: bold;color:orange}");
                    
                        SetSubTitleStyle(); //function that chagnes the common label css
                    
                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #13

                    @roseicollis said:

                    What do you mean with metatype and how do you declare it?

                    A meta-type is a class/type that is known to Qt's meta-object system. You're required to declare your class as a meta-type when you intent to use Qt's template functions that depend on it (these include QVariant's conversions and qobject_cast). You also need to register your class at runtime as a meta-type if it will be used as an argument for queued signal-slot connections, which is relevant to multithreaded applications.

                    On your other question:

                        BasePage *bp = dynamic_cast<BasePage *>( new QWizardPage()); // really not sure how to writte it sorry)
                        bp->SetSubTitleStyle();
                    

                    This is a bad idea, because of two things:

                    1. Your wizard is managing your pages, but should not be required to know anything about how the pages are built or styled. This is a responsibility of your page, not your wizard.
                    2. The code is simply wrong, from C++ point of view. You create an object of type QWizardPage, then you try to cast the pointer returned to a derived class pointer, which will always cause dynamic_cast to return NULL (simply because QWizardPage is not a BasePage). So at the end of the day, when you call your function, you'll just get a segmentation fault because bp is NULL.

                    Suppose you have the following hierarchy:

                    class A { };
                    class B : public A  {};
                    class C : public A  {};
                    class D : public B  {};
                    

                    This means B is A, C is A, D is B (but because B is A, D is A as well). What you're trying to tell the compiler with your code is: "I have an object of type A and want to treat it (the dynamic_cast) as an object of type B", but you see, this is not correct, because while B is A, A is not B, so the dynamic_cast will always return NULL (meaning it can't provide a meaningful conversion). Now suppose you have objects created like this:

                    A * a = new A;   // This is okay, our pointer references object of the same type
                    A * b = new B;   // This is okay as well, our pointer references an object of type B (but threats it as an object of type A). It's possible because B extends A.
                    B * bb = new A; // Error! The object is of type A, and cannot be meaningfully accessed like it was of type B. B does not extend A, it's the other way around!
                    

                    So...How could I do that?

                    You could set your style for the page in the page's constructor (not in the wizard's constructor).

                    I hope this helps.
                    Kind regards.

                    Read and abide by the Qt Code of Conduct

                    R 1 Reply Last reply
                    1
                    • kshegunovK kshegunov

                      @roseicollis said:

                      What do you mean with metatype and how do you declare it?

                      A meta-type is a class/type that is known to Qt's meta-object system. You're required to declare your class as a meta-type when you intent to use Qt's template functions that depend on it (these include QVariant's conversions and qobject_cast). You also need to register your class at runtime as a meta-type if it will be used as an argument for queued signal-slot connections, which is relevant to multithreaded applications.

                      On your other question:

                          BasePage *bp = dynamic_cast<BasePage *>( new QWizardPage()); // really not sure how to writte it sorry)
                          bp->SetSubTitleStyle();
                      

                      This is a bad idea, because of two things:

                      1. Your wizard is managing your pages, but should not be required to know anything about how the pages are built or styled. This is a responsibility of your page, not your wizard.
                      2. The code is simply wrong, from C++ point of view. You create an object of type QWizardPage, then you try to cast the pointer returned to a derived class pointer, which will always cause dynamic_cast to return NULL (simply because QWizardPage is not a BasePage). So at the end of the day, when you call your function, you'll just get a segmentation fault because bp is NULL.

                      Suppose you have the following hierarchy:

                      class A { };
                      class B : public A  {};
                      class C : public A  {};
                      class D : public B  {};
                      

                      This means B is A, C is A, D is B (but because B is A, D is A as well). What you're trying to tell the compiler with your code is: "I have an object of type A and want to treat it (the dynamic_cast) as an object of type B", but you see, this is not correct, because while B is A, A is not B, so the dynamic_cast will always return NULL (meaning it can't provide a meaningful conversion). Now suppose you have objects created like this:

                      A * a = new A;   // This is okay, our pointer references object of the same type
                      A * b = new B;   // This is okay as well, our pointer references an object of type B (but threats it as an object of type A). It's possible because B extends A.
                      B * bb = new A; // Error! The object is of type A, and cannot be meaningfully accessed like it was of type B. B does not extend A, it's the other way around!
                      

                      So...How could I do that?

                      You could set your style for the page in the page's constructor (not in the wizard's constructor).

                      I hope this helps.
                      Kind regards.

                      R Offline
                      R Offline
                      roseicollis
                      wrote on last edited by
                      #14

                      @kshegunov Ohhh I see it now, I understand it so much better. Thank you for the explanation and the examples, they helped me a lot as they are easy to understand for me :). I know I can do it in every WP constructor but I wanted to avoid it as it mean I will have this line in every of my 50 wizardpages so that's why I was trying to set it in another way but seeing it is totally 'ilegal' then I'll do it this way.

                      Really greatfull for your reply! :D

                      kshegunovK 1 Reply Last reply
                      0
                      • R roseicollis

                        @kshegunov Ohhh I see it now, I understand it so much better. Thank you for the explanation and the examples, they helped me a lot as they are easy to understand for me :). I know I can do it in every WP constructor but I wanted to avoid it as it mean I will have this line in every of my 50 wizardpages so that's why I was trying to set it in another way but seeing it is totally 'ilegal' then I'll do it this way.

                        Really greatfull for your reply! :D

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #15

                        @roseicollis
                        You're welcome.

                        I know I can do it in every WP constructor but I wanted to avoid it as it mean I will have this line in every of my 50 wizardpages so that's why I was trying to set it in another way but seeing it is totally 'ilegal' then I'll do it this way.

                        Well this is exactly why you have a BasePage class, isn't it? You put all the common functionality inside your base class (this would be your BasePage constructor) and when a wizard page is supposed to do something different you derive from your BasePage a new type that will provide you with the new behavior. My point is that your Wizard should not know about how the page is built or styled, but all the pages are of type BasePage, and BasePage does and should handle all the common things related to the wizard pages, while the wizard itself just collects and displays the pages.

                        Kind regards.

                        Read and abide by the Qt Code of Conduct

                        R 1 Reply Last reply
                        0
                        • kshegunovK kshegunov

                          @roseicollis
                          You're welcome.

                          I know I can do it in every WP constructor but I wanted to avoid it as it mean I will have this line in every of my 50 wizardpages so that's why I was trying to set it in another way but seeing it is totally 'ilegal' then I'll do it this way.

                          Well this is exactly why you have a BasePage class, isn't it? You put all the common functionality inside your base class (this would be your BasePage constructor) and when a wizard page is supposed to do something different you derive from your BasePage a new type that will provide you with the new behavior. My point is that your Wizard should not know about how the page is built or styled, but all the pages are of type BasePage, and BasePage does and should handle all the common things related to the wizard pages, while the wizard itself just collects and displays the pages.

                          Kind regards.

                          R Offline
                          R Offline
                          roseicollis
                          wrote on last edited by
                          #16

                          @kshegunov Yes yes I understand you and that was what I was trying to achieve but dunno why it didn't work fine. finally it works correctly without having to call it every time in every constructor of every wizardpage. The label that was not ok with the stylesheet had a QPalette with the colour and then some css with setStyleSheet() so seems that both are incompatibles and doing that the setStyleSheet() function was ignored. I've removed the QPalette and now it works perfect.

                          Thanks for everything!

                          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