LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Vala 4: grafické rozhraní GTK+

>V dnešním díle se podíváme na grafické rozhraní GTK+. Jde o jednu ze dvou největších grafických knihoven v unixovém světě. Zatímco QT začíná u C++, tak doménou GTK+ je stále ANSI C. To ale neznamená, že by nemělo podporu dalších programovacích jazyků. Vedle C++, Javy nebo C# v podobě projektu Mono, je to právě rozhraní pro jazyk Vala. Ten by se dal postavit někam mezi C++ a C#.

23.2.2014 15:00 | Ondřej Tůma | Články autora | přečteno 11110×

O grafické knihovně GTK+ se nechci příliš rozepisovat, na to je k dispozici i českým čtenářům poměrně hodně zdrojů. Nicméně základní úvod a představení termínů považuji za drobnou nutnost.

Celá knihovna je postavena nad GObject, resp. nad GLib knihovnou. Tedy vše co jsem psal o GObject systému platí i pro GTK+. Základním rozdílem je pak právě použití grafického rozhraní, to sice není nutné použít, ale pak použití grafické knihovny ztrácí význam. GTK+ samo o sobě nepoužívá jen GLib, ale ředu dalších důležitých knihoven, které jsou programátorům v podobě API více či méně odkryty. Mezi ty nejdůležitější, na které můžete narazit patří GLib, GIO, Pango, Cairo, GDK a ATK.

  • O knihovně GLib jsem psal v do teď, je to nejnižší vrstva, kterou používá implicitně sama Vala a tedy i vaše programy ve Vale napsané.
  • Knihovna GIO by pravidelným čtenářům také neměla být neznámá. Jde o rozhraní k souborovému systému.
  • Pango je používáno na práci s textem, resp. s jeho zobrazením.
  • Cairo je knihovna určená na práci s vektorovou grafikou. Díky této knihovně se snadno pracuje i s různými dalšími cíli, vedle nejčastější obrazovky to jsou například obrázky nebo tiskové dokumenty.
  • GDK je jakousi mezivrstvou v rodině GTK+. Stará se mimo jiné o pixelovou grafiku. Tuto knihovnu přímo používat tolik nebudete, často ale budete potřebovat komunikovat s některými jejími třídami a strukturami.
  • Poslední neznámou je ATK. Tato knihovna je před drtivou většinou programátorů aplikací schovaná. Přesto je velmi užitečná. Díky ní bude Vaše aplikace přístupná i například zkrakově postiženým.
architektura GTK+
Struktura GTK+ zdroj: gtk.org

Celé GTK+ pak může běžet nad různými grafickými rozhraními. Tato knihovna je zároveň multiplatformní, díky tomu můžete najít GTK+ na Linuxu, Windows, MacOS nebo libovolném unixovém systému. GTK+ umí běžet nad Xserverem, Waylandem, Frame Bufferem nebo dokonce jako HTML aplikace. A samozřejmě její vzhled nastavit a rozšiřovat. Některé aplikace tak ani nevypadají že GTK+ používají.

GTK+ pro programátora

V GTK+ se setkáte s několika druhy objektů. Nejjednodušší struktury popisují různé základní vlastnosti. Například barvu (Gdk.Color), definice čtverce (Gdk.Rectangle nebo Cairo.Rectangle), událost (Gdk.Event) a podobně. Složitější struktury, sloužící k dalšímu zpracování jsou popsány třídami. Jde v podstatě o rozsáhlé datové typy, proto je vhodné je držet v paměti jako třídy. Jsou to například Pango.Font, Gtk.Settings, Gtk.Acction, File.Filter a další. Poslední sadou objektů jsou tzv. Widgety. Jsou to takové objekty, které již obsahují konkrétní vizualizaci. Tyto widgety jsou základní stavební prvky GTK+ knihovny. Interně a nejen interně se tedy velmi často setkáte s tím, že stačí pouze informace o tom, že objekt, se kterým se dál pracuje je potomek třídy Gtk.Widget. Do této skupiny patří ikony, tlačítka, menu ale i tzv. kontejnery, jako okna, panely a záložky resp. kartotéka.

Celou hierarchii grafických prvků může programátor skládat ručně. Konečně v mnoha případech je to jediná možnost. GTK+ však má, stejně jako ostatní knihovny, nástroj na „malování“ aplikace. Tímto nástrojem je Glade. Ten se postupem času značně vyvinul a v poslední verzi je to „malovátko“, ve kterém si programátor poskládá aplikaci ze všech dostupných widgetů, které mu GTK+ nabízí. Výstup v podobě XML souboru pak lze snadno nahrát a používat v aplikaci. I tento způsob práce dostane v seriálu prostor.

Události

Než se pustíme do vytouženého příkladu, zastavíme se u událostí. Na většině grafických rozhraní, které znám jsou události základním prvkem interakce rozhraní s uživatelem. Aby také ne. To uživatel často kliká na tlačítka, scrolluje v editoru, pohybuje kurzorem a očekává, že aplikace na jeho akci bude reagovat. Vedle uživatelských událostí, má však nejen GTK+ mnoho dalších interních, programových, knihovních a aplikačních událostí. Tyto události jsou generovány například při vytvoření, zobrazení, nebo v době ničení objektu. Další obdobné události jsou vyvolány při manipulaci s tzv. dětmi atd.

Každá událost může vyvolat nějakou akci, může být jedna, nebo jich může být více. A právě na tyto události je Vala už připravena. V prvním díle tohoto seriálu jsem se krátce zmínil o tzv. signálech. Signály umožňují programátorovi tvořit asynchronní aplikaci, bez ohledu na to, zda používá nějakou pokročilejší techniku paralelního běhu. Tyto signály jsou programátorským ekvivalentem nějaké události. Programátor může tyto události různě používat. Přetěžovat, zastavovat, vyvolávat ale především na ně může reagovat.

Než se pustíme do první grafické aplikace, rád bych využil této subkapitoly k ukázce použití signálů v konsolové aplikaci. Signály budou fungovat vždy, jsou pouštěny sériově tak, jak jsou vyvolány. Aplikaci však lze rozšířit pomocí tzv. smyčky, díky které máme další možnosti.

Nejprve obyčejná verze:
class SignalTester : GLib.Object {
    // pouze vlastnosti s avizovaným set a get přístupem generují událost notify
    public string property { set; get; }

    public SignalTester() {
        notify.connect(debug);          // vytvoření události zavolá metodu debug
    }

    private void debug(GLib.ParamSpec p) {
        stdout.printf("Vlastnost '%s' byla změněna\n", p.name);
                                        // po dvou vteřinách zavolá lambda funkci
    }

    public static int main (string[] args) {
        SignalTester tester = new SignalTester();
        tester.property = "property je vlastnost";
        tester.property = "property je vlastnost";

	return 0;
    }
}
soubor: signal.vala

Všimněte si co program udělá. Každé nastavení vlastnosti s názvem property způsobí zavolání metody debug.

Poté rozšířená verze:
class SignalTester : GLib.Object {
    // pouze vlastnosti s avizovaným set a get přístupem generují událost notify
    public string property { set; get; }

    public SignalTester() {
        notify.connect(debug);          // vytvoření události zavolá metodu debug
    }

    private void debug(GLib.ParamSpec p) {
        stdout.printf("Vlastnost '%s' byla změněna\n", p.name);
                                        // po dvou vteřinách zavolá lambda funkci
        GLib.Timeout.add (2, (() => {
            stdout.printf("2 vteřiny timeout ...\n");
            return false;
        }));
    }

    public static int main (string[] args) {
        var loop = new GLib.MainLoop();
        var time = new TimeoutSource(10000);        // 10 vteřin

        time.set_callback(() => {
            stdout.printf("Nashledanou!\n");
            loop.quit();                            // ukončí smyčku
            return false;
        });
        time.attach(loop.get_context());

        SignalTester tester = new SignalTester();
        tester.property = "property je vlastnost";
        tester.property = "property je vlastnost";

        loop.run ();
	return 0;
    }
}
soubor: signal2.vala

Druhá verze umožňuje v podstatě „paralelní“ běh. Všimněte si, že po metoda debug dvakrát načasovala volání další, tentokrát lambda metody.

Tato ukázka byla jen nástin toho, co budeme v grafické aplikaci řešit. Proto, že jsou události neoddělitelnou součástí GTK+, budeme se jimi ještě mockrát zabývat.

Hello gtk+ world

Začneme rovnou kódem:
public class Application : GLib.Object {            // obecná třída Application, vlastně není potřeba

    public static int main (string args[]) {        // standardní statická metoda main
        Gtk.init (ref args);                        // inicializace GTK+

        var window = new Gtk.Window ();             // vytvoří nové okno
        window.destroy.connect (Gtk.main_quit);     // při jeho zavření se ukončí Gtk

                                                    // Nové tlačtko s nápisem
        var button = new Gtk.Button.with_label ("Klikni na mě!");
        button.clicked.connect ((w) => {            // po kliku na tlačítko se vypíše jeho název
            stdout.printf ("kliknuto na %s\n", w.name);
        });

        window.add (button);                        // tlačítko se přidá do okna
        window.show_all ();                         // vše v okně, včetně se zobrazí

        Gtk.main ();                                // pustí se GTK+ smyčka - až tady se zobrazí GTK+ okno
        return 0;
    }
}
soubor: hello_gtk_world.vala

GTK je obsaženo v gtk+ balíčku. Náš seriál bude popisovat již verzi 3.x, nicméně v mnoha případech bude kód přeložitelný i s verzí 2.x. Při kompilaci je tedy nutné uvést balíček.

$ ~ valac hello_gtk_world.vala --pkg gtk+-3.0

V závislosti na verzi GTK+, Vala kompilátoru a C kompilátoru je možné, že kompilace bude generovat různé množství varování z C kompilátoru. Tyto varování jsou známé, a spočívají v nedokonalém generování zdrojového C kódu. Ten se generuje na základě vapi souborů příslušných knihoven, a ty se s knihovnami občas rozchází. Chyby jsou známé a v dalších verzích Valy jsou opraveny.

Probereme si ještě co kód dělá. Veřejná třída Application zde vlastně není potřeba, je to jen hezký ~ správný zápis Vala aplikace. V dalších příkladech již ale bude tato třída používána tím typičtějším způsobem.

Než začneme cokoli dělat s widgety, je nutné inicializovat samotné GTK+ metodou init. Té předáváme parametry příkazové řádky, to proto, že samotné GTK+ některým parametrům rozumí. Na unixovém systému si můžete vyzkoušet parametr --display, který umožní spustit aplikaci na jiném Xserveru.

V druhé fázi vytvoříme widget okna. Okno má mnoho událostí, jedna z nich se jmenuje destroy a je volaná v době, kdy uživatel zavírá okno ze správce oken. Tedy kliknutím na křížek v pravé části panelu správci oken, nebo kombinací kláves Alt + F4, či jiným způsobem, typickým pro daného správce oken. Na tuto událostí navěsíme metodu Gtk.main_quit (). Tato metoda po sobě uklidí, ale především ukončí hlavní smyčku Gtk.main ().

Pokračujeme vytvořením tlačítka. V příkladu používáme jeden z konstruktorů, jenž na vstupu očekává text, který bude vidět na tlačítku. A i na událost tlačítka, tentokrát s názvem clicked, navěsíme naší funkci. V jednom z minulých dílů jsme si říkali o lambda funkcích. K nim se jistě ještě mnohokrát dostaneme, pro začátek nám stačí, že je to takový inline způsob, jak pustit nějaký náš kód bez toho, aniž bychom vytvářeli další metodu. Na vstupu je volitelný parametr typu Gtk.Widget. A každý widget má své jméno, můžeme jej proto vytisknout na standardní výstup.

Aby se tlačítko někde objevilo, je třeba jej přidat do okna. Třída Gtk.Window je potomkem třídy Gtk.Container. Potomci této třídy mohou obsahovat další prvky, někdy jeden, někdy dva, někdy několik. Ty nejdůležitější si představíme v dalších dílech seriálu. Po přidání je důležité tyto prvky zobrazit. To se dělá voláním metody show () nebo show_all (). Tyto metody jsou velmi podobné. Metoda show () zobrazí pouze daný widget, show_all () zobrazí widget, a všechny děti – tedy takové widgety, jenž byly do prvku přidány. Aby byly widgety vidět, musí být vidět i jejich rodiče – kontejnery. To si můžete sami vyzkoušet a doufám že to také uděláte.

Na závěr je nutné zavolat metodu Gtk.main (). Jak název napovídá, tato metoda spustí hlavní GTK+ smyčku, ve které aplikace žije. Na této metodě se aplikace „zastaví“, dokud není zavolána metoda Gtk.main_quit ().

Co nás čeká příště

Příště si představíme některé z kontejnerů a probereme si jak je to s jejich používáním. Také se podíváme na některé další zajímavé Widgety které by se nám mohli hodit. Na závěr bych rád upozornil na diskuzi pod článkem, kterou bych byl rád, pokud budete využívat. Pomůžete mě se tak zaměřit se místa, která Vás trápí.

Stránky projektu GTK+
Oficiální tutoriál k Vale
Tutoriál signálů ve Vale
Vala dokumentace Gtk balíčku
Vala dokumentace třídy Gtk.Widget
Vala dokumentace třídy Gtk.Window

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

8.5.2016 17:19 /Redakce Linuxsoft.cz
PR: Dne 26.5.2016 proběhne v Praze konference Cloud computing v praxi. Tématy bude např. nejnovější trendy v oblasti cloudu a cloudových řešení, cloudové služby, infrastruktura cloudu, efektivní využití cloudu, možné nástrahy cloudů a jak se jim vyhnout
Přidat komentář

21.4.2016 8:01 /František Kučera
Spolek OpenAlt zve na 127. distribuovaný sraz příznivců svobodného softwaru a otevřených technologií (hardware, 3D tisk, SDR, DIY, makers…), který se bude konat ve čtvrtek 28. dubna od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

2.3.2016 22:41 /Ondřej Čečák
Letošní ročník konference InstallFest již tento víkend!
Přidat komentář

14.2.2016 16:39 /Redakce Linuxsoft.cz
O víkendu 5. a 6. března 2016 proběhne na pražském Strahově 8. ročník tradiční konference InstallFest. Celkem za dva dny uvidíte ​30 přednášek​ a ​6 workshopů.
Přidat komentář

5.2.2016 17:38 /Petr Ježek
Utilitka z XFce "xfce4-power-manager" nejen umožňuje nastavení lhůty pro uspání či hybernaci, ale i zapínání a vypínání prezentačního módu pro nerušené sledování videí. Stačí ji nastavit v každém vybavenějším panelu a v jakémkoli nontiled WM/DE.
Přidat komentář

10.1.2016 11:32 /Pavel `Goldenfish' Kysilka
LinuxMarket změnil provozovatele. Nově jej provozuje Marek Pszczolka. Více info a detaily #1 a #2.
Přidat komentář

29.12.2015 11:38 /Ondřej Čečák
Ještě posledních pár dní můžete přidávat příspěvky nebo nápady na Install Fest 2016, který se bude konat 5. a 6. března 2016.
Přidat komentář

8.12.2015 11:36 /Petr Ježek
Logické se stává realitou. LibreOffice a Thunderbird se mají dle článku na Redditu stát protiváhou MS řešení (MS Office a Outlook).
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

7.5.2016 14:58 / Teodor Komárek
Soubory

20.4.2016 0:07 / Jakub Cleing
Sázkový panel PHP FUSION

9.4.2016 9:43 / jiwopene@gmail.com
Re: problém s dpkg a nemožností instalovat

9.4.2016 9:41 / jiwopene@gmail.com
Re: změna velikosti disk.oddílu

9.4.2016 9:40 / jiwopene@gmail.com
Re: Přenesení starého OS Win7 na virtuál v Debianu

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2016) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze