Sharing data between QWizardPage(s)
-
I know that using registerField is the popular means of sharing data between QWizardPage. The only types of Widget on my pages are labels and I don't need to share them. They display in the context of the code that executes on the respective page.
What I need is to share objects defined in pages that may need visibility on other pages but aren't tied to a widget. Can registerField by used along with creating Q_PROPERTY read/write properties?
-
Hi,
I would say no since registerField needs a QWidget. What you could do however is have these objects part of the QWizard, use signals and slots to update their values from the pages and set them before showing the page.
Hope it helps
-
[quote author="SGaist" date="1399061474"]Hi,
I would say no since registerField needs a QWidget. What you could do however is have these objects part of the QWizard, use signals and slots to update their values from the pages and set them before showing the page.
Hope it helps[/quote]
Hi,
I'm not sure I understand your approach. Each object is tied to the code that acts upon it in its respective page. The tasks in page one are completely different from page two. If anything is taken from your suggestion it may be emitting a signal from page one and having a slot receive it in page two if that is possible. QWizard doesn't have much of a roll here except updating a progress bar that exists on two of the four pages.
-
Yes, you can use your own properties and use them with register. You can register the WizardPage instance itself as the widget, and use your own properties (READ/WRITE/NOTIFY). Works like a charm.
-
[quote author="Andre" date="1399378884"]Yes, you can use your own properties and use them with register. You can register the WizardPage instance itself as the widget, and use your own properties (READ/WRITE/NOTIFY). Works like a charm.[/quote]
I'll try this and update post as needed.
Thanks for the clarification
-
[quote author="Andre" date="1399378884"]Yes, you can use your own properties and use them with register. You can register the WizardPage instance itself as the widget, and use your own properties (READ/WRITE/NOTIFY). Works like a charm.[/quote]
Ok,
I had difficulty setting this up as you described.
I have an integer type variable defined in page one that I need to be available to page two and further on. The error reads: cannot convert parameter 2 from 'int' to 'QWidget' The public varaible is named Filter, it is an int and the call in the QWizardPage::registerField is:
@registerField("FilterType", this->FilterRead);@
Can you post a example of what you used to accomplish this?
thanks
-
Did you actually look at the "syntax":http://qt-project.org/doc/qt-4.8/qwizardpage.html#registerField for this command?
-
Yes, but it appears that it is only used in the context of GUI widget controls and indicators. I am seeking to assign an integer on a QWizardPage to be used as a field. This integer variable is NOT associated with any UI widgets.
I hope you see what I mean
-
[quote author="Andre" date="1402941987"]Did you actually look at the "syntax":http://qt-project.org/doc/qt-4.8/qwizardpage.html#registerField for this command?[/quote]
Thinking there was something I may have missed, I looked at the docs again. There isn't anything that addresses what I am looking to do with non-GUI widgets as fields to register
-
You are trying to do this:
@
registerField("FilterType", this->FilterRead);
@How does that match with the syntax given at the link I gave you, which is:
@
void QWizardPage::registerField ( const QString & name, QWidget * widget, const char * property = 0, const char * changedSignal = 0 )
@You will need to use something like this:
@
registerField("FilterType", this, "theFilterProperty", SIGNAL(theFilterChangedSignal);
@You will need to expose your variable through a Q_PROPERTY of course. In Qt 4, that requires a bit of boilerplate code, in Qt 5 its a oneliner.
Your FilterRead variable is not the same type as QWidget*, is it?
-
[quote author="Andre" date="1402989925"]You are trying to do this:
@
registerField("FilterType", this->FilterRead);
@How does that match with the syntax given at the link I gave you, which is:
@
void QWizardPage::registerField ( const QString & name, QWidget * widget, const char * property = 0, const char * changedSignal = 0 )
@[/quote]
It doesn't; that's the issue. I'm trying to create a registered field from a non-QWidget using (for now) Qt 5.1.1.
[quote]
You will need to use something like this:
@
registerField("FilterType", this, "theFilterProperty", SIGNAL(theFilterChangedSignal);
@[/quote]
I'm starting with the code below:
@Q_PROPERTY(int Filter_Type READ Filter_Type WRITE setFilterType NOTIFY FilterTypeChanged)public:
int Filter_Type() const;signals:
void FilterTypeChanged(int);public slots:
void setFilterType(int Filter_Type);
@Then in a public method, defined in the QWizardPage, that is called by QWizard:
@
void PageOne::registerFields()
{
registerField("filter", this, "setFilterType", "FilterTypeChanged");
}
@[quote]
You will need to expose your variable through a Q_PROPERTY of course. In Qt 4, that requires a bit of boilerplate code, in Qt 5 its a oneliner.Your FilterRead variable is not the same type as QWidget*, is it? [/quote]
Please look and comment if I captured the idea. I don't know if I need to use the MEMBER keyword. My example above doesn't reflect that.
Thanks again Andre
-
You're on the right track. You could indeed use the MEMBER variant with Qt 5 for the property declaration (saving you the boiler plate code of the getter and the setter), but you'll still need the signal.
The signal as you pass it to your registerField call is wrong. Please look at my example again, and compare with how you reference signals in a normal signal-slot connection.
-
[quote author="Andre" date="1403004823"]You're on the right track. You could indeed use the MEMBER variant with Qt 5 for the property declaration (saving you the boiler plate code of the getter and the setter), but you'll still need the signal.
The signal as you pass it to your registerField call is wrong. Please look at my example again, and compare with how you reference signals in a normal signal-slot connection.[/quote]
The syntax used by your example didn't show in the docs which is why I didn't use the SIGNAL keyword. With that, do I have to "connect" the signal and slot in the page's constructor? The slot doesn't appear to be called - even if explicitly emitting the signal - with the modified registerField call below:
@registerField("filter", this, "setFilterType", SIGNAL(FilterTypeChanged));@ -
No, the signal is used internally by the wizard's field mechanism to work with the obligatory fields feature. To update availability based on that, a signal must be known. If you don't need that, you probably can leave out the signal completely.
There are two small mistakes left:
the signal should have a set of parenthesis with the arguments just like you use in the connect method
you now seem to reference the setter slot. Don't. Just use the property name as shown in the example.
@
registerField("filter", this, "Filter_Type", SIGNAL(FilterTypeChanged(int)));
@ -
Thanks,
Still not working. As mentioned earlier. I call a public method from the ctor of the QWizard which is below:
@
void PageOne::registerFields()
{
registerField("filter", this, "Filter_Type", SIGNAL(FilterTypeChanged(int)));
}
@The READ property is below:
@
int PageOne::Filter_Type() const
{
return m_filter_type;
}
@and of course the setter:
@
void PageOne::setFilterType(int FilterType)
{
m_filter_type = FilterType;
}
@How then does FilterType get set? I made an explicit call to the setter in my PageOne::Loaded method:
@
void PageOne::PageLoaded()
{
ui->lblSearching->setText("Page is loaded.");
....
....
....ui->lblSearching->setText("Filter Read"); setFilterType(FilterRead);
}
@That may not be the best use of this technique though.
-
How should we know how the FilterType gets set? That's something application specific and hence your responsibility. I assumed you had control over that from the start, when you said
[quote]What I need is to share objects defined in pages that may need visibility on other pages but aren’t tied to a widget.[/quote]
The setter should also emit the signal if the set value is different from the current value, of course.
The idea of doing this was to use QWizards fields feature to share data between wizard pages (and the wizard itself) that was not bound to widgets on those pages. It doesn't magically set these values.
-
That's all true if not using Q_PROPERTY. It is not something that one would use outside of creating custom Widgets and/or plug-ins. This is why I placed the setter call in the registerField call so that the setter would apply the changed value. Since you wrote that is incorrect, I then wasn't sure how to apply the changed value of what I wanted to export as a field.
-
Why? Using the Q_PROPERTY is only a trick in order to be able to use the fields feature of QWizard. That's the only reason to introduce it.
And I use Q_PROPERTY way more often than when creating custom widgets or plugins. It has many useful uses.
-
I'm not going to dispute this. You obviously have more of a handle on this than I do. I'm just attempting to explain why I did what I posted. I want to use as much "tricks" as I can to get Qt to do what I want.
I was also stating that I searched for using fields for wizards and it is dominated by the requirement of QWidget - especially with the first response to my question.
Your use of Q_PROPERTY as well as your posts related to QThread are very much appreciated.