Problem
You would like to have a login prompt before your main program starts as shown below:
Solution
We can easily use a GtkDialog to display the popup dialog box that prompts for username and password.
However, since a dialog box to prompt for data is frequently used, we will wrap this into a generic function called get_data()
. We simply pass in the title of the dialog, and an array containing the field labels, the function will automatically display a dialog prompting user to enter the data.
When the user clicks the OK button, the data entered by the user will be returned to you as an array.
Sample Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 27 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 50 51 52 53 54 55 56 57 58 60 61 63 64 65 66 67 69 70 71 72 73 74 75 76 77 78 82 83 84 85 86 87 88 89 90 91 92 93 94 95 97 98 99 100 101 102 103 104 105 106 107 | <?php $login_success = login(); // calls the login function if (!$login_success) exit(0); // exit if login not successful // starts the main program only if login successful $window = new GtkWindow(); $window->set_size_request(400, 150); $window->connect_simple('destroy', array('Gtk','main_quit')); $window->add($vbox = new GtkVBox()); // display title $title = new GtkLabel("Login prompt - Part 1"); $title->modify_font(new PangoFontDescription("Times New Roman Italic 10")); $title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff")); $title->set_size_request(-1, 40); $vbox->pack_start($title, 0, 0); $vbox->pack_start(new GtkLabel("User verified")); $vbox->pack_start(new GtkLabel("Main program starts...")); // the login function function login() { $count = 0; while ($count<3) { $data = get_data("Login", array("Username:", "Password:")); // get username and passwd list($username, $password) = $data; // result of user input is returned as an array if ($username=='user1' && $password=='phpgtk2') { // validate username and password return true; // ok! } else { alert("Incorrect username and password!\nHint: username=user1\npassword=phpgtk2"); // not ok. alert user - note 2 } ++$count; } return false; } // display a popup dialog box to prompt for data function get_data($title, $field_labels) { $dialog = new GtkDialog($title, null, Gtk::DIALOG_MODAL); // create a new dialog $dialog->set_position(Gtk::WIN_POS_CENTER_ALWAYS); $top_area = $dialog->vbox; // get the top area $top_area->pack_start($hbox = new GtkHBox()); $stock = GtkImage::new_from_stock(Gtk::STOCK_DIALOG_QUESTION, Gtk::ICON_SIZE_DIALOG); $hbox->pack_start($stock, 0, 0); // stuff in the icon // display the data entry form as table $table = new GtkTable(); // create a new table $row = 0; $input = array(); // holds the ID of each GtkEntry foreach ($field_labels as $field_label) { $label = new GtkLabel($field_label); $label->set_alignment(0,0); // left-justify the label $table->attach($label, 0, 1, $row, $row+1); // insert the label into table $input[$row] = new GtkEntry(); // create a new input field $table->attach($input[$row], 1, 2, $row, $row+1); // add this besides the label if (eregi("password", $field_label)) $input[$row]->set_visibility(false); // show password entry as '*' ++$row; } $hbox->pack_start($table); $dialog->add_button(Gtk::STOCK_OK, Gtk::RESPONSE_OK); // add an OK button $dialog->set_has_separator(false); // don't display the set_has_separator $dialog->show_all(); // show the dialog $dialog->run(); // the dialog in action // grab the user input before destroying the dialog - note 1 $data = array(); // put user input in an array for ($i=0; $i<count($input); ++$i) { $data[] = $input[$i]->get_text(); } $dialog->destroy(); // done. close the dialog box. return $data; // returns the user input as array } // display popup alert box - note 2 function alert($msg) { $dialog = new GtkDialog('Alert', null, Gtk::DIALOG_MODAL); $dialog->set_position(Gtk::WIN_POS_CENTER_ALWAYS); $top_area = $dialog->vbox; $top_area->pack_start($hbox = new GtkHBox()); $stock = GtkImage::new_from_stock(Gtk::STOCK_DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG); $hbox->pack_start($stock, 0, 0); $hbox->pack_start(new GtkLabel($msg)); $dialog->add_button(Gtk::STOCK_OK, Gtk::RESPONSE_OK); $dialog->set_has_separator(false); $dialog->show_all(); $dialog->run(); $dialog->destroy(); } $window->show_all(); Gtk::main(); ?> |
Output
As shown above. Note: Don't press Enter. You have to click the "OK" button.
Explanation
- When the user clicks "OK", we need to grab the user input before the dialog is destroyed. Since we have stored the ID of each GtkEntry in
$input[$row]
, we can easily get the value of the user input with GtkEntry::get_text(). - When user enters an invalid username or password, we alert the user with the
alert()
function we have written in How to display a popup alert for required fields - Part 1?
Note
This is a very useful function. For example, you can use a one-liner:
get_data("Item Details", array("Item number", "Item description", "quantity", "unit price"));to prompt user to enter the details of an item as shown below:
Of course, you can improve on the function to allow specification of the width of each field.
Please also note that there are a number of "annoyances" in this program:
- Pressing Enter does not automatically go to next field, or activates the "OK" button.
- Suppose the user enters an invalid username or password, the login form gets destroyed, the alert box appears, and the login form re-appears agian. Ideally the login form should only disappear after the user has keyed in the correct username and password.
We will fix this in the Part 2.
Read more...