DaClown
DaClown

Reputation: 4569

How to specialize a widget according to a file type?

I'm looking for a way to specialize a widget at runtime. I have a form created with Qt Designer. In this form there is a widget that displays user data, like name, age and so on. Then the user chooses a file and according to the type the widget shall display additional information (like to OO example person -> student, teacher).

I tried to put an empty QWidget on my form, assigned a person widget to it and if the user clicks a button I call deleteLater() on person and assign a new Student(). This works but the new widget then doesn't follow the layout.

I also found QStackedWidget. This seems to work but because all possible widgets are created when the form is shown, even if they are never used, this way doesn't feel right.

What would be the way to accomplish this?

Edit: I feel that my question is a bit unclear. What Qt mechanism should be utilized if one wants to replace a QWidget with a specialized (inherited) version of the original widget? I'm looking for the Qt way to do this.

Upvotes: 1

Views: 159

Answers (4)

TimW
TimW

Reputation: 8447

You need to add a widget dynamically to the widget you have drawn in the designer.

// in UI file
QWidget *wdgFromForm;

// in cpp file 
QHBoxLayout *const layout(new QHBoxLayout(wdgFromForm)); 
SpecializedWidget * specializedWidget( new SpecializedWidget(wdgFromForm));
layout->addWidget(specializedWidget);

Upvotes: 1

Frank Osterfeld
Frank Osterfeld

Reputation: 25155

Adding widgets dynamically to a layout is not a problem. You might need to call updateGeometry on the containing widget though.

Upvotes: 0

Rudi
Rudi

Reputation: 19940

This looks like a use case for the factory pattern.

#include <map>
#include <string>
struct Whatever;
struct QWidget;
typedef QWidget*(*WidgetCtor)(Whatever*);
typedef std::map<std::string, WidgetCtor> FileFactory;

QWidget* createFoo(Whatever*);
QWidget* createBar(Whatever*);
QWidget* createDefault(Whatever*);

void factory_init(FileFactory& ff)
{
    ff["foo"] = createFoo;
    ff["bar"] = createBar;
}

QWidget* create_by_factory(const FileFactory& ff, const std::string t, Whatever* w)
{
    FileFactory::const_iterator it(ff.find(t));
    if(it != ff.end())
    {
        return it->second(w);
    }
    else
    {
        return createDefault(w);
    }
}

Upvotes: 0

Baltasarq
Baltasarq

Reputation: 12202

Maybe the problem is not that the widget is not suitable, but simply that you're not giving time for the widget to update.

You could take a look at processEvents: http://web.mit.edu/qt-dynamic/www/qapplication.html#details

Upvotes: 0

Related Questions