Hlavní navigace

Gtkmm a jeho spolupráce s Glade

Tomáš Velecký 12. 5. 2011

V tomto díle našeho seriálu o knihovně Gtkmm budou popsány základy práce s programem Glade, návrhářem grafického rozhraní GTK+, od samotného návrhu rozhraní po propojení vygenerovaného XML souboru s konečným výtvorem v kódu C++. Ukázkovým programem je tentokrát opravdu malý a jednoduchý formulář.

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

Glade plugin v Anjutě

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í

Glade po spuštění

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.

Reference pěkně vedle Glade

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

Vysvětlení 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ů.

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č).

Našli jste v článku chybu?

19. 5. 2011 21:30

__dark__ (neregistrovaný)

Mi se tento tutoriál vůbec nelíbí. Nechtěl bych porovnávat gtkmm vs třeba Qt, ale proč autor použil globální proměnné pro widgety a proč tam jsou ty statické callbacky? Podle mě tyto 2 věci zcela degradují celý smysl využití gtkmm.

Root.cz: Telegram spustil anonymní blog Telegraph

Telegram spustil anonymní blog Telegraph

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

DigiZone.cz: ČRo rozšiřuje DAB do Berouna

ČRo rozšiřuje DAB do Berouna

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Vitalia.cz: Jmenuje se Janina a žije bez cukru

Jmenuje se Janina a žije bez cukru

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

Vitalia.cz: Znáte „černý detox“? Ani to nezkoušejte

Znáte „černý detox“? Ani to nezkoušejte

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Vitalia.cz: 9 největších mýtů o mase

9 největších mýtů o mase

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

Podnikatel.cz: Chtějte údaje k dani z nemovitostí do mailu

Chtějte údaje k dani z nemovitostí do mailu

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

DigiZone.cz: ČRa DVB-T2 ověřeno: Hisense a Sencor

ČRa DVB-T2 ověřeno: Hisense a Sencor