A dialog is a window used to communicate information to the user and/or prompt the user for a response. Use the class WDialog to show a dialog. A specialized dialog is also available to alert the user with a message then use the simple WMessageBox dialog.
By default, a WDialog
is modal. A modal window blocks
the user interface, and does not allow the user to interact with
any other part of the user interface until the dialog is
closed. With a modeless dialog the window can be left open while
the user continues in another window of the application. Use
setModal(false)
to create a non-modal dialog. In the
Message box section below you can
find an example of a modeless window.
Unlike other widgets, a dialog does not need to be added to a parent
widget, and it is hidden by default. You must use the method
show()
or setHidden(false)
to show the dialog. The
dialog may be closed by calling accept()
, reject()
or
done()
(or connecting a signal to one of these methods). This
will hide the dialog and emit the finished()
signal, which you
then can listen for to process the dialog result and delete
the dialog.
Typically, an OK button will be connected to accept()
, and in
some cases a Cancel button to reject()
.
You can add content to the dialog by adding the content to its container.
You can get the container with the contents()
method.
A modal dialog can be instantiated in two ways —
synchronously or asynchronously — while a non-modal dialog
can only be instantiated asynchronously. By preference
instantiate a dialog asynchronously. The synchronous use of a
dialog is what is commonly done in desktop applications to show
a modal dialog, and involves a call to exec()
that
starts a local event loop, and returns only when the dialog is
closed. The draw-back of synchronous use is that the application
is not scalable to many concurrent sessions, since it blocks a
thread. This means it is only suitable for applications with
restricted access or applications that are deployed on an
intranet or extranet. When using a dialog asynchronously, there
is no API call that waits for the dialog to be closed. In this
case, the usage is similar to instantiating any other
widget.
A message box is a simple dialog to alert the user with a message. It may require an acknowledgment that the message has been read (usually by clicking an "OK" button), or a decision whether an action should proceed (by clicking an "OK" or "Cancel" button).
The usage is similar to instantiating a WDialog
(or any other
widget). You need to connect to the buttonClicked
signal with a
method that interprets the result and deletes the message
box.
You can get the resulting standard button with buttonResult()
.
The buttons of a WMessageBox may be standard or customized
type of buttons. Customized buttons should be dealt with using
the result()
method from the parent WDialog
.
The strings used in standard buttons can be translated by overriding the
default values of localization keys.
#include <Wt/WContainerWidget.h>
#include <Wt/WMessageBox.h>
#include <Wt/WPushButton.h>
#include <Wt/WText.h>
auto container = std::make_unique<Wt::WContainerWidget>();
Wt::WPushButton *button = container->addNew<Wt::WPushButton>("Status");
Wt::WText *out = container->addNew<Wt::WText>();
out->setMargin(10, Wt::Side::Left);
auto c = container.get();
button->clicked().connect([=] {
out->setText("The status button is clicked.");
auto messageBox =
c->addChild(std::make_unique<Wt::WMessageBox>(
"Status",
"<p>Ready to launch the rocket...</p>"
"<p>Launch the rocket immediately?</p>",
Wt::Icon::Information,
Wt::StandardButton::Yes | Wt::StandardButton::No));
messageBox->setModal(false);
messageBox->buttonClicked().connect([=] {
if (messageBox->buttonResult() == Wt::StandardButton::Yes)
out->setText("The rocket is launched!");
else
out->setText("The rocket is ready for launch...");
c->removeChild(messageBox);
});
messageBox->show();
});
The following example is much more compact, but it has a big disadvantage
because the messagebox is instantiated synchronously. The show()
method is used statically; this involves the static use of the
exec()
method which blocks the current thread until the user has
clicked a button and the result of the messagebox is processed.
It is highly recommended to use a messagebox asynchronously because there
is no API call that waits for the messagebox to be processed in that
case.
#include <Wt/WContainerWidget.h>
#include <Wt/WMessageBox.h>
#include <Wt/WPushButton.h>
#include <Wt/WText.h>
using namespace Wt;
auto container = std::make_unique<Wt::WContainerWidget>();
Wt::WPushButton *button = container->addNew<Wt::WPushButton>("Start");
Wt::WText *out = container->addNew<Wt::WText>();
out->setMargin(10, Wt::Side::Left);
button->clicked().connect([=] {
Wt::StandardButton answer
= Wt::WMessageBox::show("Launch phase",
"<p>Launch the rocket?</p>",
Wt::StandardButton::Ok | Wt::StandardButton::Cancel);
if (answer == Wt::StandardButton::Ok){
out->setText("The rocket is launched!");
} else {
out->setText("Waiting on your decision...");
}
});
A WMessageBox
can be styled using the Wt-dialog
and
Wt-outset
style classes from it's superclass WDialog
.
Its buttons can be styled using the Wt-msgbox-buttons
style
class.