Blog (9)
Komentarze (7)
Recenzje (0)
@skrzeczol755Prosty program z obsługą zdarzeń w GTKmm

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”.

Utwórz nowy projekt
Utwórz nowy projekt

Następnie wybieramy zakładkę „C++” i ikonę „GTKmm (prosty)”

Nowy projekt GTKmm
Nowy projekt GTKmm

Klikamy na  „Kontynuuj” i uzupełniamy według uznania informacje o projekcie.

Informacje o projekcie
Informacje o projekcie

Po kliknięciu na „Kontynuuj” pokaże się okienko pozwalające na dostosowanie widocznych poniżej ustawień

Opcje projektu cz. 2.
Opcje projektu cz. 2.

Klikamy jeszcze raz na „Kontynuuj” i potwierdzamy informacje dotyczące naszego projektu

Potwierdzenie ustawień projektu
Potwierdzenie ustawień 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)

Projektant interfejsu
Projektant interfejsu

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ą.

Ustawianie liczby elementów w kontenerze
Ustawianie liczby elementów w kontenerze
Gotowy układ kontenerów
Gotowy układ kontenerów

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.

Docelowy układ widżetów w oknie
Docelowy układ widżetów w oknie

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:

Okno naszego programu
Okno naszego programu
Widoczny skutek obsługi zdarzenia przez nasz program
Widoczny skutek obsługi zdarzenia przez nasz program

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

Wybrane dla Ciebie
Komentarze (6)