background image

PROGRAMOWANIE OBIEKTOWE W C++

LABORATORIUM 7

BIBLIOTEKA GTK+/GTKMM 

GTK+ jest darmową (GNU LGPL), międzyplatformową biblioteką służącą do tworzenia GUI 

(Graphical User Interface). Pierwotnie została napisana w języku C, lecz obecnie istnieją wersje przeznaczone 
dla innych języków (np. Python, Perl). Zastosowano ją w wielu aplikacjach, np.: GIMP, gnome (domyślne 
środowisko graficzne wielu dystrybucji linuxa), Inkscape, Chromium.

Międzyplatformowość biblioteki oznacza, że przygotowana aplikacja będzie działała niezależnie od 

systemu operacyjnego, pod którym program jest kompilowany. Jest to istotna zaleta względem na przykład 
WinAPI, działającego wyłącznie pod Windowsem. Istnieją również inne biblioteki pełniące te same funkcje co 
GTK+, np. Qt, czy wxWidgets i trudno jednoznacznie wskazać najlepszą spośród wymienionych.

W trakcie zajęć wykorzystano bibliotekę gtkmm, która stanowi „opakowanie” GTK+ do postaci 

obiektowej w języku C++. Interfejs użytkownika (GUI) będzie tworzony w trakcie zajęć przez wpisywanie 
komendy „z palca”, jednak wygodniejszą formą jest korzystanie z kreatora – Glade.

Poniższa instrukcja oparta jest w znacznej części na podręczniku Cumming M.i in. Programming 

with gtkmm 2. dostępnego na stronie 

http://developer.gnome.org/gtkmm-tutorial/2.24

.

1. Stwórz pierwszy program tworzący puste okienko. Kod znajduje się poniżej:

#include <gtkmm.h>

 //dołączenie plików nagłówkowych gtkmmm

int main(int argc, char* argv[])
{

Gtk::Main kit(argc, argv); //inicjalizacja biblioteki 
Gtk::Window window;

 //stworzenie obiektu window klasy Gtk::Window

Gtk::Main::run(window);

 //wyświetlenie obiektu window

return 0;

}

Powyższy przykład powinien wygenerować puste okno o wymiarach 200x200px. W pierwszej linii zawarto 
instrukcje służące inicjalizacji biblioteki. Dalej, tworzony jest obiekt klasy 

Gtk::Window

, która jest 

podstawową jednostką odpowiedzialną za okno. Instrukcja 

Gtk::Main::run(window)

 wyświetla obiekt 

window

 i uruchamia właściwe działanie „okienek”. Proces ten kończy działanie w momencie zamknięcia okna 

window

2. Utwórz pustą klasę 

Okno

, która dziedziczy po klasie 

Gtk::Window

. Tworzona klasa będzie 

przechowywać główne okno programu.

W celu nadania nazwy (napis na górnym pasku) oknu programu należy wywołać metodę 

set_title(„napis”)

 na danym obiekcie.

3. Dodaj do istniejącego okna przycisk. Przycisk ma być składową klasy 

Okno

 i powinien zawierać napis 

„Hello world!”. Sprawdź jak wyglądają poszczególne typy przycisków w bibliotece GTK+.

Biblioteka GTK+ zawiera różne rodzaje przycisków:

Gtk::Button

Gtk::ToggleButton

Gtk::CheckButton

Gtk::RadioButton

Podstawowy klawisz z 
tekstem lub ikoną 
(naciśnij-puść)

Przełącznik 
dwupozycyjny (on/off)

Gtk::ToggleButton

 o 

innym wyglądzie

Klawisz występujący w 
grupach; stosowany gdy 
możliwe jest wybranie 
tylko jednej opcji z kilku 
podanych

Ustawienie tekstu wyświetlanego przez klawiszu można wykonać wołając konstruktor parametryczny

 

Gtk::Button(„napis”)

  lub metodę 

set_label(„napis”)

;

background image

Stworzony obiekt należy dodać do okna  ( 

Gtk::Window::add( Gtk::Button mbtn) 

) i następnie 

wyświetlić w tym oknie 

Gtk::Button::show()

. Zamiast ręcznie ustawiać wyświetlanie każdego obiektu 

wygodniej jest wyświetlić wszystkie za pomocą metody 

Gtk::Window::show_all_children()

4. Dodaj w klasie 

Okno

 metodę (slot), która w przypadku naciśnięcia na klawisz wypisze w konsoli 

komunikat „Nacisnieto klawisz”.

Biblioteka GTK+ oparta jest na zdarzeniach (event driven). Oznacza to, że program oczekuje na jakieś 
wydarzenie, np. naciśnięcie klawisza, zmianę stanu, i wówczas podejmuje określone działanie. Mówi się, że 
sygnał jest wysyłany (emitowany) do odbiornika (slotu). Klasa 

Gtk::Button

 posiada zaimplementowanych 

kilka sygnałów dostępnych przez akcesory (m.in.: 

signal_clicked()

reagujący na kliknięcie w dany klawisz).

Slotem jest zwyczajna funkcja lub metoda, która jest wykonywana, jeżeli określony sygnał zostanie 
wyemitowany. Przed rozpoczęciem pracy z GUI należy połączyć ze sobą sygnał i slot, służy do tego metoda 

connect()

 klasy reprezentującej sygnał. Argumentem metody 

connect()

 jest adres funkcji lub metody, która 

ma zostać wywołana, jednak „po drodze” konieczne jest wywołanie funkcji 

sigc::mem_fun

 (dla slotu – 

metody) lub 

sigc::fun_ptr

 (dla slotu – funkcji). Przykład:

void mojafunkcja();   //funkcja 
class Klasa
{

...
void metoda(); // metoda klasy
...

}

int main()
{

Gtk::Button btn(“Napis”);

btn.signal_clicked().connect( sigc::fun_ptr( &myfunction ) );
Klasa obj;
btn.signal_clicked().connect( sigc::mem_fun(obj, &Klasa::metoda );

}

W przypadku, gdy slotem ma być metoda klasy, pierwszym argumentem jest obiekt, na którym ma zostać 
wykonana dana metoda (tutaj 

obj

), natomiast drugim – adres tej metody (

&Klasa::metoda

). 

5. W głównym oknie programu stwórz i wyświetl drugi przycisk.

Biblioteka GTK+ przechowuje elementy w kontenerach: jedno- lub wieloelementowych. Przykładem kontenera 
zawierającego tylko jeden widget (element) jest 

Gtk::Button

Gtk::Window,Gtk::Frame

. Istnieje również 

wiele kontenerów przechowujących więcej niż jeden widget, kilka najważniejszych to:

Gtk::HBox, Gtk::VBox

Układ liniowy elementów, odpowiednio poziomo i pionowo

Gtk::Table

Tworzy macierz elementów

Gtk::Notebook

Kontener tworzący zakładki/karty

Aby dodać elementy do kontenera 

Gtk::HBox

 i 

Gtk::Vbox

 należy wywołać metodę 

pack_start(button) 

lub 

pack_end(button)

. Sprawdź czym się różnią te metody.

Należy pamiętać o dodaniu przynależności widżetu 

Gtk::Hbox/Gtk::Vbox

 do okna, w którym ma być 

wyświetlony – metoda 

Gtk::Window::add( .. )

6. Wyświetl w oknie trzeci klawisz w sposób jak na rysunku obok wykorzystując

kontener 

Gtk::Table

.

W celu dodania elementu do kontenera 

Gtk::Table

 wykorzystuje się metodę składową 

Gtk::Table::attach()

. Szczegóły dotyczące składni znajdują się w dokumentacji biblioteki oraz 

podręczniku użytkownika Programming with gtkmm 2 (rozdział 7.2.6. Table)

background image

7. Stwórz klasę 

Przycisk

 dziedziczącą po klasie 

Gtk::Button

, która ma dodatkowy atrybut 

mid

przechowujący cyfrę, którą reprezentuje dany klawisz.

8. Stwórz i wyświetl macierz 4x3 z układem przycisków jak na klawiaturze alfanumerycznej z 

wykorzystaniem klasy 

Przycisk

. Dodaj obsługę sygnałów tak, aby po naciśnięciu klawisza w konsoli 

wyświetlała się cyfra, którą przedstawia dany klawisz.

Biblioteka 

sigc++

 wykorzystana wewnątrz GTK+ ma możliwość tworzenia sygnałów wysyłających różne 

zmienne/obiekty. Przygotowane wcześniej połączenie sygnału nie przewidywało przekazywania argumentów do 
slotu. Aby umożliwić wysyłanie sygnału z argumentami, konieczne jest wykorzystanie funkcji 

sigc::bind

W przypadku wysyłania zmiennej całkowitej 

val

 po naciśnięciu klawisza 

mbtn

 postać jest następująca:

int main()
{
...
Klasa::metoda(int i);
Gtk::Button mbtn;
mbtn.signal_clicked().connect(sigc::bind<int>(sigc::mem_fun(obj,&Klasa::metoda),val)
...
}

9. W istniejącym oknie utwórz obiekt 

Gtk::Entry

, który po naciśnięciu klawisza wyświetli jego cyfrę.

Widget 

Gtk::Entry

 służy do wprowadzania tekstu, jednak może być wykorzystany również jako obiekt tylko 

do odczytu, na którym wyświetlany będzie napis. Podstawową rolę odgrywają tutaj dwie metody 

Gtk::Entry::set_text()

 oraz 

Gtk::Entry::get_text()

, służące odpowiednio do wyświetlenia 

podanego komunikatu oraz pobrania wyświetlanego napisu. W celu ustawienia widgetu tylko do odczytu służy 
metoda 

Gtk::Entry::set_editable(true/false)

.

10. Stwórz własny kalkulator

Specyfikacja:
- Kalkulator działa w sposób przyrostowy, tzn. wartość w lewej komórce jest dodawana, odejmowana, mnożona 
lub dzielona przez liczbę po prawej stronie. Wynik działania jest wyświetlany w lewej komórce, natomiast 
pozostałe są czyszczone.
- Wyodrębnić klasę odpowiadającą za obliczenia i wykorzystać mechanizm sygnałów w celu sterowania tą klasą.