QWIzardPage parent() method returning NULL pointer inside initializePage()
-
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...
-
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
-
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...
-
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.
-
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
-
You're welcome !
What pointer does your QWizard set ?
-
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...
-
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.
-
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
-
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)
}
@