background image

2 / 2 0 0 5

 

Wszelkie prawa zastrzeżone.  Rozpowszechnianie artykułu bez  zgody Software Wydawnictwo Sp. z o.o.  zabronione.

 Software Wydawnictwo Sp. z o.o., ul. Lewartowskiego 6, 00-190 Warszawa, POLSKA.

redakcja@phpsolmag.org

background image

Projekty

PHP Solutions Nr 2/2005

www.phpsolmag.org

2

Projekty

PHP-GTK

PHP Solutions Nr 2/2005

www.phpsolmag.org

3

C

zęste  uruchamianie  wielu  kom-
puterów  jest  bardzo  męczące, 
szczególnie,  gdy  są  one  rozsia-

ne po wielu pomieszczeniach w budynku. 
Można jednak ułatwić tę czynność – słu-
żą  do  tego  aplikacje  typu  Wake-On-Lan 
(WOL), które budzą wszystkie lub wybra-
ne  komputery  znajdujące  się  w  sieci  lo-
kalnej  na  podstawie  adresów  MAC  ich 
kart sieciowych.

Wzięliśmy  pod  lupę  jeden  z  takich 

programów.  Jego  instalację  opisaliśmy 
w  Ramce  Instalacja  Wake-On-Lan.  Jest 
to prosta aplikacja działająca w trybie tek-
stowym – aby ją uruchomić, trzeba w linii 
poleceń wpisać 

wakeonlan <adres _ MAC>

np. 

wakeonlan 3F:34:00:AC:90:A0

 i zdalny 

komputer  zostanie  uruchomiony.  Już  to 
jest powodem do radości – o niebo lepiej 
przecież wprowadzić serię takich instruk-
cji, niż biegać po całym budynku! Dlacze-
go by jednak nie ułatwić sobie życia auto-
matyzując ten proces? Zrobimy to, wypo-
sażając to pożyteczne narzędzie w inter-

Za pomocą biblioteki PHP-GTK możemy tworzyć 

profesjonalne aplikacje okienkowe przy użyciu 

PHP. Wystarczy przećwiczyć ją na paru prostych 

przykładach i zacząć pisać programy, do których 

dawniej potrzebowalibyśmy znajomości C++ czy 

Javy.

fejs graficzny (frontend), do napisania któ-
rego użyjemy PHP z biblioteką PHP-GTK. 
Jest  ona  darmowa  i  dostępna  na  naszej 
płycie oraz w Sieci (jej instalację opisali-
śmy w Ramce Instalacja PHP-GTK).

Dla  wielu  programistów  PHP  jest  to 

nowość  –  przyzwyczaili  się  bowiem,  że 
PHP  to  wyłącznie  wygodny  język  skryp-
towy umożliwiający tworzenie zaawanso-
wanych stron WWW lub aplikacji interne-
towych.  Niewielu  natomiast  zdaje  sobie 
sprawę z faktu, że po zainstalowaniu 

Tworzymy frontend

do Wake-On-Lan w PHP-GTK

Jacek Niewęgłowski

W SIECI

NA CD

Na  CD  zamieściliśmy  kody 

źródłowe gotowego interfejsu, 

aplikację wakeonlan oraz roz-

szerzenie PHP-GTK pod Win-

dows i Linuksa.

1. http://gtk.php.net

2. http://gtk.php.net/manual/en/

reference.php

3. http://oldgsd.lsd.di.uminho.pt./

jpo/software/wakeonlan/

4. http://www.gtk.org

Co należy wiedzieć...

Czytelnik  powinien  mieć  podstawową 

znajomość składni języka PHP. Przydat-

na też będzie wiedza z zakresu podstaw 

programowania obiektowego, w tym po-

jęć klasa obiekt.

Co obiecujemy...

Programista  dowie  się,  jak  stworzyć 

graficzny  interfejs  do  programu  Wake-

On-Lan i zdobędzie wystarczającą wie-

dzę, aby samodzielnie tworzyć aplikacje 

z wykorzystaniem PHP-GTK.

background image

Projekty

PHP Solutions Nr 2/2005

www.phpsolmag.org

2

Projekty

PHP-GTK

PHP Solutions Nr 2/2005

www.phpsolmag.org

3

PHP-GTK parser PHP może również 

stać  się  potężnym  narzędziem  do  budo-
wania w pełni funkcjonalnych, samodziel-
nych  aplikacji  okienkowych  działających 
zarówno  pod  kontrolą  systemu  Linux  jak 
i Windows.

Okno na dzień dobry

Tworzenie interfejsu graficznego (w skró-
cie  GUI)  przy  użyciu  PHP-GTK  nie  jest 
zbyt  trudne  (co  wynika  m.in.  z  przejrzy-
stości biblioteki GTK). Czas jego wdroże-
nia zależy przede wszystkim od tego, jak 
dobrze zaprojektujemy go przed przystą-
pieniem do programowania. 

Najprostszy  przykład  zastosowania 

PHP-GTK znajduje się na Listingu 1 – te 
kilka  linijek  kodu  to  wszystko,  czego  po-
trzebujemy,  aby  wygenerować  okienko 
i  ustawić  jego  podstawowe  właściwości. 
Efekt  działania  tego  skryptu  przedstawia 
Rysunek 1.

Koncepcja

Nasz interfejs ma być funkcjonalny i pro-
sty w obsłudze. Aplikacja zewnętrzna Wa-
ke-On-Lan
  ma  być  uruchamiana  jednym 
kliknięciem. Chcemy móc wpisywać adre-
sy MAC w okienku i gromadzić listę kilku 
do kilkunastu ostatnio odwiedzanych, aby 
następnie je wybierać. Lista powinna być 
automatycznie ładowana przy uruchamia-
niu frontendu i zapisywana przy jego za-
mykaniu. 

Musimy wziąć pod uwagę to, iż apli-

kacja  Wake-On-Lan  przesyła  budzą-
ce  zdalny  komputer  „magiczne  pakiety” 
przy pomocy protokołu UDP (ang. User 
Datagram  Protocol
)  –  nie  mamy  więc 
żadnej gwarancji, iż zostaną dostarczo-

ne  do  adresata.  Obowiązek  zmniejsze-
nia  ilości  błędów  spada  więc  na  nas  – 
dlatego  powinniśmy  zaimplementować 
sprawdzanie  danych  po  stronie  naszej 
aplikacji, która automatycznie będzie in-
formować o błędach dotyczących forma-
tu adresu.

Podczas  pisania  naszego  programu 

będziemy  dążyli  do  uzyskania  efektu  ta-
kiego  jak  na  Rysunku  2.  Cały  kod  two-
rzący interfejs umieścimy w jednym pliku 
o nazwie wolgui.php.

Tworzymy interfejs

Każda  aplikacja  PHP-GTK  musi  zawie-
rać  na  końcu  pliku  z  kodem  instrukcję 

gtk::main()

,  która  rozpoczyna  główną 

pętlę  programu.  Aby  poprawnie  zakoń-
czyć działanie aplikacji, trzeba wywołać 
instrukcję 

gtk::quit()

. Okienko jest pod-

stawowym  obiektem  zawierającym  inne 
elementy  interfejsu  (widgety,  ang.  wid-
gets
),  zwanym  kontenerem  (ang.  con-
tainer
).

Na Listingu 1 mamy już zalążek ko-

du  tworzącego  okienko  –  musimy  go 
tylko  rozwinąć.  Na  początek  usuwa-
my  (albo  blokujemy  znacznikiem  ko-
mentarza)  instrukcję 

$window->show _

all()

,  którą  należy  umieścić  po  usta-

wieniu  wszystkich  elementów  fronten-
du.  Inicjujemy  okienko,  nadajemy  mu 
tytuł i ustawiamy jego parametry: poło-

żenie (zawsze na środku ekranu), sze-
rokość  (stała),  wysokość  (automatycz-
na,  zależna  od  zawartości  okna),  sze-
rokość  ramki  (margines  wewnętrzny 
między  elementami  okna  a  jego  kra-
wędzią),  możliwości  skalowania  (wyłą-
czamy całkowicie), a następnie decydu-
jemy,  że  zamknięcie  okienka  oznacza 
przerwanie  programu.  Efekty  naszych 
dotychczasowych prac można obejrzeć 
na Listingu 3.

Wypadałoby  powiedzieć  parę  słów 

o  zamykaniu  okna  –  skąd  program  ma 
wiedzieć, że gdy to robimy, każemy mu 
przerwać swoje działanie? Dzieje się to 
dzięki połączeniu (ang. connecting) wy-
syłanego przez wydarzenie (ang. event
zamknięcia  okna  sygnału  (ang.  signal

destroy

 z funkcją 

shutdown() 

(napisze-

my  ją  później),  która  wywołując 

gtk::

quit()

  przerywa  działanie  aplikacji.  Sy-

gnały  wysyła  podczas  interakcji  z  użyt-
kownikiem każdy element interfejsu wy-
stępujący w PHP-GTK, a kojarzone z ni-
mi funkcje (które są zwykłymi funkcjami 

Rysunek  1. 

Pierwsze  okienko  w  PHP-

GTK

Listing 1. 

Tworzenie okienka 

w PHP-GTK

$window

 = &

new

 GtkWindow

()

;

$window

-

>

set_title

(

"Wake-On-Lan"

)

;

$window

-

>

set_usize

(

300, -1

)

;

$window

-

>

show_all

()

;

Czym jest adres MAC?

Adres MAC (ang. Media Access Control 

address) to 48-bitowy, sprzętowy adres 

karty  sieciowej  nadawany  przez  produ-

centa.  Jest  unikalny  w  skali  światowej 

(teoretycznie  –  niektóre  nowsze  karty 

dają  możliwość  jego  zmiany).  Zapisu-

jemy  go  w  postaci  sześciu  liczb  8-bito-

wych w systemie szesnastkowym (hek-

sadecymalnym),  rozdzielonych  znakami 

dwukropka  lub  myślnikami  –  przykład: 

A0:04:FC:0C:00:26.

Wymagania Wake-On-Lan

Na komputerze, z którego będziemy uruchamiać inne maszyny potrzebujemy jedynie za-

instalowanej aplikacji WOL. Jednak, aby cała operacja przebiegła pomyślnie, budzony 

komputer musi spełniać pewne warunki sprzętowe. Oto one:

•   płyta główna ATX z 3-pinowym złączem WOL,
•   opcja LAN Wakeup włączona w BIOS-ie,
•   karta sieciowa wspierająca WOL, prawidłowo podłączona do płyty głównej,
•   zasilacz zgodny ze specyfikacją ATX 2.01.

Instalacja Wake-On-Lan

Istnieje  kilka  różnych  aplikacji  typu  WOL.  My  skorzystamy  z  programu  napisanego 

w PERL-u przez José Pedro Oliveira, dostępnego pod adresem http://gsd.di.uminho.pt/

jpo/software/wakeonlan/downloads/wakeonlan-0.40.tar.gz

Aplikacja działa pod kontrolą systemu Linux, a jej instalacja sprowadza się do kilku 

prostych kroków – ściągnij archiwum, przejdź do katalogu, w którym zostało zapisane 

i wykonaj następujące polecenia:

tar -zxvf wakeonlan-0.40.tar.gz
cd wakeonlan-0.40
perl Makefile.PL
make
make install

Po wykonaniu tych czynności dostępne będzie polecenie 

wakeonlan

. Sposób jego użycia 

to: 

wakeonlan <adres karty sieciowej komputera do obudzenia>

Przykład: 

wakeonlan 00:09:7B:89:48:71

background image

PHP-GTK

Projekty

PHP Solutions Nr 2/2005

www.phpsolmag.org

4

PHP)  określamy  angielskim  terminem 
callbacks

Przejdźmy  teraz  do  tworzenia  funk-

cji 

shutdown()

.  Wiemy  już  częściowo,  co 

ma ona robić – przerywać działanie pro-
gramu.  Fajnie  by  było,  gdyby  zostawiała 
po tym ślad w konsoli systemowej, z któ-
rej  użytkownik  wywoła  skrypt  –  łatwiej 
będzie stwierdzić, że program został za-
mknięty  prawidłowo.  Pamiętajmy,  że  nie 
pracujemy  w  trybie  CGI  i  naszym  stan-
dardowym wyjściem jest nie ekran prze-
glądarki, tylko konsola – do niej więc funk-
cje takie jak 

print()

 czy 

echo

 będą kiero-

wać dane. Kod funkcji 

shutdown()

 prezen-

tujemy na Listingu 4.

Elementy interfejsu

Utworzenie  i  ustawienie  okienka  to  jed-
nak  dopiero  początek.  Oto  lista  elemen-
tów, które dopiero musimy zaimplemento-
wać w naszym frontendzie:

•   etykieta  Adres  MAC,  opisująca  pole 

tekstowe do wprowadzania adresu,

•   pole tekstowe, w które użytkownik bę-

dzie mógł wpisać adres MAC budzo-
nego komputera,

•   lista przechowującą ostatnio wprowa-

dzone adresy (historia),

•   przycisk  Obudź,  wywołujący  ze-

wnętrzną aplikację,

•   przycisk  Zamknij,  kończący  działanie 

aplikacji,

•   przycisk Wyczyść listę, pozwalający wy-

czyścić historię wpisywanych adresów.

Zaczniemy  od  utworzenia  tych  elemen-
tów,  a  dopiero  później  rozmieścimy  je 
w obszarze naszego okna. Każdy z wid-
getów jest zdefiniowany w odrębnej kla-
sie – tworzymy więc jego instancję czy-
li obiekt. Wszelkie parametry przekazu-
jemy  albo  przez  jego  konstruktor,  albo 
później, przy użyciu innych metod obiek-
tu.  Na  pierwszy  ogień  pójdzie  etykieta 

Adres  Mac,  zdefiniowana  w  klasie 

Gtk-

Label

.  Tworzymy  jej  instancję 

$label

przekazując  jednocześnie  napis,  który 
ma się na niej ukazać, a następnie usta-
wiamy dodatkowy parametr – wyrówna-
nie tekstu. 

Następnie  utworzymy  pole  tekstowe 

–  obiekt  klasy 

GtkEntry

,  który  nazwiemy 

$macaddress

.  Pamiętajmy,  aby  umożliwić 

użytkownikowi wpisywanie tekstu do nie-
go. Efekt prac widać na Listingu 5.

Zrobiliśmy  już  najprostsze  elemen-

ty,  czas  na  coś  trudniejszego.  Zajmij-
my  się  więc  historią  ostatnio  wpisywa-
nych adresów, która będzie listą zawie-
rającą  tylko  jedną  kolumnę  o  nagłówku 
Ostatnio  wywołane  i  umożliwiającą  wy-
branie tylko jednego elementu pojedyn-
czym kliknięciem. Ma także dostosowy-
wać swoją szerokość do zawartości. Ża-
den  problem,  PHP-GTK  dysponuje  kla-
są 

GtkCList

.  Tworzymy  jej  obiekt  nazy-

wając go 

$clist

. Ustawiamy jej parame-

try dotyczące kolumn i wymiarów. Defi-

Rysunek 2. 

Wygląd interfejsu

Listing 2. 

Ładowanie rozszerzenia 

PHP-GTK

if

(

!extension_loaded

(

'gtk'

)){

  dl

(

'php_gtk.'

.PHP_SHLIB_SUFFIX

)

;

}

Wymagania PHP-GTK

Do  poprawnego  działania  rozszerzenie  PHP-GTK  potrzebuje  zainstalowanego  PHP 

4.3.x oraz biblioteki Gtk+ 1.2.6 lub nowszej (ale nie z serii Gtk+ 2.x). Aktualnie rozszerze-

nie w żadnym stopniu nie współpracuje z PHP5. W przyszłości autorzy planują dodanie 

obsługi PHP5 i biblioteki Gtk+ z serii 2.x.

Instalacja PHP-GTK

Pod Linuksem zwykle mamy w systemie bibliotekę Gtk+, a jeśli nie, to znajduje się ona 

wśród pakietów w dystrybucji. Można też ją ściągnąć ze stron GTK: http://www.gtk.org 

i zainstalować. Następnie pobieramy archiwum PHP-GTK – z płyty załączonej do nume-

ru lub z witryny projektu PHP-GTK: http://gtk.php.net/, sekcja download. Potem wchodzi-

my do katalogu, w którym umieściliśmy ten plik i wydajemy następujące polecenia:

tar -zxvf php-gtk-1.0.1.tar.gz
cd php-gtk-1.0.1
./buildconfig
./configure –enable-php-gtk –disable-libglade
make
make install

Pod Windows sprawa jest jeszcze prostsza – wystarczy ściągnąć z Sieci lub przegrać 
z naszej płyty archiwum PHP-GTK zawierające komplet skompilowanych pakietów, któ-
rych potrzebujemy: rozszerzenie PHP-GTK, bibliotekę GTK 1.2.x i parser PHP 4, a na-
stępnie  rozpakować  archiwum  i  postępować  zgodnie  z  instrukcją  umieszczoną  w  pliku 
Readme.

Listing 3. 

Zmodyfikowany kod tworzący okienko

// zainicjowanie okienka

$window

 = &

new

 GtkWindow

()

// nadanie mu tytułu

$window

-

>

set_title

(

"Wake-On-Lan"

)

;

// ustalenie szerokości ramki okienka

$window

-

>

set_border_width

(

10

)

;

// wyłączenie możliwości skalowania okna: zmniejszania, zwiększania 
// i automatycznej minimalizacji do rozmiaru, przy którym widoczne są
// wszystkie jego elementy (każdy parametr może być true albo false)

$window

-

>

set_policy

(

false, false, false

)

;

// ustawienie szerokości okienka na 300 pikseli i wysokości na automatyczną

$window

-

>

set_usize

(

300, -1

)

;

// ustawienie okienka na środku ekranu (bez względu na rozdzielczość)

$window

-

>

set_position

(

GTK_WIN_POS_CENTER

)

// skojarzenie akcji zamknięcia okienka z wywołaniem funkcji 
// shutdown(), która uruchamia instrukcję gtk::quit()

$window

-

>

connect

(

"destroy"

"shutdown"

)

;

background image

Projekty

PHP-GTK

PHP Solutions Nr 2/2005

www.phpsolmag.org

5

niujemy zdarzenia (było już o tej techni-
ce)  na  wypadek  wybrania  wiersza  oraz 
usunięcia  jego  zaznaczenia.  Oba  zda-
rzenia  obsłuży  callback 

add _ to _ en-

trybox()

,  wpisujący  wybraną  z  listy  po-

zycję do pola adresowego. To, co zrobi-
liśmy zawierają Listingi 6 i 7.

Z  obiektów  widocznych  pozostaną 

nam jeszcze trzy przyciski – ObudźZa-
mknij
,  Wyczyść  listę.  Każdy  z  nich  sta-
nowi obiekt 

GtkButton

. Do dwóch z nich 

będziemy  chcieli  dodać  skróty  klawiszo-
we  –  w  tym  celu  utworzymy  obiekt  kla-
sy 

GtkAccelGroup

,  który  będzie  je  prze-

chowywał: 

$keys = &new GtkAccelGroup();

Zaczniemy  od  przycisku  Zamknij.  Two-
rzymy  go,  ustawiając  jednocześnie  na-
pis, który ma się na nim znaleźć. Następ-
nie  ustalamy,  że  po  naciśnięciu  (emituje 
wtedy  sygnał 

clicked

)  przycisk  ma  wy-

woływać  przerywającą  działanie  progra-
mu funkcję 

shutdown()

. Chcemy też, aby 

użytkownik  mógł  zrobić  to  samo  wciska-
jąc klawisz [Escape] – nic trudnego, moż-
na  skojarzyć  z  przyciskiem  skrót  klawi-
szowy, używając metody 

add _ accelera-

tor()

 (Listing 8).

Przejdźmy  teraz  do  przycisku  Wy-

czyść  listę.  Tworzymy  obiekt  typu 

Gtk-

Button

,  nazywając  go 

$btnClear

  i  łączy-

my  jego  wciśnięcie  z  wywołaniem  funk-
cji 

clearlist()

, która usuwa historię wpi-

sywanych  adresów  –  zarówno  z  obiek-
tu  listy 

$clist

,  jak  i  zmiennej  tablicowej 

$macs

.  Wynik  naszych  działań  przedsta-

wiamy na Listingu 9.

Zdefiniujemy  teraz  przycisk  Obudź, 

który  będzie  wywoływał  aplikację  ze-
wnętrzną  Wake-On-Lan.  Nazwiemy  go 

$btnWake

  (Listing  10).  Ponieważ  czyn-

ność  przez  niego  powodowana  jest  naj-
ważniejsza  w  całej  aplikacji,  dobrze  by 
było, gdyby użytkownik mógł ją wywołać 
klawiszem. A nawet jednym z dwóch kla-
wiszy – niech będą to [Enter] – na klawia-

turze głównej i numerycznej. Wiemy już, 
jak przypisać skrót klawiszowy: wystarczy 
wywołać  funkcję 

add _ accelerator()

.  Tu 

zrobimy to dwukrotnie. 

Pamiętajmy,  że  uruchomienie  tej 

aplikacji to ostatnia czynność – najpierw 
trzeba  odczytać  adres  z  pola  adreso-
wego (

$macaddress

) i (przy pomocy wy-

rażeń  regularnych)  sprawdzić  jego  po-
prawność.  Jeśli  został  wprowadzony 
prawidłowo,  nasz  interfejs  wywoła  apli-
kację, o której mowa. Jeśli nie – oczom 
użytkownika ukaże się okienko informu-
jące go o błędzie, a okno aplikacji zosta-
nie  schowane.  Jak  to  wykonamy?  Jak 
już  wiemy,  wciśnięcie  przycisku  gene-
ruje sygnał 

clicked

. Połączymy go więc 

z funkcją 

checkvalidity()

, którą dopiero 

utworzymy.  Zawrzemy  w  niej  wszystkie 
powyższe  czynności  sprawdzające  (Li-
sting 11). Należy nadmienić, że tym ra-

Pierwszy test

Przed skorzystaniem z funkcji i metod tego rozszerzenia powinniśmy zadbać o jeszcze 

jeden mały drobiazg. Aby mieć pewność, że rozszerzenie zostało załadowane, napisze-

my kilka instrukcji, które to sprawdzą oraz w razie potrzeby załadują rozszerzenie.

Do  sprawdzenia,  czy  rozszerzenie  jest  dostępne  wykorzystajmy  funkcję 

exten-

sion _ loaded()

, podając jej jako parametr ciąg 

gtk

. Funkcja ta zwróci wartość logiczną 

TRUE

 lub 

FALSE

. Gdy okaże się, że rozszerzenia brakuje, użyjemy funkcji 

dl()

, aby je za-

ładować. W systemach uniksowych rozszerzenie pliku z wykorzystywaną przez nas bi-

blioteką to .so, natomiast w Windows jest to .dll. Aby uniezależnić się od systemu ope-

racyjnego, możemy w funkcji 

dl(),

 zamiast wpisywania rozszerzenia pliku, użyć stałej 

PHP _ SHLIB _ SUFFIX

, która przechowuje odpowiednie rozszerzenie. Kod ładujący roz-

szerzenie powinien znaleźć się na samym początku pliku (Listing 2). 

Listing 7. 

Kod funkcji add_to_entrybox()

function

 add_to_entrybox

(

$clist

){

  

global

 

$macaddress

;

 

 // metoda set_text() wpisuje treść do pola tekstowego, a get_text() –

 

 // pobiera tekst wybranej z listy $clist pozycji o numerze

 

 // przechowywanym przez atrybut tej listy – tablicę selection (lista

 

 // wszystkich wybranych pozycji) pod indeksem 0 

  

$macaddress

-

>

set_text

(

@$clist

-

>

get_text

(

$clist

-

>

selection

[

0

]

, 0

))

;

}

Listing 6. 

Utworzenie listy przechowującej adresy 

// w konstruktorze określamy: liczbę kolumn listy 

(

parametr 1.

)

// i tablicę zawierającą nagłówki kolejnych kolumn (parametr 2.)

$clist

 = &

new

 GtkCList

(

1, 

array

(

"Ostatnio wywołane:"

))

;

// ustawienie wybierania tylko jednej pozycji na liście

$clist

-

>

set_selection_mode

(

GTK_SELECTION_BROWSE

)

;

// szerokość automatyczna, wg rozmiaru okna (-1), wysokość 200 pikseli

$clist

-

>

set_usize

(

-1, 200

)

;

// zaznaczenie elementu na liście wysyła sygnał select_row
// i wywołuje funkcję add_to_entrybox()

$clist

-

>

connect

(

"select-row"

"add_to_entrybox"

)

;

// usunięcie zaznaczenia elementu wysyła sygnał unselect_row
// i wywołuje funkcję add_to_entrybox()

$clist

-

>

connect

(

"unselect-row"

"add_to_entrybox"

)

;

Listing 5. 

Tworzenie etykiety – obiektu klasy GtkLabel i pola tekstowego 

(GtkEntry)

// utworzenie obiektu etykiety i przekazanie napisu przez konstruktor

$label

 = &

new

 GtkLabel

(

"Adresy MAC:"

)

;

// dokładne wyrównanie tekstu

$label

-

>

set_justify

(

GTK_JUSTIFY_FILL

)

;

// utworzenie obiektu pola tekstowego

$macaddress

 = &

new

 GtkEntry

()

;

// ustawienie możliwości pisania tekstu (true – można, false – nie)

$macaddress

-

>

set_editable

(

TRUE

)

;

Listing 4. 

Kod funkcji shutdown()

function

 shutdown

(

){

   

print

(

"Zamykanie programu.

\n

"

)

;

   gtk::main_quit

()

;

}

background image

PHP-GTK

Projekty

PHP Solutions Nr 2/2005

www.phpsolmag.org

6

zem nie tylko powiązaliśmy sygnał z cal-
lbackiem
, ale również przekazaliśmy do 
niego  odniesienie  do  obiektu 

$macad-

dress

Natomiast  będąc  przy  funkcji 

check-

validity()

, zwróćmy uwagę na trzy rze-

czy.  Pierwszą  i  najważniejszą  jest  wy-
wołanie  uruchamiającej  aplikację  ze-
wnętrzną  Wake-On-Lan  funkcji 

wake()

 

w  przypadku,  gdy  adres  jest  poprawny. 
Druga  dotyczy  użycia  będącej  kontene-
rem  i  obiektem  niewidocznym  dla  użyt-
kownika  tabeli  porządkującej  elementy 
(obiekt  klasy 

GtkTable

).  Po  jej  utworze-

niu  i  przypisaniu  do  okienka  dodajemy 
do niej elementy, które mają się w oknie 
ukazać,  określając  położenie  każdego 
z  nich  (szczegóły  w  Ramce  Rozmiesz-
czenie  elementów  w  tabeli
).  Jest  to  cał-
kiem  wygodny  sposób  organizowania 
widgetów.  Trzecią  sprawą,  której  należy 

poświęcić  trochę  uwagi  jest  wywołanie 
przedstawionej  na  tym  samym  Listingu 
funkcji 

warnclick()

. Zamyka ona dowolne 

okienko przekazane jej przez parametr – 
w tym przypadku, jest to okno z komuni-
katem o błędzie. 

Można  też  zrobić,  aby  przycisk 

Obudź był niedostępny (i nie dało się na 
niego  kliknąć),  gdy  pole  adresowe  jest 
puste.  Tylko  po  co?  Czy  nie  wystarczy 
potraktowanie pustego pola 

$macaddress

 

jako  błędnie  wprowadzonego  MAC-a? 
Byłoby  to  poprawne,  ale  znacznie  mniej 
eleganckie.  Jak  to  wykonać?  Program 
musi  w  jakiś  sposób  sprawdzać,  że  po-
le 

$macaddress

 nie jest puste i modyfiko-

wać właściwości przycisku Obudź. Zmia-
ny  w  polu  tekstowym  generują  sygnał 

changed

 – trzeba go więc połączyć z od-

powiednią funkcją, która będzie włączać 
lub wyłączać przycisk 

$btnWake

 i gotowe! 

Wymaga to drobnej modyfikacji we frag-
mencie kodu tworzącego pole adresowe 

$macaddress

 (dodanie połączenia sygna-

łu)  i  utworzenia  funkcji 

check _ length()

Wdrożenie  tego  pomysłu  widać  na  Li-
stingu 12.

Utworzymy  teraz  funkcję 

wake()

.  Jej 

kod  widnieje  na  Listingu  13.  Pisaliśmy 
już,  iż  spełnia  ona  najważniejszą  w  ca-
łym programie rolę, którą jest wywołanie 
aplikacji  Wake-On-Lan.  Wspomnijmy,  iż 
używa ona do tego wbudowanej do PHP 
funkcji 

system()

.  Przedtem  jednak  prze-

Rozmieszczenie elementów w tabeli

Ostatnie cztery parametry metody 

attach()

 obiektu klasy 

GtkTable

 określają pozycję, 

w której ma być umieszczony element. Pierwsze dwa z nich określają pozycje w pozio-

mie, kolejne dwa – w pionie. Każda para określa zasięg “od-do” między krawędziami ko-

lumn i wierszy (po 2 krawędzie na każdy wiersz i tyle samo na każdą kolumnę). 

Przykład z naszej aplikacji: chcemy umieścić element 

$label

 w jednej komórce znaj-

dującej się w pierwszym wierszu tabeli o pięciu wierszach i trzech kolumnach.

$table->attach($label, 0, 1, 0, 1);

Można to opisać w następujący sposób: “element 

$label

 umieścimy w tabeli 

$table

 mię-

dzy 0. i 1. krawędzią w poziomie i między 0. i 1. krawędzią w pionie”. Okno, którego frag-
mentem jest nasz przykład przedstawiamy na Rysunku 3. Jest to układ widgetów naszego 
interfejsu z Rysunku 2, na który dodatkowo nanosimy siatkę tabeli. Widoczne tam wąskie 
odstępy między kolumnami i wersami są traktowane tak samo, jak inne kolumny i wersy.

Rysunek 3. 

Numeracja krawędzi tabeli

Listing 10. 

Kod tworzący przycisk „Obudź”

// stworzenie nowego przycisku Obudź, wywołującego aplikację Wake-On-Lan

$btnWake

 = &

new

 GtkButton

(

"Obudź"

)

;

// przypisanie 1. skrótu klawiszowego (Enter na klawiaturze głównej)

$btnWake

-

>

add_accelerator

(

"clicked"

$keys

,GDK_KEY_Return,GDK_MOD2_MASK,0

)

;

// przypisanie 2. skrótu (Enter na klawiaturze numerycznej)

$btnWake

-

>

add_accelerator

(

"clicked"

$keys

,GDK_KEY_KP_Enter,GDK_MOD2_MASK,0

)

;

// połączenie wciśnięcia przycisku z funkcją checkvalidity() i przekazanie 
// do niej odniesienia do pola $macaddress

$btnWake

-

>

connect

(

"clicked"

"checkvalidity"

$macaddress

)

;

$btnWake

-

>

set_sensitive

(

FALSE

)

;

Listing 9. 

Kod tworzący przycisk czyszczący listę oraz funkcje clearlist()

// utworzenie przycisku 

$btnClear

 i nadanie mu etykiety Wyczyść 

list

ę

$btnClear

 = &

new

 GtkButton

(

"Wyczyść listę"

)

;

// połączenie wciśnięcia $btnClear z funkcją clearlist()

$btnClear

-

>

connect

(

"clicked"

"clearlist"

)

;

function

 clearlist

(

){

  

global

 

$clist

$macs

;

  

$clist

-

>

clear

()

;

  

$macs

 = 

array

()

;

}

Listing 8. 

Przyciski 

// utworzenie przycisku 

$btnAbort

 z etykietą Zamknij

$btnAbort

 = &

new

 GtkButton

(

"Zamknij"

)

;

// Przypisanie skrótu klawiszowego do przycisku $btnAbort (Zamknij). Parametry
// to po kolei: sygnał emitowany przez przycisk po naciśnięciu, nazwa obiektu 
// klasy GtkAccelGroup, kod klawisza (kody są w plikach źródłowych PHP-GTK:
// ext/gtk+/php_gdk.c), maska klawiszy-modyfikatorów (alt,shift,ctrl – tu
// żadnego nie używamy). Ostatni parametr (wartość 0) nie jest używany.

$btnAbort

-

>

add_accelerator

(

"clicked"

$keys

,GDK_KEY_Escape,GDK_MOD2_MASK,0

)

;

// skojarzenie przycisku z funkcją shutdown()

$btnAbort

-

>

connect

(

"clicked"

"shutdown"

)

;

background image

Projekty

PHP-GTK

PHP Solutions Nr 2/2005

www.phpsolmag.org

7

wana  w  pliku,  gdy  tylko  wyłączamy  nasz 
interfejs  i  automatycznie  z  niego  łado-
wana,  gdy  go  znów  uruchamiamy.  Stwo-
rzymy  więc  w  tym  celu  funkcje: 

write _

list()

,  która  będzie  zapisywać  dane 

loadlist()

, która będzie je odczytywać. 

Pierwszą rzeczą, która przychodzi na 

myśl,  jest  wybór  metody  zapisu  i  odczy-
tu.  Nasza  lista  adresów  (zmienna 

$macs

jest tablicą, więc ma swoją strukturę. Aby 
ją  bezproblemowo  zachować,  a  potem 
odtworzyć,  użyjemy  funkcji 

serialize()

 

unserialize()

. Poddają one dane seria-

lizacji i deserializacji.

Listing 13. 

Kod funkcji wake()

function

 wake

(

$address

){

 

 // zamiana liter w adresie na 

 

 // wielkie i dodanie znaku końca

 

 // linii (CR), niezbędnego do 

 

 // uruchomienia aplikacji WOL

  

$address

=

strtoupper

(

$address

)

.

    

"

\n

"

;

 

 // dodanie adresu do historii

  add_to_list

(

$address

)

;

 

 // wywołanie aplikacji WOL

  system

(

"wakeonlan "

 . 

$address

)

;

}

Listing 12. 

Kod funkcji check_

length() i połączenia sygnału 

changed 

function

 check_length

(

$inputfield

){

  

global

 

$btnWake

;

 

 // sprawdzanie, czy w polu 

 

 // tekstowym ($inputfield) jest

 

 // tekst (długość >0). Pobieramy

 

 // go metodą get_text()

  

if

 

(

strlen

(

    

$inputfield

-

>

get_text

())

 

>

 0

){

   

 // jeśli tak, ustawiamy

   

 // przycisk Obudź na aktywny

    

$btnWake

-

>

set_sensitive

(

TRUE

)

;

  

}

 

else

{

   

 // jeśli nie, ustawiamy

   

 // Obudź na nieaktywny

    

$btnWake

-

>

set_sensitive

(

      FALSE

)

;

  

}

}

// połączenie dokonywania zmian
// w polu $macaddress z wywołaniem
// funkcji check_length

$macaddress

-

>

connect

(

"changed"

  

"check_length"

)

;

Listing 11. 

Kody funkcji checkvalidity() i warnclick()

function

 checkvalidity

(

$button

$entry

){

  

global

 

$window

;

 

 // odczytanie adresu MAC z pola adresowego

  

$address

 = 

$entry

-

>

get_text

()

;

 

 // zamiana myślników w adresie na dwukropki

  

$address

 = 

str_replace

(

"-"

 ,

":"

$address

)

;

 

 // sprawdzenie poprawności adresu przy użyciu wyrażeń regularnych

  

if

 

(

preg_match

(

"/^[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]

    {2}:[0-9a-f]{2}:[0-9a-f]{2}

$

\b

/i"

trim

(

$address

))){

   

 // jeśli jest poprawny, wywołujemy funkcję wake() (uruchamia aplikację WOL)

    wake

(

trim

(

$address

))

;

  

}

  

else

{

   

 // jeżeli MAC jest niepoprawny, to:

   

 // ukrywamy okienka aplikacji

    

$window

-

>

hide

()

;

   

 // tworzymy okienko $warnwindow, w którym będzie ostrzeżenie

    

$warnwindow

 = &

new

 GtkWindow

()

;

   

 // ustawiamy tytuł okienka

    

$warnwindow

-

>

set_title

(

"WOL: Błąd"

)

;

   

 // ustawiamy margines okienka

    

$warnwindow

-

>

set_border_width

(

10

)

;

   

 // ustawiamy skalowalność okienka

    

$warnwindow

-

>

set_policy

(

true, false, false

)

;

   

 // ustawiamy pozycję okienka (pośrodku ekranu)

    

$warnwindow

-

>

set_position

(

GTK_WIN_POS_CENTER

)

;

   

 // ustawiamy rozmiar okienka (szerokość automatyczna, wysokość 80)

    

$warnwindow

-

>

set_usize

(

-1, 80

)

;

   

 // tworzymy tabelę porządkującą i ustalamy liczbę wersów (2) i kolumn (3)

    

$tab2

 = &

new

 GtkTable

(

2, 3

)

;

   

 // tworzymy etykietę zawierającą komunikat o błędzie

    

$errormsg

 = &

new

 GtkLabel

(

"Format wprowadzanego adresu MAC jest

       nieprawidłowy !"

)

   

 // włączamy zawijanie tekstu (ang. wrapping) w tej etykiecie 

    

$errormsg

-

>

set_line_wrap

(

true

)

;

   

 // definiujemy przycisk OK i łączymy go z funkcją warnclick() zamykającą 

   

 // okienko komunikatu i przywracającą okno aplikacji

    

$btnok

 = &

new

 GtkButton

(

"OK"

)

;

    

$btnok

-

>

connect

(

"clicked"

"warnclick"

, &

$warnwindow

)

;

   

 // przypisanie tabeli porządkującej do obiektu okienka

    

$warnwindow

-

>

add

(

$tab2

)

;

   

 // wstawienie etykiety i przycisku do tabeli porządkującej

    

$tab2

-

>

attach

(

$errormsg

, 0, 5, 0, 1

)

;

    

$tab2

-

>

attach

(

$btnok

, 2, 3, 2, 3

)

;

   

 // pokazanie okienka i wszystkich jego elementów 

    

$warnwindow

-

>

show_all

()

;

  

}

}

// funkcja zamykająca dowolne okienko i przywracającą okno główne

function

 warnclick

(

$button

$win

){

    

global

 

$window

;

   

 // zamknięcie (zniszczenie) okienka przekazanego przez parametr

    

$win

-

>

destroy

()

;

   

 // ukazanie okna głównego aplikacji

    

$window

-

>

show

()

;

}

prowadza  jeszcze  dwie  czynności  –  za-
mienia wszystkie litery w adresie na wiel-
kie  (ze  względów  estetycznych)  i  dodaje 
adres do historii (stąd się ona bierze) przy 
użyciu  funkcji 

add _ to _ list()

.  Funkcja 

dodaje  adres  zawsze  na  początku  listy 
(jako najnowszy). Najpierw sprawdza, czy 
dodawany MAC istnieje już w historii i do-

pisuje go tylko, jeśli nie. Pamiętajmy też, 
że nie możemy przekroczyć maksymalnej 
liczby obiektów na liście (10) – gdyby mia-
ło to nastąpić, to najstarszy adres zosta-
nie usunięty. Kod 

add _ to _ list()

 przed-

stawiliśmy na Listingu 14.

Jak  już  wcześniej  wspomnieliśmy, 

chcemy, aby historia adresów była zapisy-

background image

PHP-GTK

Projekty

PHP Solutions Nr 2/2005

www.phpsolmag.org

8

Pierwszy  z  tych  procesów  przetwa-

rza  całą  tablicę  (dane  i  ich  strukturę) 
na  formę,  którą  można  zapisać  w  pli-
ku,  a  drugi  jest  jego  odwrotnością.  Wy-
korzystamy  więc 

serialize()

  w  funkcji 

write _ list()

  i 

unserialize()

  w 

load-

list()

.  Obie  funkcje  zostały  przedsta-

wione na Listingu 15.

Teraz pora na implementację auto-

matycznego  ładowania  listy  przy  uru-

Listing 14. 

Kod funkcji add_to_list()

function

 add_to_list

(

$address

){

  

global

 

$macs

$clist

;

 

 // oczyszczenie adresu ze znaków takich jak spacje i entery 

  

$address

 = 

trim

(

$address

)

;

 

 // zmienna określająca, czy adres znajduje się na liście (TRUE)

 

 // czy nie (FALSE). Tu ustawiamy ją domyślnie na FALSE

  

$exists

 = FALSE;

 

 // tablica tymczasowa, do której przenosimy adresy, jeżeli lista

 

 // jest już pełna i trzeba usunąć najstarszy element

  

$temp

 = 

array

()

;

 

 // pętla sprawdzająca, czy dodawany adres jest już na liście

  

foreach

(

$macs

 AS 

$addr

){

     

 // jeśli adres został znaleziony, to ustawiamy $exists na TRUE

      

if

 

(

$addr

 === 

$address

){

          

$exists

 = TRUE;

      

}

  

}

   

 // po zakończeniu pętli: jeśli funkcja nie znalazła dodawanego

   

 // adresu na liście, to:

    

if

 

(

!

$exists

){

       

 // jeżeli historia ma maksymalną zdefiniowaną liczbę linii (10)

        

if

 

(

count

(

$macs

)

 == MAX_LINES

){

           

 // to tworzymy tablicę tymczasową $temp i w pętli foreach 

            

$temp

 = 

array

()

;

           

 // przenosimy do niej wszystkie adresy oprócz najstarszego 

           

 // ze zmiennej $macs

            

foreach

 

(

$macs

 AS 

$key

 =

>

 

$value

){

                

if

 

(

$key

 

<

 

(

MAX_LINES

)

 && 

(

$key

 

>

 0

)){

                    

$temp

[

$key

-1

]

 = 

$value

;

                

}

            

}

           

 // po czym dodajemy do niej ($temp) nasz nowy adres ($address)

            

$temp

[]

 = 

$address

;

           

 // i przenosimy jej zawartość z powrotem do tablicy $macs

            

$macs

 = 

$temp

;

       

 // jeżeli historia jest krótsza niż 10 pozycji

        

}

 

else

{

           

 // to zwyczajnie dopisujemy do niej nowy adres

            

$macs

[]

 = 

$address

;

        

}

       

 // sortujemy tablicę $macs

        ksort

(

$macs

)

;

       

 // czyścimy zawartość listy $clist

        

$clist

-

>

clear

()

;

       

 // usuwamy zmienną $temp

        

unset

(

$temp

)

;

       

 // przenosimy zawartość tablicy $macs do listy $clist

        

foreach

 

(

$macs

 AS 

$addr

){

            

$clist

-

>

prepend

(

array

(

$addr

))

;

        

}

    

}

}

chamianiu  programu  i  jej  zapisywa-
nia  przy  jego  zamykaniu.  W  pierw-
szym przypadku, wstawimy odwołanie 
do funkcji 

loadlist()

 w części głównej 

programu,  tuż  przed  instrukcją 

gtk::

main()

.  W  drugim  umieścimy  wywoła-

nie 

write _ list()

  wewnątrz  napisa-

nej  wcześniej  funkcji 

shutdown()

,  któ-

rą lekko zmienimy, co widać na Listin-
gu 16.

Układanka

Najwyższy  czas  na  rozmieszczenie 
wszystkich  elementów  w  obrębie  okien-
ka aplikacji. Musimy tylko zadbać o jeden 
drobiazg – nasza lista 

$clist

 nie jest, nie-

stety, z definicji listą przewijalną. Dostęp-
ne na niej są tylko te elementy, które są 
widoczne na ekranie – reszty nie można 
nijak z niej wybrać. 

Istnieje jednak proste rozwiązanie te-

go  problemu  –  biblioteka  PHP-GTK  dys-
ponuje  klasą 

GtkScrolledWindow

,  która 

definiuje okienko przewijalne ze znanymi 
wszystkim paskami. Umieszczenie naszej 
listy  w  tym  okienku  (które  zostanie  po-
traktowane  jako  kontener)  umożliwi  nam 
więc  jej  przewijanie.  Stworzymy  obiekt 
o nazwie 

$scwindow

 i ustalimy, że okienko 

ma być przewijalne tylko w pionie, a pa-
sek przewijania – pojawiać się tylko wte-
dy, gdy jest potrzebny (czyli, gdy jest wy-
starczająco dużo pozycji). Rozwiązanie to 
przedstawiliśmy na Listingu 17.

Przejdziemy  teraz  do  finalizacji  na-

szej  układanki  –  ułożymy  widgety 
w  oknie  głównym  aplikacji.  Podobnie, 
jak  w  przypadku  okienka  informujące-
go o błędzie, także tutaj użyjemy do te-
go  tabeli 

GtkTable

.  Nadamy  jej  4  wersy 

i 2 kolumny, przypiszemy do nich widge-
ty,  po  czym  dodamy  skróty  klawiszowe 
oraz  instrukcję,  o  której  wspominaliśmy 
na  samym  początku  – 

$window->show _

all()

, która wyświetla na ekranie okien-

ko  i  wszystkie  jego  elementy.  Widać  to 
na Listingu 18.

Tak  oto,  krok  po  kroku,  skompleto-

waliśmy  cały  interfejs  programu  Wake-
On-Lan
.

Uruchomienie aplikacji

Spróbujmy  teraz  uruchomić  naszą  apli-
kację pod systemem Linux. Jak już wspo-
mnieliśmy, wystarczy w konsoli systemo-
wej wpisać 

php  wolgui.php

 (przy założe-

niu,  że  ścieżka  do  interpretera  PHP  jest 
zdefiniowana). Powinno ukazać się okien-
ko  podobne  do  tego  z  Rysunku  1.  Takie 
uruchamianie  programu  nie  należy  jed-
nak  do  najwygodniejszych  –  usprawnij-
my więc je trochę. Wystarczy, że w pierw-
szej linijce skryptu (jeszcze przed znacz-
nikiem 

<?php

)  umieścimy  odwołanie  do 

parsera  PHP,  jak  w  przykładzie: 

#!/usr/

local/bin/php -q 

Oczywiście, podana ścieżka dostępu 

jest  zależna  od  położenia  parsera  PHP 
na dysku i może być inna – sprawdzimy 
ją wydając polecenie 

whereis  php

 (jeśli 

background image

Projekty

PHP-GTK

PHP Solutions Nr 2/2005

www.phpsolmag.org

9

nic  nie  zwraca,  to  znaczy,  że  PHP  nie 
jest w ogóle zainstalowany!). Następnie, 
komendą 

chmod oug+x wolgui.php

 zmie-

nimy uprawnienia dostępu do pliku wol-
gui.php
. Od tej pory, aby uruchomić apli-
kację, wystarczy w wierszu poleceń wpi-
sać jej nazwę.

Co dalej z PHP-GTK

Zaprojektowanie  i  wykonanie  interfejsu 
opisanego w tym artykule dość dokład-

nie pokazuje ideę programowania z wy-
korzystaniem  PHP-GTK.  Oczywiście, 
możliwości  tego  rozszerzenia  są  du-
żo większe i nie sposób je tu wszystkie 
opisać.  Na  szczęście,  na  stronie  pro-
jektu,  pod  adresem  http://gtk.php.net/
manual/en/reference.php
 

dostępna 

jest  znakomita  dokumentacja  (niestety 
nie  w  języku  polskim).  Opisano  w  niej 
dokładnie  każdy  dostępny  widget  – 
wszystkie  jego  cechy,  metody  i  emito-

wane sygnały. Zachęcamy więc do lek-
tury tego podręcznika oraz nauki PHP-
GTK i jego wdrażania w swoich projek-
tach. n

Listing 16. 

Zmieniony kod funkcji shutdown()

function

 shutdown

(

){

  

print

(

"Zamykanie programu.

\n

"

)

;

 

 // serializacja listy i zapis do pliku

  write_list

()

;

 

 // przerwanie pętli głównej programu

  gtk::main_quit

()

;

Listing 15. 

Kody funkcji write_list() i loadlist()

function

 write_list

(

){

    

global

 

$macs

;

   

 // otwarcie pliku list.dat do zapisu (w)

    

$fp

 = 

fopen

(

"list.dat"

"w"

)

;

   

 // serializacja (serialize()) i zapisanie (fputs()) danych w pliku

    

fputs

(

$fp

, serialize

(

$macs

))

;

   

 // zamknięcie pliku

    

fclose

(

$fp

)

;

}

function

 loadlist

(

){

    

global

 

$clist

$macs

;

   

 // sprawdzenie, czy istnieje plik list.dat

    

if

 

(

file_exists

(

"list.dat"

)){

   

 // jeśli tak, to czy da się go otworzyć do odczytu

        

if

 

(

$fp

 = 

fopen

(

"list.dat"

"r"

)){

          

 // gdy jest otwarty, to odczytujemy go w pętli while linia po linii

            

while

 

(

!

feof

(

$fp

)){

                

$fline

 .= 

fgets

(

$fp

, 1024

)

;

            

}

           

 // po czym dane są deserializowane, czyli zamieniane na zwykłą

           

 // tablicę $macs 

            

$macs

 = unserialize

(

trim

(

$fline

))

;

        

}

       

 // zamknięcie pliku

        

fclose

(

$fp

)

;

    

}

   

 // wypełnienie listy $clist wartościami z $macs

    

foreach

(

$macs

 AS 

$value

){

        

$clist

-

>

prepend

(

array

(

$value

))

;

    

}

}

Listing 18. 

Kod tworzący tabelę 

i umieszczający w niej widgety

// utworzenie obiektu tabeli 

$table

$table

 = &

new

 GtkTable

(

4, 2

)

;

// odstępy między rzędami 
// (wersami) tabeli

$table

-

>

set_row_spacings

(

5

)

;

// odstępy między kolumnami tabeli

$table

-

>

set_col_spacings

(

5

)

;

// dodanie skrótów klawiszowych

$window

-

>

add_accel_group

(

$keys

)

;

// umieszczenie tabeli w oknie

$window

-

>

add

(

$table

)

;

// ustawienie w tabeli widgetów

$table

-

>

attach

(

$label

,

  0, 1, 0, 1

)

;

$table

-

>

attach

(

$macaddress

,

  2, 3, 0, 1

)

;

$table

-

>

attach

(

$scwindow

,

  0, 3, 4, 5

)

;

$table

-

>

attach

(

$btnClear

,

  0, 1, 6, 7

)

;

$table

-

>

attach

(

$btnAbort

,

  0, 1, 8, 9

)

;

$table

-

>

attach

(

$btnWake

,

  2, 3, 8, 9

)

;

// wyświetlenie na ekranie okienka 
// i jego wszystkich elementów

$window

-

>

show_all

()

;

Listing 17. 

Kod tworzący okno klasy 

GtkScrolledWindow

// utworzenie okienka przewijalnego

$scwindow

=&

new

 GtkScrolledWindow

()

;

// przewijalność okna: pozioma
// (wyłączona) i pionowa (automa-
// tyczna, włączana zależnie od 
// rozmiaru zawartości)

$scwindow

-

>

set_policy

(

  GTK_POLICY_NEVER,
  GTK_POLICY_AUTOMATIC

)

;

// dodanie do okienka listy $clist

$scwindow

-

>

add

(

$clist

)

;