Dialogs

A dialog box pops up, shows the user something, and gets a response back from the user. It's a brief interaction that can (optionally) force the user to respond.

QDialog, the base class for dialogs, has a bool attribute named modal. If modal is set to true, the dialog box blocks input to all other visible windows in its parent. A modal dialog box must be dismissed (by clicking on one of its buttons) before the application can proceed.

In general, dialog boxes should be used only for obtaining or communicating important information that should (or must) be dealt with before the program can proceed.

The QMessageBox (derived from QDialog) class produces a modal dialog with a brief message (or question), a distinctive icon, and from one to three buttons. Each of the icons characterizes a particular severity level and corresponds to a particular kind of message box.

QMessageBox has a number of static convenience functions that cause these kinds of dialogs to pop up. A short application demonstrating the use of the various kinds of QMessagebox is shown in Examples 11.4 and 11.5.

Example 11.4. src/widgets/dialogs/messagebox/dialogs.h

#ifndef APPWINDEMO_H #define APPWINDEMO_H #include class Dialogs : public QMainWindow { Q_OBJECT public: Dialogs(); public slots: void askQuestion(); void askDumbQuestion(); private: QString answer; }; #endif

Example 11.5. src/widgets/dialogs/messagebox/dialogs.cpp

[ . . . . ] void Dialogs::askQuestion() { bool done=false; QString q1("Who was Canadian Prime Minister in 1847?"), a0("John A. Macdonald"), a1("Alexander Mackenzie"), a2("Sir Wilfred Laurier"); while (!done) { int ans = QMessageBox:: question( this, <-- 1 "Difficult Question", q1, a0, a1, a2, 0, <-- 2 -1 ) ; <-- 3 if (ans > 0) return; <-- 4 switch( ans ) { case 0: answer = a0; break; case 1: answer = a1; break; case 2: answer = a2; break; } QString q2(QString("Your answer was: %1." " That is incorrect. Try again?") .arg(answer)); int again = QMessageBox:: question(this, "Your Score", q2, "No", "Yes", "I give up - what's the answer?"); if ( again <1 ) { return; } if (again == 2) { QMessageBox:: information(this, "Ha Ha!", "There was no prime minister until 1867", "Grrrrr....."); return; } } }  

(1)Message box is modal relative to its parent.

(2)default value

(3)Value sent on "esc" or "windowclose".

(4)If window was closed, no QButton was pressed.

When you build and run this application, notice that once the critical dialog is onscreen, you cannot interact with the main window at allthe pull down Questions menu is not receiving events, and even the window manager can't kill the main window. This is the power of a modal dialog.

11.3.1. Input Dialogs and Widgets

When a user enters text into a box, it is an input widget, probably a QLineEdit (for single lines), a QComboBox (for a choice of values), QSpinBox (for a number), or QTextEdit (for multiple lines of text). These widgets are never "solitary" because there needs to be at least a label nearby that tells the user what information is required.

Input dialogs are higher-level widgets that group together the lower-level input widgets with labels and decorations for convenience. QInputDialog has a label, an input widget (such as a QLineEdit), and, like the message dialogs, one to three buttons.

QInputDialog has four configurable static functions that determine the characteristics of the data entry widget. It can return a QString, an int, or a double. Example 11.6 is a short application that supplies the static function getItem() with a QStringList to store a set of possible responses and returns the QString selected by the user.

Example 11.6. src/widgets/dialogs/inputdialog/inputdialog.cpp

#include #include #include int main(int argc, char** argv) { QApplication app(argc, argv); app.setQuitOnLastWindowClosed(false); QStringList hobbits, yesno; hobbits << "Frodo" << "Bilbo" << "Samwise" < "Merry" << "Pippin"; yesno << "yes" << "no"; QString outcome, more, title("Hobbit Selector"); QString query("Pick your favorite Hobbit"); do { QString pick = QInputDialog::getItem(0, title, query, hobbits); outcome = QString("You picked %1, try again?").arg(pick); more = QInputDialog:: getItem(0, "Pick a Hobbit", outcome, yesno, 1, false); } while (more == "yes"); }

The first call to getItem() uses the overloaded version that accepts a QStringList. This puts a QComboBox (editable by default) on the screen, pre-filled with the values from the QStringList. The user can then select one of the choices or type in a new string.

We supplied six arguments in the second call to getItem(), resulting in a non-editable combobox. Here are two screenshots of the running program.

By default, Qt expects a GUI app to have a single top-level window (i.e., a window with no parent). Our Hobbit selection app has two. This can cause some confusion about when the program is finished.

We inserted the following function call to address this problem:

app.setQuitOnLastWindowClosed(false);

 

Exercise: Dialogs

Make the following modifications of the Hobbit Selection app.

1.

Remove the line

app.setQuitOnLastWindowClosed(false);  

and see if you can explain the results.

2.

Change the app so that each time the user, by editing one of the selections in the list, creates a new Hobbit name, that name becomes one of the (sorted) choices for the next iteration.

3.

In both of the getItem() dialogs of the Hobbit Selection app, there is no difference between OK and Cancel. What should that difference be? As Captain Picard would say, "Make it so."

Images and Resources

Категории