Archive | Kurs PHP-GTK RSS for this section

Kurs PHP-GTK cz. 2

Już minęło sporo czasu od pojawienia się pierwszej części kursu PHP-GTK. Chciałem mocno przeprosić za to, że musieliście czekać, niestety w sporej mierze to wina mojego lenistwa…

Dzisiaj zajmiemy się czymś bardziej skomplikowanym. Stworzymy formularz logowania, który pokaże komunikat błędu jeśli wpiszemy złe hasło/login.


Screeny

Free Image Hosting at www.ImageShack.us Free Image Hosting at www.ImageShack.us Free Image Hosting at www.ImageShack.us

Zaczynamy

Na początku tworzymy nowy obiekt-okno, nadajemy mu tytuł, oraz tworzymy proste dowiązanie przerywające główną pętlę (Gtk::main).

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

Później tworzymy dwa pola, do których będziemy mogli wpisać login i hasło. Podobnie jak w wypadku labela tworzymy dwie zmienne, które będą po prostu obiektami.

$txtUsername = new GtkEntry();
$txtPassword = new GtkEntry();

Dodatkowo do tych pól stwórzmy etykietki, aby rozróżnić oba pola.

$lblUsername = new GtkLabel('_Username', true);
$lblPassword = new GtkLabel('_Password', true);

Zwróćcie uwagę, że dodano jeszcze drugi parametr. Jest on opcjonalny, a gdy jest ustawiony na true, to literka przed którą będzie znak ‘_’, będzie podkreślona.

Pozostało nam jeszcze stworzenie dwóch przycisków – “Login” i “Cancel”.

$btnLogin    = new GtkButton('_Login');
$btnCancel   = new GtkButton('_Cancel');

W odróżnieniu od GtkLabel(), w przypadku GtkButton() nie musimy podawać drugiego parametru aby kolejna litera po ‘_’ była podkreślona.

Teraz ustawimy połączenie pomiędzy GtkLabel, a GtkEntry. Ktoś się spyta, co to takiego? Już tłumaczę. To podkreślenie, które ustwiliśmy jest niczym innym jak skrótem klawiszowym. Po wciśnięciu kombinacji [Alt]+[u] pole Username zostanie aktywowane, podobnie jest z drugim polem. Aby stworzyć takie połączenie wykorzystujemy metodę set_mnemonic_widget.

$lblUsername->set_mnemonic_widget($txtUsername);
$lblPassword->set_mnemonic_widget($txtPassword);

Pozostaje nam jeszcze najważniejsze. Ustawienie odpowiednich zdarzeń, które muszą nastąpić po wciśnięciu na Buttony.

$btnCancel->connect_simple('clicked', array($wnd, 'destroy'));
$btnLogin ->connect_simple('clicked', 'login', $wnd, $txtUsername, $txtPassword);

Po wciśnięciu “Cancel” program po prostu się wyłączy. Po wciśnięciu “Login” zostanie wywołana (jeszcze nie opisana) funkcja “login”, zmienne $wnd, $txtUsername, $txtPassword są po prostu parametrami przesyłanymi do funkcji.

Już wcześniej wspominałem, że okno może trzymać bezpośrednio tylko jeden widżet. Rozwiązaniem są różne kontenery, które wszystko przetrzymują wewnątrz, a potem są “doklejane” do głównego okna. W tym wypadku posłużymy się GtkTable, które w przejrzysty sposób utrzyma nasze widżety (zmienna $lblCredit, będzie jedynie przechowywała krótki komunikat).

Aby zamieścić nasze widżety w tabelkę należy wykonać coś takiego:

$tbl = new GtkTable(3, 2);
$tbl->attach($lblCredit, 0, 2, 0, 1);
$tbl->attach($lblUsername, 0, 1, 1, 2);
$tbl->attach($txtUsername, 1, 2, 1, 2);
$tbl->attach($lblPassword, 0, 1, 2, 3);
$tbl->attach($txtPassword, 1, 2, 2, 3);

Niestety umieszczanie elementów w tabeli wydaje się IMO wyjątkowo udziwnione. Żeby to jakoś ułatwić, postaram się króciutko wyjaśnić co oznaczają kolejne parametry.

void attach(GtkWidget child, int left_attach, int right_attach, int top_attach, int bottom_attach [, GtkAttachOptions xoptions = Gtk::EXPAND|Gtk::FILL [, GtkAttachOptions yoptions = Gtk::EXPAND|Gtk::FILL [, int xpadding = Gtk::EXPAND|Gtk::FILL [, int ypadding = Gtk::EXPAND|Gtk::FILL]]]]);

Taki jest początek opisu tej metody. Nie chcę straszyć nikogo także wytłumaczę tylko czym są te cyferki ;-)

int left_attach – oznacza miejsce od lewej strony
int right_attach – oznacza miejsce od prawej strony
int top_attach – oznacza miejsce od góry
int bottom_attach – oznacza miejsce od dołu

Możliwe, że źle zrozumiałem sposób umiejscowienia w tabelce elementów, także poprawcie mnie jeśli się mylę.

Przyciski dostaną swój własny kontener.

$bbox = new GtkHButtonBox();
$bbox->set_layout(Gtk::BUTTONBOX_EDGE);
$bbox->add($btnCancel);
$bbox->add($btnLogin);

Stworzyliśmy dwa osobne kontenery, ale główne okno, może mieć “przyczepiony” tylko jeden widżet, także oba kontenery dodamy do kolejnego.

$vbox = new GtkVBox();
$vbox->pack_start($tbl);
$vbox->pack_start($bbox);

Dopiero teraz możemy dodać nasze widżety na główne okno (konkretniej dodajemy kontener, który przechowuje wszystkie widżety).

$wnd->add($vbox);
$wnd->show_all();
Gtk::main();

Teraz pozostaje nam zapis funkcji logowania. Jeśli jakieś z pól pozostanie puste, wyświetli się komunikat o błędzie. Jeśli uda nam się zalogować to dostaniemy komunikat, że wszystko jest ok, po czym program się wyłączy.

Aby wyciągnąć zawartość pól “Username” i “Password”, posługujemy się metodą get_text() dołączoną do klasy GtkEntry.

$strUsername = $txtUsername->get_text();
$strPassword = $txtPassword->get_text();

Poprawność wpisanego tekstu sprawdzamy poprzez zwykłe funkcje PHP (nie zapominajcie, że to jest tylko dodatek do PHP ;-] ).

W celu wyświetlenia okna dialogowego wystarczy wpisać:

$dialog = new GtkMessageDialog($wnd, Gtk::DIALOG_MODAL, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, $errors);
$dialog->set_markup("W I A D O M O S C");
$dialog->run();
$dialog->destroy();

Na koniec załączam gotowy kod (można go również pobrać z phpfi):

<?php
if (!class_exists('gtk')) {
    die("Please load the php-gtk2 module in your php.ini\r\n");
}

/**
*   Ta funkcja zostaje wywołana po kliknieciu buttona "Login"
*
*   @param GtkWindow $wnd           Okno logowania, potrzebne, zeby je pozniej 
*                                   zamknac
*   @param GtkEntry $txtUsername    Pole tekstowe, potrzebny zeby wyciagnac 
*                                   tekst
*   @param GtkEntry $txtPassword    Tak samo jak wyzej
*/

function login(GtkWindow $wnd, GtkEntry $txtUsername, GtkEntry $txtPassword)
{
    //pobranie wartosci pol tekstowych
    $strUsername = $txtUsername->get_text();
    $strPassword = $txtPassword->get_text();
 
    //sprawdzanie potrzebnych rzeczy
    $errors = null;
    if (strlen($strUsername) == 0) {
        $errors .= "Brakuje nazwy uzytkownika.\r\n";
    }
    if (strlen($strPassword) == 0) {
        $errors .= "Brakuje hasla.\r\n";
    }
 
    if ($errors !== null) {
        //Jesli byl przynajmniej blad to powinno sie pokazac okno dialogowe
        $dialog = new GtkMessageDialog($wnd, Gtk::DIALOG_MODAL,
            Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, $errors);
        $dialog->set_markup(
            "Wystapily pewne problemy:\r\n"
            . "<span foreground='red'>" . $errors . "</span>"
        );
        $dialog->run();
        $dialog->destroy();
    } else {
        $msg = "Witaj $strUsername!\r\n";
        $msg .= "Twoje magiczne haslo to: $strPassword ;-]";

        $dialog = new GtkMessageDialog($wnd, Gtk::DIALOG_MODAL, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK, $msg);
        $dialog->set_markup($msg);
        $dialog->run();
        $dialog->destroy();
        $wnd->destroy();
    }
}
 
$wnd = new GtkWindow();
$wnd->set_title('Login');
$wnd->connect_simple('destroy', array('gtk', 'main_quit'));

// stworzenie pol tekstowych
$txtUsername = new GtkEntry();
$txtPassword = new GtkEntry();

// stworzenie etykiet
$lblUsername = new GtkLabel('_Username', true);
$lblPassword = new GtkLabel('_Password', true);
$lblCredit = new GtkLabel('Please login');

// stworzenie buttonow
$btnLogin    = new GtkButton('_Login');
$btnCancel   = new GtkButton('_Cancel');

// ustawienie skrotow klawiszowych
$lblUsername->set_mnemonic_widget($txtUsername);
$lblPassword->set_mnemonic_widget($txtPassword);

// polaczenie zdarzen
$btnCancel->connect_simple('clicked', array($wnd, 'destroy'));
$btnLogin ->connect_simple('clicked', 'login', $wnd, $txtUsername, $txtPassword);

// stworzenie tabelki
$tbl = new GtkTable(3, 2);
$tbl->attach($lblCredit, 0, 2, 0, 1);
$tbl->attach($lblUsername, 0, 1, 1, 2);
$tbl->attach($txtUsername, 1, 2, 1, 2);
$tbl->attach($lblPassword, 0, 1, 2, 3);
$tbl->attach($txtPassword, 1, 2, 2, 3);

// kontener na przyciski
$bbox = new GtkHButtonBox();
$bbox->set_layout(Gtk::BUTTONBOX_EDGE);
$bbox->add($btnCancel);
$bbox->add($btnLogin);

// kontener przechowujacy tabelke i buttony
$vbox = new GtkVBox();
$vbox->pack_start($tbl);
$vbox->pack_start($bbox);

$wnd->add($vbox);
$wnd->show_all();
Gtk::main();
?>

Przypominam, że póki co ten kurs jest jedynie tłumaczeniem oficjalnego kursu, którego można znaleźć na stronie php.net

Kurs PHP-GTK cz.1

PHP-GTK to rozszerzenie PHP stworzone przez Andrieja Zmiewskiego pozwalające używać popularnej biblioteki GTK+ służącej do tworzenia graficznych interfejsów użytkownika na podstawie zestawu dostępnych widgetów (kontrolek). Programy korzystające z PHP-GTK wyróżniają się łatwością i szybkością napisania.

via Wikipedia

Już od dawna chciałem chociaż troszkę poznać to rozszerzenie. Trochę to potrwało zanim cokolwiek się dowiedziałem. Aktualnie sam poznaję PHP-GTK, ale mogę już opisać pewne “podstawy podstaw”. Ten kurs proszę traktujcie raczej jako wolne tłumaczenie kolejnego z rozdziałów tutoriala znajdującego się na stronie projektu.


Instalacja

Aby zainstalować rozszerzenie PHP-GTK należy skompilować jego źródła. Dobry kurs na zrobienie tego pod Ubuntu (czyli pewnie też i pod Debianem) znajduje się na forum Ubuntu. Ja tylko przypomnę jak należy skompilować tą paczkę.

Źródła można pobrać stąd. Po ściągnięciu i rozpakowaniu wchodzimy do katalogu, a potem w konsoli wpisujemy:

./buildconf 
./configure 
make 
sudo make install

Później pozostaje nam jedynie edycja pliku /etc/php5/cli/php.ini, a mianowicie dopisanie na końcu czegoś takiego:

extension=php_gtk2.so

Hello World

Zawsze wszystko zaczyna się od tego prostego skryptu/programu. Naszym celem będzie wyświetlenie okienka dialogowego z napisem “Hello World”. Podobnie jak innym kursie przedstawię najpierw kod, a potem zajmę się jego tłumaczeniem.

<?php
if (!class_exists('gtk')) {
    die("Please load the php-gtk2 module in your php.ini\r\n");
}
 
$wnd = new GtkWindow();
$wnd->set_title('Hello world');
$wnd->connect_simple('destroy', array('gtk', 'main_quit'));
 
$lblHello = new GtkLabel("Just wanted to say\r\n'Hello world!'");
$wnd->add($lblHello);
 
$wnd->show_all();
Gtk::main();
?>

Jeśli pokaże nam się komunikat: Fatal error: Call to undefined function: connect_simple() to oznacza, że prawdopodobnie korzystasz z wersji GTK1. Ten kurs obejmuje jedynie GTK2, także nie masz czego tutaj szukać ;-]

Takiemu plikowi nadajemy dowolną nazwę, ale dla odróżnienia od innych, zwykłych, skryptów PHP nadajmy mu rozszerzenie *.phpw. Ważne jest aby odpalić skrypt spod konsoli poleceniem php {nazwa_pliku}. Otwierając przez przeglądarkie nie zobaczymy żadnych efektów.

Na specjalne życzenie S. wstawiam dodatkowo zrzut efektu działania tego skryptu:

PHP-GTK Hello World Script

Sprawdzanie czy klasa GTK istnieje

if (!class_exists('gtk')) {
    die("Please load the php-gtk2 module in your php.ini\r\n");
}

Te linijki są odpowiedzialne za sprawdzenie, czy rozszerzenie PHP-GTK jest zainstalowane. Jeśli nie jest skrypt się nie wykona, ponieważ nie znajdzie klasy “gtk”. Dawniej w takim wypadku stosowało się polecenie dl(), lecz w PHP 5 to polecenie posiada status “deprecated”, także nie zaleca się jego stosowania.

Tworzenie głównego okna

$wnd = new GtkWindow();

Tworzenie nowego okna jest proste jak tworzenie nowego obiektu. Zmienna $wnd jest właśnie deklarowana jako obiekt.

$wnd->set_title('Hello world');

Metoda set_title sprawia, że okienko będzie miało jakiś tytuł. Wiadomo, że to akurat jest przydatne ;-)

$wnd->connect_simple('destroy', array('gtk', 'main_quit'));

To jest bardzo ważna linijka. Bez niej po wyłączeniu skryptu główna pętla będzie się cały czas wykonywała. W tym wypadku metoda connect_simple sprawia, że po zamknięciu (a dosłownie mówiąc – po zniszczeniu) okna pętla zostanie przerwana.

Metoda connect_simple służy również do podpinania różnych zdarzeń pod odpowiednie funkcje. Przykłado dla kliknięcia buttona, który jest zdefinowany w osobnej zmiennej, skorzystanie z tej metody wyglądałoby tak:

$button->connect_simple("clicked", array($wnd, "zdarzenie"));

Po kliknięciu na ten guzik zostanie wywołana funkcja “zdarzenie”. W następnych częściach postaram się lepiej przedstawić jak z czegoś takiego korzystać.

Tworzenie labela, z napisem “Hello World”

Tworzenie nowego labela (tudzież etykietki) polega na stworzeniu nowego obiektu. W naszym przykładzie jest to po prostu:

$lblHello = new GtkLabel("Just wanted to say\r\n'Hello world!'");

Jak widać nowa etykietka to nowy obiekt, a jej zawartość to paramter, który został podany podczas tworzenia obiektu.

Aby dodać (hmm dokleić) naszą etykietę należy jeszcze dopisać:

$wnd->add($lblHello);

Główne okno sprawia jeden mały problem. Jest nim mianowicie to, że można do niego “wsadzić” tylko jeden widżet. W tej części kursu tylko jeden widżet jest przyczepiany, także nie ma większych problemów, ale w późniejszych częściach widżety trzeba będzie “składować” w jakimś pojemniku. Taki pojemnik dopiero przytwierdzamy do głównego okna. Umożliwi to nam wyświetlenie kilku widżetów w głównym oknie.

Wyświetlenie okna

Póki co naszeg okno nie będzie widoczne. Aby je pokazać, należy skorzystać z metody show_all():

$wnd->show_all();

Ta metoda sprawi, że zostaną pokazane wszystkie widżety. Można również skorzystać z metody show(), ale w tym wypadku należałoby stosować ją dla każdego obiektu, ponieważ inaczej nie zostanie wyświetlony.

Po tych “zabiegach” pozostaje nam odpalenie głównej pętli Gtk::main();. Ta pętla sprawi, że nasze okno będzie się wyświetlało nawet wtedy kiedy skrypt będzie bezczynny. Normalnie (tzn, bez tej pętli) nasz skrypt by się wykonał, a okno prawdopodobnie by tylko mignęło, ponieważ po wykonaniu działania skrypt by się wyłączył, czyli nasze okno by zginęło.

Podsumowanie

W tym (bardzo) krótkim kursie przedstawiłem sposób instalacji rozszerzenia PHP-GTK, oraz bardzo podstawowego sposobu pisania skryptów z wykorzystaniem klasy “gtk”. W następnym kursie postaram się coś więcej już przedstawić. Nie wiem kiedy kolejna część wyjdzie, ale powinna się ukazać.

Gdyby ktoś chciał bardziej poznać PHP-GTK to niech zajrzy sobie na anglojęzyczny kurs.