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. QWIzardPage parent() method returning NULL pointer inside initializePage()
Qt 6.11 is out! See what's new in the release blog

QWIzardPage parent() method returning NULL pointer inside initializePage()

Scheduled Pinned Locked Moved General and Desktop
12 Posts 3 Posters 7.2k Views 1 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.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by
    #1

    So still very new to Qt, but decent programmer (I'd like to think). I'm currently porting some code from a VS solution to Qt and attempting to keep most of the logic. It heavily uses MFC...

    I designed the QWizardPage and its "parent" QWizard class under the designer.

    Inside my initializePage() method I want to get the pointer to my parent, SxtWizard, and do some stuff with a few of it's members. But... the inherited parent() method from QObject only returns a NULL pointer... This is the way its done in the code I'm porting, but I'm completely open to suggestions with doing things differently. Should I even be using parent()!? Just add member that is set to "parent" in the constructor and use it? (think that works btw...)

    Also something to note, the QWizard dialog is shown after a button is clicked on a different dialog (there will be multiple wizards).

    So my QWizardPage class:

    @
    #include "inputinfo.h"
    #include "ui_inputinfo.h"
    #include "sxtwizard.h"

    InputInfo::InputInfo(SxtWizard* parent) : QWizardPage(parent), ui(new Ui::InputInfo),
    maxSpeed(0), minSpeed(0),
    ...
    {
    this->setupUi(this);
    }

    void InputInfo::initializePage()
    {
    SxtWizard wizard = dynamic_cast<SxtWizard>(this->parent()); //this returns a null pointer! :(
    ...do some stuff...
    }
    @
    Now the QWizard class:
    @
    #include "ui_sxtwizard.h"
    #include "inputinfor.h"
    #include "sxtwizard.h"

    SxtWizard::SxtWizard(QWidget *parent) : QWizard(parent), ui(new Ui::SxtWizard)
    , exportData(NULL), ...
    {
    ui->setupUi(this);
    addPage(new InputInfo(this));
    }
    @

    Iv looked at "this ":http://qt-project.org/forums/viewthread/15838 thread for awhile...but to no avail.

    What am I doing wrong!?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      First, you should use qobject_cast since you are casting a derived class of QObject. Then can you check what this->parent() points to before casting ?

      As a side note, it's generally a bad design for a child to have to know the parent to get some information from it, it creates a tight coupling that should be avoided as much a possible to keep a clean and maintainable code.

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #3

        First of all thank you for the replay SGaist!

        Sorry I had tested both dynamic_cast and qobject_cast, both return a null pointer.

        Using the debugger inside the constructor if I traverse this -> ... -> QObject -> ... ->parent: There's an additional value with "Name" as "_vtcast_SxtWizard", "Value" as "class SxtWizard" and "Type" as "SxtWizard".

        Doing the same thing inside of initializePage() method when traversing the same "this" pointer there is no (name. value, type) tuple mentioned in the constructor. Any ideas...?

        Also side question... I think I know the answer but want to confirm. What exactly is the Qt mechanism to having actual data (class members, etc..) linked (not sure on terminology) to widgets? Like having a QString linked to a QTextBrowser, and when the string I changed its reflected/updated inside the widget. Is this accomplished by using the Property System? (using value changed or something...?)

        Thanks again for your help...

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Are you missing the Q_OBJECT macro ?

          Also what does this->parent() (without any casting) return in initializePage ?

          Indeed, Property System + Signals and Slots. You can see this in the examples throughout the documentation

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • ? Offline
            ? Offline
            A Former User
            wrote on last edited by
            #5

            I have the Q_OBJECT macro declared in both header files...that's the only place where its needed right?

            And I can do:
            @
            Qbject test = this->parent(); @

            and get back a valid pointer.

            But...I finally got it! But want to know why...
            @
            SxtWizard* test = qobject_cast<SxtWizard*>(this->parent()->parent()->parent()); @

            returns the correct pointer... I know I'm doing something wrong now...

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              If you print each ancestor you'll find the chain of parenting and it probably contains a layout manager.

              As I said before, the child should not know about it's parent/ancestors. It's the wizard duty to setup the page, not the page to try and discover it's wizard ancestor and take information from it.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • ? Offline
                ? Offline
                A Former User
                wrote on last edited by
                #7

                Yea...its a layout manger... bleh Well at this point I was just curious on what was going on... But I'v changed the logic to have the QWizard sets the pointers and adds the page after.

                Thanks for your help! :D

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  You're welcome !

                  What pointer does your QWizard set ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • ? Offline
                    ? Offline
                    A Former User
                    wrote on last edited by
                    #9

                    There are two pointers to set to separate class instances, each holding a hefty amount of data (strings, floats, other pointers). In the code I am porting they set them in the OnInitDialog() method for a CPropertyPage (MFC), which I guessed would be similar to the initalizePage() method for QWizardPage. But I can change what I see fit thankfully lol..

                    Im still having trouble using properties and signal/slots... I have a QWizardPage and a QTextBrowser. Suppose I have the following header:

                    @
                    class MyClass : public QWizardPage
                    {
                    Q_OBJECT
                    Q_PROPERTY(QString dbName READ getDbName WRITE setDbName)
                    public:
                    QString dbName() const { return m_dbName; )
                    void setDbName(const QString &name)
                    private:
                    QString m_dbName;
                    @

                    Then the setDbName is as follows:
                    @
                    void MyClass::setDbName(const QString &f)
                    {
                    if (f != m_dbName)
                    {
                    m_dbName = f;
                    ui->databaseName->setHtml(m_dbName );
                    }
                    }
                    @

                    databaseName being the QTextBrowsers object name (set in the designer).

                    I have the user clicking a button and opening a QFileDialog, using the return value I want to set m_dbName and thus have it updated in the QTextBrowser....

                    Is this in any way the correct approach for having class members linked to widgets of that class...? Should I be using the NOTIFY along with a signal...? I know I can just call ui->databaseName->setHtml(m_dbName ) in the same method opening the file dialog and have it set... Should I even be trying this?

                    I have other QStrings and widgets I wish to do the same: just set the value of the string (or whatever the variable is).

                    Thanks again man... No one where I work has even touched Qt so having someone to ask a few questions is amazing...

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #10

                      If you need the wizard, wouldn't it be a good idea to use the QWizardPage::wizard method instead? It directly returns a QWizard*; no casting needed.

                      Note that if you want to communicate values between the wizard and its pages or between pages, you can use the fields mechanism too.

                      1 Reply Last reply
                      0
                      • ? Offline
                        ? Offline
                        A Former User
                        wrote on last edited by
                        #11

                        Yea but I need a pointer to the actual class. I'm trying to reuse as much code as possible... and they create pointers to class instances, pass them around, and set members of these instances throughout the wizard. Like 250+ members across a 2 classes. I guess I could just make the pointers fields but meh...it's already working.

                        Any input on the Q_PROPERY question I had...? :D

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          Generally, if you have a property you want to propagate you use NOTIFY to make the signal name known to the property system (it also ensure that you don't forget to add the signal to your object).

                          Then the classic applies:
                          @
                          void setMyProperty(const QString &propertyValue)
                          {
                          if (m_propertyValue != propertyValue) {
                          m_propertyValue = propertyValue;
                          emit propertyValueChanged(m_propertyValue)
                          }
                          }
                          @

                          Now if you use e.g. a QLineEdit (either in a ui file or directly in code) you don't need to store yourself the string since it's already done by the QLineEdit.

                          You can then simplify your code:
                          @
                          MyCoolClass::MyCoolClass(QWidget *parent):
                          QWidget(parent)
                          {
                          // ui setup et everything else
                          connect(ui->myLineEdit, SIGNAL(textChanged(QString)), SIGNAL(myPropertyChanged(QString)));
                          }
                          void setMyProperty(const QString &propertyValue)
                          {
                          ui->myLineEdit->setText(propertyValue)
                          }
                          @

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          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