How to use a WComboBox with C++/Wt (Witty)
In this entry I’m going to create a simple form that shows how to add items to WComboBox in two different ways. The first one is useful for static combo items while the second one might be used to populate a combo from a database.
The code is based on our previous Hello World application. There are few lines that changed.
Using Static Combo Items
Adding items to a WComboBox is just a matter of calling the addItem method.
#include <Wt/WApplication>
#include <Wt/WContainerwidget>
#include <Wt/WLabel>
#include <Wt/WComboBox>
#include <Wt/WPushButton>
#include <Wt/WText>
using namespace Wt;
class FormExample: public WContainerWidget {
private:
WLabel* label;
WComboBox* combo;
WPushButton* button;
WText* text;
public:
FormExample(WContainerWidget *parent = 0): WContainerWidget(parent) {
label = new WLabel(this);
combo = new WComboBox(this);
button = new WPushButton(this);
text = new WText(this);
label->setText("Best place to live? ");
combo->addItem("Earth");
combo->addItem("Mars");
combo->addItem("Venus");
combo->addItem("Jupiter");
combo->addItem("Saturn");
button->setText("Send");
button->clicked().connect(this, &FormExample::buttonClicked);
}
void buttonClicked() {
text->setText(combo->currentText() + " is the best place to live...");
}
};
WApplication* createApplication(const WEnvironment &env) {
WApplication* app = new WApplication(env);
app->setTitle("Form Test");
app->root()->addWidget(new FormExample());
return app;
}
int main(int argc, char** argv) {
return WRun(argc, argv, &createApplication);
}
Using Dynamic Combo Items
For this example, I’m using an additional Planet class. This class contains a key and a name properties. It is not really necessary, however it may help you visualize how to handle data from a database in an easier way.
The key classes here are WStandardItemModel and WStandardItem. These two classes will help you create an in-memory representation of your data. To retrieve the selected data you have to use the boost::any_cast function.
#include <Wt/WApplication>
#include <Wt/WContainerwidget>
#include <Wt/WLabel>
#include <Wt/WComboBox>
#include <Wt/WPushButton>
#include <Wt/WStandardItem>
#include <Wt/WStandardItemModel>
#include <Wt/WText>
using namespace Wt;
class Planet {
public:
std::string key;
std::string name;
Planet(std::string key, std::string name): key(key), name(name) {}
};
class FormExample: public WContainerWidget {
private:
WLabel* label;
WComboBox* combo;
WPushButton* button;
WText* text;
public:
FormExample(WContainerWidget *parent = 0): WContainerWidget(parent) {
label = new WLabel(this);
combo = new WComboBox(this);
button = new WPushButton(this);
text = new WText(this);
WStandardItemModel *si = new WStandardItemModel();
Planet p1("P3", "Earth");
WStandardItem *i = new WStandardItem();
i->setData(p1.key, UserRole);
i->setText(p1.name);
si->appendRow(i);
Planet p2("P4", "Mars");
i = new WStandardItem();
i->setData(p2.key, UserRole);
i->setText(p2.name);
si->appendRow(i);
Planet p3("P5", "Jupiter");
i = new WStandardItem();
i->setData(p3.key, UserRole);
i->setText(p3.name);
si->appendRow(i);
label->setText("Best place to live? ");
combo->setModel(si);
button->setText("Send");
button->clicked().connect(this, &FormExample::buttonClicked);
}
void buttonClicked() {
std::string key = boost::any_cast<std::string>(combo->model()->data(combo->currentIndex(), 0, UserRole));
text->setText(key + " is the best place to live...");
}
};
WApplication* createApplication(const WEnvironment &env) {
WApplication* app = new WApplication(env);
app->setTitle("Form Test");
app->root()->addWidget(new FormExample());
return app;
}
int main(int argc, char** argv) {
return WRun(argc, argv, &createApplication);
}
In both cases, you should see something like this:
Happy coding.