Krátké představení
Glade je program, ve kterém se dá jednoduše – pouhým klikáním – vytvořit vzhled nějakého grafického programu. Generuje XML kód, který program dynamicky zpracovává a rozumí mu i člověk, takže můžeme měnit vzhled programu, aniž bychom ho museli překládat. Nejnovější verze Glade pro GTK+ 2 nese číslo 3.8 a pro GTK+ 3 pak číslo 3.10. My se podíváme na 3.8.
Práce s Glade
Existuje také možnost, jak pracovat s Glade jako s kódem – tak, jak je to např. v Anjutě, kde existuje takový glade plugin (viz screenshot výše). My se vydáme druhou cestou, tedy, jak pracovat s Glade ve smyslu v programu Glade.
Rozhraní
Po spuštění se zobrazí okno s novým, prázdným projektem uprostřed. Po levé straně jsou k dispozici widgety, na pravé straně pak strom se všemi použitými widgety a jejich vlastnosti. Menu je velmi přehledné . V nastavení lze zvolit, zda chceme formát souborů pro GtkBuilder či LibGlade, umístění obrázků a pro kterou verzi GTK+ grafické prostředí děláme. Program je přeložen do češtiny, příručka pro vývojáře ne (naleznete ji v menu Nápověda, jedná se o program DevHelp). Obsahuje plno referencí, mezi kterými je i naše gtkmm. Mně se s ní pracuje lépe než v prohlížeči, protože po levé straně je přehledný strom s widgety. Na jeho červené ikony občas narazíte rovnou v programu, kde plní funkci nápovědy pro daný widget, metodu či signál.
Základy
Protože nemůže existovat widget samotný, musíme vždy začít oknem. Jednoduše klikneme na kteroukoli ikonku (tlačítko) ze sekce Nejvyšší úrovně. Uprostřed se objeví požadovaný druh okna a můžeme už přidávat další widgety. Tady je maličká odlišnost, a to ta, že první musíme kliknout na widget (kontejner, …) a potom do volného místa v okně (kontejneru). Mazat lze jak kliknutím na widget uprostřed, tak kliknutím na widget ve stromové struktuře vpravo nahoře a stisknutím klávesy Delete. To je celé.
Volby
Vpravo dole je okno, ve kterém se nastavují jednotlivé widgety. Samotné volby mají jen krátké popisky, takže člověku nemusí být hned jasné, co vlastně nastavuje. Naštěstí se po najetí myší na kteroukoli volbu zobrazí delší vysvětlení. S delšími popisky to jde hladce, včetně nastavení signálů.
Propojení s programem
Pro práci s těmito XMl soubory nepotřebujeme žádné další knihovny. O vše se stará třída Gtk::Builder, se kterou však musíme pracovat pomocí Glib::RefPtr. O inicializaci se stará metoda create()
. Přímo nahrání souboru do paměti provede metoda add_from_file()
, které předáme jen cestu k souboru. Abychom mohli s „externím“ widgetem plnohodnotně pracovat (zobrazí se i tak), potřebujeme ukazatel. Ten nám poskytne metoda třídy Gtk::Builder, get_widget()
, jejímž prvním argumentem je název (ID) widgetu v Glade (je v kartě Obecné pod položkou Název), v XML kódu, a druhým argumentem pak (zatím nulový) ukazatel v programu. Občas je kód vhodné ošetřit podmínkami nebo výjimkami, viz ukázkový program.
Ukázkový program
#include <gtkmm.h> #include <iostream> Gtk::Window* Window_okno = 0; Gtk::Entry* Entry_Nazev = 0; Gtk::CheckButton* Checkbutton_Blog = 0; Gtk::SpinButton* Spinbutton_Uzivatele = 0; Gtk::Button* Button_Smazat = 0; Gtk::Button* Button_Dokoncit = 0; // Tato metoda vynuluje a vymaže všechny pole kromě CheckButtonu static void on_button1_Smazat_clicked() { // Kdyby Entry_Nazev neexistoval (což je možné), mohl by celý program spadnout, proto to radši ověříme podmínkou if(Entry_Nazev) { Entry_Nazev->set_text(""); } if(Spinbutton_Uzivatele) { Spinbutton_Uzivatele->set_value(0); } } // Vypíše obsah formuláře na terminál a ukončí program void on_button2_Dokoncit_clicked() { if (Checkbutton_Blog && Entry_Nazev && Spinbutton_Uzivatele) { if (Checkbutton_Blog->get_active()) { std::cout << "Název webové stránky: " << Entry_Nazev->get_text() << std::endl << "Blog: " << "ANO" << std::endl << "Počet předpokládaných uživatelů: " << Spinbutton_Uzivatele->get_value() << std::endl; } else { std::cout << "Název webové stránky: " << Entry_Nazev->get_text() << std::endl << "Blog: " << "NE" << std::endl << "Počet předpokládaných uživatelů: " << Spinbutton_Uzivatele->get_value() << std::endl; } } else { std::cout << "CHYBA: Pravděpodobně neexistuje některý z potřebných widgetů.\n"; } if(Window_okno) { Window_okno->hide(); } } int main (int argc, char **argv) { Gtk::Main kit(argc, argv); // Nahrání rozhraní ze souboru je trochu více náchylné k chybám, proto ta výjimka Glib::RefPtr<Gtk::Builder> refBuilder = Gtk::Builder::create(); try { refBuilder->add_from_file("ui.glade"); } catch(const Glib::FileError& ex) { std::cerr << "Chyba v souboru: " << ex.what() << std::endl; return 1; } catch(const Gtk::BuilderError& ex) { std::cerr << "Chyba třídy Builder: " << ex.what() << std::endl; return 1; } refBuilder->get_widget("window1", Window_okno); if(Window_okno) { // Toto "získávání" widgetů není pro jejich zobrazení povinné, nicméně s těmito widgety se bude pracovat refBuilder->get_widget("entry1_Nazev", Entry_Nazev); refBuilder->get_widget("checkbutton1_Blog", Checkbutton_Blog); refBuilder->get_widget("spinbutton1_Uzivatele", Spinbutton_Uzivatele); Spinbutton_Uzivatele->set_range(0,1000); Spinbutton_Uzivatele->set_increments(1,1); refBuilder->get_widget("button1_Smazat", Button_Smazat); refBuilder->get_widget("button2_Dokoncit", Button_Dokoncit); if(Button_Smazat) { Button_Smazat->signal_clicked().connect(sigc::ptr_fun(on_button1_Smazat_clicked)); } if(Button_Dokoncit) { Button_Dokoncit->signal_clicked().connect(sigc::ptr_fun(on_button2_Dokoncit_clicked)); } kit.run(*Window_okno); } return 0; }
Můžete si také stáhnout XML soubor.
Pokračování
Obsahem příštího dílu bude popis práce s tiskárnou a návod, jak si v gtkmm hrát s barvičkami, geometrickými obrazci a vůbec s grafikou. Pokud mě náhodou ještě něco nenapadne nebo si už nikdo nic nebude například ve fóru přát, bude tento díl dílem posledním (o novinkách v gtkmm 3 psát nebudu, jelikož se nezměnilo nic, o čem by již byla v seriálu řeč).