Prosty program z obsługą zdarzeń w GTKmm
07.06.2012 00:32
Witam. Działam od niedawana na tym portalu (na razie niezbyt aktywnie na tymże koncie użytkownika) pod widoczną nazwą, która zadebiutowała na YouTube.com. Wpis ten będzie dotyczyć napisania prostego programu z obsługą zdarzeń w C++ z użyciem GTKmm 3 i nowszego. Ci, którzy znają GTK2 lub GTK3 powinni od razu skojarzyć potrzebne do wykonania kroki, tak więc do dzieła!
Co trzeba mieć, zanim rozpocznie się tworzenie?
- Działający kompilator C++ (g++) i zestaw programów instalowany wraz z dostępnym w Ubuntu pakietem build-essentials,
- Pliki nagłówkowe GTK i GTKmm (najłatwiej zainstalować je przez instalację pakietów z grupy GTK mające w nazwie „dev” lub „devel”, w zależności od używanej dystrybucji,
Należy jeszcze dorzucić program Anjuta (IDE ) oraz Glade, który posłuży do zaprojektowania interfejsu programu.
Tworzymy program
Łopatologiczny opis inicjalizacji projektu
Na początek uruchomimy Anjuta i wybierzemy opcję „Utwórz nowy projekt”.
Następnie wybieramy zakładkę „C++” i ikonę „GTKmm (prosty)”
Klikamy na „Kontynuuj” i uzupełniamy według uznania informacje o projekcie.
Po kliknięciu na „Kontynuuj” pokaże się okienko pozwalające na dostosowanie widocznych poniżej ustawień
Klikamy jeszcze raz na „Kontynuuj” i potwierdzamy informacje dotyczące naszego projektu
Wystarczy chwilę odczekać i ukaże się nam projekt gotowy do rozpoczęcia pracy na nim.
Projektujemy interfejs
W zakładce „Projekt” odnajdujemy folder „src” i pozycję „ui”. Klikamy 2 razy na wyświetloną pozycję.
Ukaże się następujący widok (pomijając pojawiające się ostrzeżenie)
Przy okazji widać, że po prawej stronie jest okienko „Widżety”, za pomocą którego można zmienić właściwości widżetów (w terminologii windowsowej „kontrolki”). Właśnie zmieniono tytuł okna głównego, co jest pierwszą rzeczą, którą trzeba zrobić.
Następnie wybieramy z palety kontener „Skrzynka”, klikamy na obszar okna (szary prostokąt) i ustawiamy liczbę elementów na 2. Robimy tak jeszcze raz dla każdego z elementów. Wewnętrznym elementom zmieniamy orientację na pionową.
Kontener posłuży jako miejsce, w którym zostaną umieszczone dwie etykietki oraz dwa liniowe pola tekstowe. Wybieramy z palety „Etykieta” (kliknięciem) i klikamy na jeden z górnych elementów. Tak samo robimy dla drugiego pola. Następnie wybieramy „Wejście tekstowe” i robimy tak samo, jak z etykietą, ale wstawimy do dolnych elementów.
Etykietom zmienimy tekst:
- na etapie projektowania, co się sprowadza do odnalezienia etykiet, w oknie „Widżety” właściwości „Etykieta” i wpisaniu swojego tekstu,
- na etapie kodzenia, co sprowadza się do wprowadzenia następującego kodu: [code=cpp] builder->get_widget("label1", et1); builder->get_widget("label2", et2); if(et1 && et2) { et1->set_text("Pole nr 1"); et2->set_text("Pole nr 2"); } [/code]
- Nie wolno zapomnieć o deklaracji wskaźników et1 i et2 na obiekt typu Gtk::Label, gdyż kompilacja nie powiedzie się.
Kodzimy!
Teraz część, na którą tak czekaliście... Bez zbędnego owijania w bawełnę zaczynamy od deklaracji dwóch wskaźników na obiekt Gtk::Entry, które nazwiemy według uznania. Powinno to wyglądać podobnie do poniższego fragmentu, który umieścimy bezpośrednio nad funkcją main(int argc, char *argv[]):
Gtk::Entry* wejscie; Gtk::Entry* wyjscie;
Następnie odnajdujemy linijkę
builder->get_widget("main_window",main_win);
i dopisujemy do niej dwie poniższe: [code=cpp] builder->get_widget("entry1",wejscie); builder->get_widget("entry2", wyjscie); [/code]
Skoro mamy już zaimportowane pola tekstowe, to czas na wykonanie operacji na nich. Za pomocą poniższego kodu przypiszemy zdarzenie (wciśnięcie klawisza ENTER) oraz uniemożliwimy wpisywanie tekstów z klawiatury do drugiego pola tekstowego.
if(wejscie && wyjscie) { wyjscie->set_editable(false); //wyłączamy możliwość edycji wejscie->signal_activate().connect(sigc::ptr_fun(&wprowadz_tekst)); }
Między deklaracją wskaźników na obiekt a funkcją main(int argc, char *argv[]) tworzymy funkcję wprowadz_tekst
void wprowadz_tekst() { wyjscie->set_text(wejscie->get_text()); }
Funkcja ta przepisuje tekst z pierwszego pola do drugiego po przypięciu do zdarzenia, czyli w naszym wypadku wciśnięcie ENTER pozwoli na wykonanie tej funkcji.
Kompilacja i uruchomienie
Zostaje wybrać pozycję „Budowanie › Zbuduj projekt” i czekać na koniec kompilacji. Jeśli nie będzie błędów, nie zostaną wyróżnione w okienku „Komunikaty” teksty na czerwono (zielony jest dla ostrzeżeń) i będzie można uruchomić program, który prezentuje się tak:
Kiedy zamkniemy okno programu, pojawi się w konsoli (okno na dole)
Program exited successfully with errcode (0) Press the Enter key to close this terminal ...
Naciśnięcie klawisza ENTER spowoduje całkowite wyłączenie programu.
Kod referencyjny (main.cc)
#include <gtkmm.h> #include <iostream> #include "config.h" #ifdef ENABLE_NLS # include <libintl.h> #endif /* For testing propose use the local (not installed) ui file */ /* #define UI_FILE PACKAGE_DATA_DIR"/ui/projekt.ui" */ #define UI_FILE "src/projekt.ui" Gtk::Entry* pole1=0; Gtk::Entry* pole2=0; Gtk::Label* et1=0; Gtk::Label* et2=0; void enter_text() { pole2->set_text(pole1->get_text()); } int main (int argc, char *argv[]) { Gtk::Main kit(argc, argv); //Load the Glade file and instiate its widgets: Glib::RefPtr<Gtk::Builder> builder; try { builder = Gtk::Builder::create_from_file(UI_FILE); } catch (const Glib::FileError & ex) { std::cerr << ex.what() << std::endl; return 1; } Gtk::Window* main_win = 0; builder->get_widget("main_window", main_win); builder->get_widget("entry1", pole1); builder->get_widget("entry2", pole2); builder->get_widget("label1", et1); builder->get_widget("label2", et2); if(et1 && et2) { et1->set_text("Pole nr 1"); et2->set_text("Pole nr 2"); } if(pole1 && pole2) { pole2->set_editable (false); pole1->signal_activate().connect(sigc::ptr_fun(&wprowadz_tekst)); } if (main_win) { kit.run(*main_win); } return 0; }
Podsumowanie
Ten wpis ma przybliżyć podstawy tworzenia programów obsługujących zdarzenia napisanych z użyciem GTKmm. Zainteresowanych odsyłam do Dokumentacji GTKmm i zachęcam do eksperymentów, nawet jeśli kończyłyby się porażką. W następnych wpisach zostaną pokazane ciekawsze przykłady :D