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
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
Komentarze
Disclaimer
Jakkolwiek jestem właścicielem tego bloga, nie ponoszę odpowiedzialności za kometarze napisane przez innych obywateli tego wolnego kraju.
Zastrzegam sobie prawo do kasowania/modyfikowania komentarzy (jeśli uznam to za stosowne).
Dodaj komentarz
Tylko zalogowani użytkownicy mogą komentować.



#1
Hmm… stosuj Boxy zamiast tabel, a dobrze na tym wyjdziesz ;). Zarowno semantycznie jak i wygodowo. Wiem, bo sam sie przekonałem (choć to było w Pythonie a nie PHP).
Walker | #
#2
Hmm w jakim sensie semantycznie? :>
radmen | #
#3
Hmm.. no można porównać tabelki z GTK do tabelek w HTML, oraz analogicznie boxy do divów, rozumiesz :) ? Kiedyś czytałem na ten temat artykuł, ale nie mam pojęcia gdzie.
Walker | #
#4
Taka tabelka jaką przedstawiłem, raczej jest trudna do porównania do tej z HTMLa ;-)
radmen | #
#5
Zamiast tej tabeli, co w nią wrzuciłeś labels i entries dajesz boxy.
Walker | #
#6
GTK jest ostro popieprzone jesli chodzi o ukladanie elementow. Probowalem juz kiedys zrobic jakas aplikacje, i sie poddalem. Innym razem ;)
D4rky | #
#7
Shoes w Ruby on Rails rlz, serio. Rzuć to PHP-GTL ;-D
Amused Monkey | #
#8
W GTK podoba mi się właśnie pomysł układania elementów w tabelki – ideologicznie poprawne ;) .
W Windows wszystko ustawia się co do piksela i jest to moim zdaniem niewygodne…
Livio | #
#9
Probowałeś zrobić kiedyś całość na boxach zamiast tabelek?
Walker | #
#10
VBox/HBox masz na myśli?
Livio | #
#11
Exactly.
Walker | #
#12
Używałem :P . Czasami nawet musiałem użyć tabelki, a w niej *Boksa :] .
Livio | #