Problem
Suppose we have four modules in an application - Sales, Purchase, Inventory and Finance. You would like to run these four modules in multiple windows as shown below:
Solution
There are many ways to set up multiple applications to run in multiple windows in php gtk.
The solution presented here make use of GtkDialog. Note that a GtkDialog is a subclass of GtkWindow. So by nature, it is a GtkWindow and can do everything that a GtkWindow can do.
Here are the steps:
- Create each application or module in a GtkDialog of its own.
- Store the ID of each dialog somewhere.
- As long as you don't destroy the dialog, each dialog will be happily living in a window of its own.
- You can hide or show each application by using
$dialog->hide_all()
or$dialog->show_all()
. - When user wants to switch to a different application, you activate the desired application by using
$dialog->run()
.
Sample Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | <?php $modules = array("sales", "purchase", "inventory", "finance"); // names of the modules foreach($modules as $module) { $apps[$module] = setup_app($module); // note 1 } $apps['sales']->show_all(); // show the first module $apps['sales']->run(); // let's go! // setup_app function setup_app($module) { $dialog = new GtkDialog($module, null, Gtk::DIALOG_MODAL); $dialog->set_position(Gtk::WIN_POS_CENTER_ALWAYS); $dialog->set_size_request(400, 200); $top_area = $dialog->vbox; $top_area->pack_start(new GtkLabel("this is $module module")); $top_area->pack_start(new GtkLabel()); // used to "force" the button to stay at bottom show_buttons($top_area, $module); // shows the buttons at bottom of windows $dialog->set_has_separator(false); return $dialog; // returns the ID of the dialog } // shows the buttons at bottom of windows function show_buttons($vbox, $current_module) { global $modules; $hbox = new GtkHBox(); $vbox->pack_start($hbox, 0, 0); $hbox->pack_start(new GtkLabel()); foreach($modules as $module) { $button = new GtkButton(strtoupper(substr($module,0,1)).substr($module,1)); // cap 1st letter $button->set_size_request(80, 32); // makes all button the same size if ($module == $current_module) { // sets the color of the respective button $button->modify_bg(Gtk::STATE_NORMAL, GdkColor::parse("#95DDFF")); $button->modify_bg(Gtk::STATE_ACTIVE, GdkColor::parse("#95DDFF")); $button->modify_bg(Gtk::STATE_PRELIGHT, GdkColor::parse("#95DDFF")); } $hbox->pack_start($button, 0, 0); $hbox->pack_start(new GtkLabel()); $button->connect('clicked', 'on_clicked', $module); // event handler to handle button click } } // process button click function on_clicked($button, $activated_module) { global $apps, $modules; print "button_clicked: $activated_module\n"; $apps[$activated_module]->show_all(); // show the activated module foreach($modules as $module) { if ($module!=$activated_module) $apps[$module]->hide_all(); // hide all others } //foreach($modules as $module) $apps[$module]->show_all(); //note 2 $apps[$activated_module]->run(); } ?> |
Output
As shown above.
Explanation
- Setup each module in a window (or dialog) of its own. Here we store the ID of each dialog in the global array
$apps
. - See notes below.
Note
Note that the code above only show one dialog at a time, hiding all the other "inactive" dialogs. That's why you see only one dialog:
Try uncommenting the line labeled note 2 above. Now all the dialogs are visible, though they are sitting on top of each other. You can move the dialog away from each other to get this:
However, please bear in mind that although you can see all four dialog windows now, only one is active at one time. The active dialog will be the last dialog that you execute the command $dialog->run
. Once you execute this command, that dialog will take control. All keyboard inputs will only go to this dialog, even though other dialogs are visible.
Also, note that in this version, if you close the window in any of the four modules, the entire application will exit. We will fix this, add also add a main menu in Part 2.
p.s. If you would like to have an object-oriented version of this example using classes, please refer to Application Template 01 - multiple modules in multiple windows.
Read more...