PDA

View Full Version : How can I registed field in QWizard, which designed in QtCreator?



syjgin
4th September 2009, 20:10
I`m create QWizard and add several pages to it with QtCreator(built-in Qt Designer). I want to make some fields to be mandatory in constructor of QWizard, like this:
this->page(0)->registerField("name*",m_ui->lname); but this method of QWizardPage is protected. I can`t find constructor of QWizardPages, which has been added to .ui file in graphical mode

markusthalberg
10th October 2011, 14:58
Hi,

I see that this question is not answered and I have the exact same problem. In the QT Designer's created code, all of the widgets like QLineEdit are created in the setupUi function of the QWizard class and their parents are set to the related QWizardPage. I promoted all of the wizard pages in my wizard and if I try to use "registerField" in the constructor of my class inherited from the QWizardPage, I get "Segmentation fault" in run-time. I assume that's because registerField refers to QLineEdit widgets, which are not yet assigned to this wizard page, since they are created in the wizard's scope!

However, if I try to use registerField in the Wizard's constructor, this time I cannot access the protected method of QWizardPage.

I think, there must be a right way to do this and I am missing something. Otherwise, it would be pointless to use the QT Designer.


The generated code:
ui_Wizard.h


...
class Ui_Wizard
{
public:
PageSP *wizardPage_SP;
QLineEdit *lineEdit_SP;
QLabel *label_SP;
QLabel *label_SPInfo;
QFrame *frame_banner;
QLabel *label_logo;
QLabel *label_SP_W;
QLabel *label_req_1;

...

void setupUi (QWizard *Wizard)
{
...
wizardPage_SP = new PageSP();
wizardPage_SP->setObjectName(QString::fromUtf8("wizardPage_SP"));
wizardPage_SP->setFocusPolicy(Qt::TabFocus);
lineEdit_SP = new QLineEdit(wizardPage_SP);
lineEdit_SP->setObjectName(QString::fromUtf8("lineEdit_SP"));
lineEdit_SP->setGeometry(QRect(180, 100, 183, 20));
label_SP = new QLabel(wizardPage_SP);
label_SP->setObjectName(QString::fromUtf8("label_SP"));
label_SP->setGeometry(QRect(180, 80, 183, 16));
....

}
}


Segmentation Fault Case
My own class using the this Ui_Wizard class:
configwizard.cpp


...
PageSP::PageSP(QWidget *parent)
: QWizardPage(parent)
{
registerField("f_SP*",this->findChild<QLineEdit *>("lineEdit_SP"),"plainText", SIGNAL(textChanged()));
}


Protected method case
configwizard.cpp


ConfigWizard::ConfigWizard(QWizard *parent)
{
setupUi(this);

this->wizardPage_SP->registerField("f_SP*",this->lineEdit_SP);
}

wysota
10th October 2011, 16:52
Have your page classes contain a public method "registerFields" (or name it whatever you want) which they use to register their fields (by calling registerField) and call that method for each page after the constructor of the wizard (or at least after its setupUi() call).

ChrisW67
11th October 2011, 00:47
I promoted all of the wizard pages in my wizard and if I try to use "registerField" in the constructor of my class inherited from the QWizardPage,

This works just fine for me.


I get "Segmentation fault" in run-time. I assume that's because registerField refers to QLineEdit widgets,

Yes, the pointers you use must be valid when you use them. If you have used Designer to construct your QWizardPage then don't try register fields until after the generated setupUi() call in the constructor. You also don't need to use findChild(), just access the widget through the ui member/pointer. For example (from one of mine):


RegoWizardPageIntro::RegoWizardPageIntro(QWidget *parent) :
QWizardPage(parent),
ui(new Ui::RegoWizardPageIntro)
{
ui->setupUi(this);
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/wizard/rego_watermark.png"));
...

// Register some of the radio buttons as fields
registerField("action.activate", ui->registerRadioButton);
registerField("action.deactivate", ui->unregisterRadioButton);
...
}



which are not yet assigned to this wizard page, since they are created in the wizard's scope!

Not sure what you mean by this? If you are creating widgets in the QWizard's constructor and injecting them into a QWizardPage's layout dynamically then you should reconsider your design.

markusthalberg
11th October 2011, 15:13
Not sure what you mean by this? If you are creating widgets in the QWizard's constructor and injecting them into a QWizardPage's layout dynamically then you should reconsider your design.
Actually, this is exactly my problem with the Designer's generated code. It creates the widgets of the WizardPage in Wizard's setupUi, after creating the WizardPage like in the "ui_Wizard.h" code above. If it were to me, I would have done it as you suggested. However, wysota's suggestion of defining a new public method in WizardPage worked for me.

wysota
11th October 2011, 15:24
But you are still injecting widgets that belong to some other widget into the pages.

ChrisW67
13th October 2011, 00:14
Actually, this is exactly my problem with the Designer's generated code. It creates the widgets of the WizardPage in Wizard's setupUi, after creating the WizardPage like in the "ui_Wizard.h" code above.
If you use Designer to build the entire QWizard, including the pages then that is what you get. This approach keeps your source file count down but makes almost everything else awkward by hiding the widgets on the pages from easy access.

If you use Designer to generate a set of wizard pages then the code to place the widgets on those pages is in the correct place and you can register fields in each page's constructor. Then create a QWizard, add your wizard pages (using Designer promotion) and all is well. That's how I did it in the example I posted.

If you have inherited the awkward QWizard setup and cannot change it then what you have done will work.