Helping ordinary people create extraordinary websites!
HOME TUTORIALS SCRIPTS WEB HOSTING BLOG FORUM
Get Our Newsletter
Your Email:

Desktop Application Development with PHP-GTK

By Akash Mehta
2008-03-13


Building a real application in PHP-GTK

We've gone through all the usual Hello World, and taken a look at what PHP-GTK can do. But let's do this for real; PHP has a lot of useful inbuilt functionality, so let's take some of it and put it in a useful desktop mini-app. An MD5 hash is always useful, and the md5() function is simple enough, so we'll build a simple application to take a string and generate its MD5 hash.

Interface

When building any desktop application, you should always plan the interface before you start development. In this case, all we need is a text box and a button to click. We can reuse the textbox for the MD5 hash, just for simplicity's sake, although in a production application you might want to put it in an alert box. This is the tricky part of PHP-GTK.

Bashing out code is all very well, but when we develop applications in PHP-GTK we need to think about how the window will be laid out. A standard GtkWindow is what we call a bin container, or a container that can only have one child. That is, you could put a label in it, or a text box, but not both. In our hello world demonstration, we only had one label, so we could put this directly inside the window, like so:

As you can see based on this (oversized) diagram, we have a GtkWindow with a single child control, the GtkLabel. But we can't just pack labels inside windows together, as a window is a bin container. Instead, we can use horizontal and vertical boxes, as well as tables. A special button box is also available just for buttons. PHP-GTK's different containers all use classes, and in true PHP style make use of full OOP with liberal extending of classes. Navigate the subclass tree from the GtkBox section of the documentation onwards to see what sort of containers are on offer.

Our text entry for the string to be MD5 encoded can appear right next to the button to encode, so we don't need any complex structures, just a horizontal container. Inside this horizontal container we'll put a text box and button. Think of it like this:

I find that putting together visual diagrams similar to this is very helpful when planning interfaces to be implemented with pure PHP-GTK. Some simple HTML with inline CSS thrown together in Firebug's realtime editing allowed me to quickly put together these simple yet effective diagrams. Each box is a div with a border, and each label a span inside the div with position: relative to move it up to the border. Of course, there's an alternative to all this complicated wireframing which I'll explain in a moment.

So, we've now worked out what our application is going to look like. Time to get coding!

And that alternative to all this tricky interface diagramming? Well, here it is, and you're going to love it. First, check out the screenshot. All the controls / containers / windows / etc. in an easily-accessible panel on the left, drag and drop application design, tree hierarchy to represent all these parent-child structures? We call it Rapid Application Development, and I'm sure you can guess why! Head over to the official Glade site for more details, and check out this tutorial on how to use Glade with PHP-GTK.

Coding the application

Developing the application is very easy. As we've covered the hello world example in detail, I'll launch into the code here and explain the important points as we go along.

First, we need to create our window:

<?php
$wndHash = new GtkWindow();
$wndHash->connect_simple('destroy', array('gtk', 'main_quit'));

Nothing special here, almost identical to the above. We'll call our window variable $wndHash to avoid conflicts in case we need to run multiple PHP-GTK applications in the same execution. Next, we start creating controls:

$txtString = new GtkEntry();
$btnEncode = new GtkButton('Encode');

For our textbox, where the user will enter a string to be hashed, we'll use a GtkEntry object. A GtkEntry is a fairly standard single-line text entry field, just as you'd expect from, say, your Firefox search bar (besides the search functionality, of course). We also need a button, and a GtkButton object is about our only option here. Next, we need to connect up a signal so that our button can actually do something once clicked:

$btnEncode->connect_simple('clicked', 'encode', $txtString);

When we wanted to connect the "destroy" signal, we only passed two parameters - the first was the signal name, "destroy", and the second was the callback, Gtk:;main_quit(). However, our callback may need to be given a reference to the objects on the form, and instead of messy global variables, the signal connect methods give us an easy way to pass parameters to the callback function. In this case, our callback function is encode(), and we pass it $txtString from the current scope, which it will then take a reference too. We can pass as many arguments to the callback function as needed; just keep adding parameters to connect_simple().

Of course, we also need to write this callback function encode(). We have a reference to the text box, which, as an instance of GtkEntry, has the methods get_text() and set_text(). All we need to do is work out what is in the text box, run it through md5() and put the hash back into the text box. Pretty simple stuff:

function encode(GtkEntry &$txtString)
{
$md5 = md5($txtString->get_text());
$txtString->set_text($md5);
}

We now have our window and the objects that will be on it ready. But we still need to manage layout! Remember that wireframe diagram of the interface we put together? Well, constructing that in code is easier than you think. We first need a container, a GtkHBox (Gtk Horizontal Box). We then need to put inside it first the text box, and then the button. A GtkHBox has an (inherited) method pack_start() (also pack_end()) which tells it to pack in another object inside the container from the start of the container. For a horizontal box, the start is the left. If we used the end counterpart, it would start packing in from the right. Therefore, if we put in first a textbox, and then a button, we'll get a horizontal box filled with a textbox on the left and a button right next to it, ready to put inside our GtkWindow (after a while, you'll start to think of application windows by their PHP-GTK class names too!).

$ctrMain = new GtkHBox();
$ctrMain->pack_start($txtString);
$ctrMain->pack_start($btnEncode);

$wndHash->add($ctrMain);

With that all ready, it's time to put all this inside our GtkWindow, hand over to Gtk::main(), and away we go!

$wndHash->show_all();
Gtk::main();

Here's the final code:

<?php
$wndHash = new GtkWindow();
$wndHash->connect_simple('destroy', array('gtk', 'main_quit'));

$txtString = new GtkEntry();
$btnEncode = new GtkButton('Encode');

$btnEncode->connect_simple('clicked', 'encode', $txtString);
function encode(GtkEntry &$txtString)
{
$md5 = md5($txtString->get_text());
$txtString->set_text($md5);
}

$ctrMain = new GtkHBox();
$ctrMain->pack_start($txtString);
$ctrMain->pack_start($btnEncode);

$wndHash->add($ctrMain);

$wndHash->show_all();
Gtk::main();

Save this is md5.php, load it up via command-line/terminal (Win "C:\Gnope\php-win.exe md5.php" or *nix "php md5.php") and you should see something like the following:

Play around with it a little, and check all is in order:

Your first PHP-GTK application is complete!



Tutorial Pages:
» What is PHP-GTK?
» Getting started with PHP-GTK
» Your first PHP-GTK application
» So how powerful is this PHP-GTK?
» Building a real application in PHP-GTK
» Further reading


Related Tutorials:
» Port Scanning and Service Status Checking in PHP
» Web Database Access from Desktop Applications
» CubeCart 3.0 Installation and Configuration
» PHP Site Search Made Easy
» Installing and Configuring Drupal 6.1
» Installing PHP on Windows