Subclassing QWizardPage
-
Hello,
I have not seen any examples that illustrate use of custom classes to override methods in QWizardPage class. All wizard examples I've seen are written outside of the designer. For instance, in Qt Creator I create a Wizard with two pages. All the widgets are contained in the ui file and I need access to each of the page's widgets as well as the methods i.e. initializePage(), nextId() etc. in both pages. The new project creation wizard creates an application with one class and the ui file. How do I override the two mentioned methods? In the header file created by the project wizard in Qt Creator, I have the following default header file:
@
#ifndef FLASHWIZARD_H
#define FLASHWIZARD_H#include <QWizard>
#include <QtCore>
#include "Interface.h"namespace Ui
{
class FlashWizard;
class IntroPage;}
class FlashWizard : public QWizard
{
Q_OBJECTpublic:
explicit FlashWizard(QWidget *parent = 0);
virtual ~FlashWizard();private:
Ui::FlashWizard* ui;
PInterface scanner;
QString SupportFile;
QString iniFile;
QSettings* settings;
ushort Language_Id;
bool convertedOK;};
class IntroPage : public QWizardPage
{
Q_OBJECTpublic:
IntroPage(QWidget *parent = 0); void initializePage();
// int nextId() const;
// void setVisible(bool visible);};
class ProgramPage : public QWizardPage
{
Q_OBJECTpublic:
ProgramPage(QWidget *parent = 0);void initializePage();
};
#endif // FLASHWIZARD_H
@
I try and implement the method initializePage() as:
@
void IntroPage::initializePage()
{
setSubTitle(tr("Blah-Bah"));
}
@That code is never executed. I can only access widgets from the main class - FlashWizard and get/set properties from the ui object, created in the main class. I am required to create UI objects in the designer and access them in code as per projects requirements. I am stuck as how to do that.
I hope that is clear, Thanks in advance
-
Nobody care to offer a solution? This is not a typical scenario (at least to my extent of familiarity with Qt)
-
You have to override this methods like always, I mean using the C++ way, but keep in mind that when working with Qt Designer and wants to reimplement an object/widget (QWizardPage in this case) you have to use the Qt Designer option "Promote to..." (located at right click over the object), this option will promote your class (ProgramPage) to be used by the Qt Designer instead the default. For more info take a look to this doc which have a detailed guide: "Using Custom Widgets with Qt Designer":http://qt-project.org/doc/qt-4.8/designer-using-custom-widgets.html. About the widgets, so far as I know they are only accessible from QWizard (FlashWizard), but this doesn't have to be a problem, you can solve it using Signals and Slots.
-
OK that doesn't work. I right clicked on the page in the object inspector in Qt Designer. I slected Promote to, enter the name ProgramPage and selected the header file that contains the class def for ProgramPage.
@
#ifndef FLASHWIZARD_H
#define FLASHWIZARD_H#include <QWizard>
#include <QtCore>
#include "Interface.h"namespace Ui
{
class FlashWizard;
class IntroPage;}
class FlashWizard : public QWizard
{
Q_OBJECTpublic:
explicit FlashWizard(QWidget *parent = 0);
virtual ~FlashWizard();private:
Ui::FlashWizard* ui;
PInterface scanner;
QString SupportFile;
QString iniFile;
QSettings* settings;
ushort Language_Id;
bool convertedOK;};
class IntroPage : public QWizardPage, public QWizard
{
Q_OBJECTpublic:
IntroPage(QWidget *parent = 0); void initializePage();
};
class ProgramPage : public QWizardPage
{
Q_OBJECTpublic:
ProgramPage(QWidget *parent = 0);void initializePage();
};
#endif // FLASHWIZARD_H
@
I compiled and get errrors:
flashwizard.obj:-1: error: LNK2019: unresolved external symbol "public: __thiscall ProgramPage::ProgramPage(class QWidget *)" (??0ProgramPage@@QAE@PAVQWidget@@@Z) referenced in function "public: void __thiscall Ui_FlashWizard::setupUi(class QWizard *)" (?setupUi@Ui_FlashWizard@@QAEXPAVQWizard@@@Z)
debug\FlashWizard.exe:-1: error: LNK1120: 1 unresolved externals
It appears that the linker is looking in Ui::FlashWizard. How can one do UI design in a .ui file and have the code behind and and inherited classes in seperate code files?
So frustrating. Please help.
-
I've used QWizard just once and after using the option "Promote to..." everything worked like a charm, so I didn't have to face these problems. Looking at your code the main diference between what your are doing and what I've done are the following:
1 - For each QWizardPage, I've created a header file (.h) and a implementation file (.cpp).
2 - I haven't used multiple inheritance....right now nothing else come to my mind, just keep debugging your code.
-
So one pair of class files per wizard page then? Fair enough. I'll give it a shot.
Thanks.
-
Original header:
@
#ifndef FLASHWIZARD_H
#define FLASHWIZARD_H#include <QWizard>
#include <QtCore>namespace Ui
{
class FlashWizard;
class IntroPage;
class ProgramPage;}
class FlashWizard : public QWizard
{
Q_OBJECTpublic:
explicit FlashWizard(QWidget *parent = 0);
virtual ~FlashWizard();private slots:
private:
Ui::FlashWizard* ui;
QString SupportFile;
QString iniFile;
QSettings* settings;
ushort Language_Id;
bool convertedOK;};
class IntroPage : public QWizardPage, public QWizard
{
Q_OBJECTpublic:
IntroPage(QWidget *parent = 0); void initializePage(); int nextId() const;
};
class ProgramPage : public QWizardPage
{
Q_OBJECTpublic:
ProgramPage(QWidget *parent = 0); void initializePage();
};
#endif // FLASHWIZARD_H
@
What it became:
@
#ifndef FLASHWIZARD_H
#define FLASHWIZARD_H#include <QWizard>
#include <QtCore>
#include "Interface.h"namespace Ui
{
class FlashWizard;
class IntroPage;
class ProgramPage;}
class FlashWizard : public QWizard
{
Q_OBJECTpublic:
explicit FlashWizard(QWidget *parent = 0);
virtual ~FlashWizard();private slots:
private:
Ui::FlashWizard* ui;
QString SupportFile;
QString iniFile;
QSettings* settings;
ushort Language_Id;
bool convertedOK;};
#endif // FLASHWIZARD_H
@
I promoted the two pages as:
@
#ifndef PAGEONE_H
#define PAGEONE_H#include <QWizardPage>
class PageOne : public QWizardPage
{
Q_OBJECTpublic:
PageOne();void initializePage();
};
#endif // PAGEONE_H
@
And the other class for the second page:
@
#ifndef PAGETWO_H
#define PAGETWO_H#include <QWizardPage>
class PageTwo : public QWizardPage
{
Q_OBJECTpublic:
PageTwo();void initializePage();
};
#endif // PAGETWO_H
@
A simple test of the two:
@
#include "pageone.h"PageOne::PageOne()
{}
void PageOne::initializePage()
{
setSubTitle(tr("Blah-Blah"));
}@
@
#include "pagetwo.h"PageTwo::PageTwo()
{
}void PageTwo::initializePage()
{
setSubTitle(tr("Blahdey-Blah-Blah"));
}@
Now why couldn't this model work with the two promoted classes defined in the main header file? Regardless, I will use this for now.
Thanks
-
I don't know why didn't work that way, maybe somebody here could help providing an explication about this.
I follow this approach (each class have it's own header and implementation file) for good programming habit, I do it without thinking. It's something that I've read in many C++ books.
From my point of view a good source of information about this topic could be:
"C++ Coding Standards":http://www.gotw.ca/publications/c++cs.htm
and for a direct reading:
"C++ Coding Standard":http://www.possibility.com/Cpp/CppCodingStandard.html#classes
Glad to hear that you got it to work.