Hlavní navigace

Knihovna ClanLib (14)

Petr Kavánek 16. 8. 2004

Na přípravu tohoto dílu jsem měl trochu více času než obvykle, takže jsem stihl připravit ukázkový program demonstrující tvorbu GUI v ClanLibu. Program si můžete stáhnout buď jako obvykle v podobě zapakovaného KDevelopího projektu, nebo ve formě archivu s ručně psaným makefilem. Pro vás, které pouze zajímá, jak taková okenní aplikace vytvořená v ClanLibu může vypadat, jsem připravil pár obrázků. V našem povídání navážeme na minulý díl.

Ukázky stříbrného stylu GUI

Zde jsou slíbené obrázky toho, jak může vypadat aplikace vytvořená v ClanLibu s využitím stříbrného stylu GUI. Jedná se o screenshoty z ukázkového programu, který si můžete stáhnout na konci článku.


Několik poznámek k příkladu

Přiložený program demonstruje funkčnost a vzhled několika komponent GUI. Jedná se o CL_DisplayWindow (hlavní okno celé aplikace), CL_Window (základní okno vytvořeného GUI), CL_Label, CL_ScrollBar, CL_ListBox, CL_Frame, CL_InputBox, CL_Image, CL_Button (ať již klasického, či vlastního vzhledu), CL_ProgressBar a CL_MessageBox. Tento výčet samozřejmě neobsahuje vše, co ClanLib nabízí, avšak obsahuje myslím to, co nejčastěji potřebujeme, kromě tvorby menu, které se, jak doufám, budeme věnovat v souvislosti s nějakým dalším příkladem.

Součástí příkladu je poměrně rozsáhlý GDF soubor, který by se vám mohl hodit při vlastní tvorbě. Když si nebudete jisti, jak se něco zapíše, možná to tam objevíte. Například zápis obrázeku (image) zatím tvůrci ClanLibu nezdokumentovali, takže pokud nechcete procházet zdrojáky, jako jsem to dělal já, podívejte se do zmíněného GDF souboru (samozřejmě si tento zápis popíšeme i v tomto seriálu).

Program sám o sobě nedělá nic moc duchaplného, spíše samé pouťové efekty. Zkuste tedy klikat na všechno možné, vypozorovat, co se kdy stane, a pak se podívejte do zdrojáků, jak je to naprogramované. Použité obrázky jsou z mé hry, za jejich nakreslení vděčím své přítelkyni.

Při psaní ukázkového programu jsem narazil na několik věcí, o kterých bych se rád zmínil.

Uzavření hlavního okna programu

Možná jste si všimli u některého z předchozích příkladů, že pokud jste klikli na křížek v pravém horním rohu hlavního okna, který obvykle slouží k jeho zavření, nic se nestalo. Otázka zní, jak zařídit, aby se něco stalo, přesněji řečeno, aby se stalo to, co my chceme. Řešení je poměrně jednoduché, pokud víme, že při kliknutí na zmíněné tlačítko vyšle CL_DisplayWindou signál sig_window_close. Stačí pak už jen tento signál připojit k nějaké naší metodě a provést to, co chceme:

// zde Sloty je CL_SlotContainer
// signál připojujeme k metodě on_HlavniOkno_close(),
// jejiz telo nasleduje ...
Sloty.connect(HlavniOkno.sig_window_close(), this, &T_Aplikace::on_HlavniOkno_close);

void T_Aplikace::on_HlavniOkno_close() {

  // Zjistime, zda chce uzivatel opravdu ukoncit program
  if (CL_MessageBox::info("Ukonceni...", "Chcete opravdu ukoncit program?"
    "Ano", "Ne", "Storno", SpravceGUI) == 0) {

    // prerusime hlavni smycku, cimz ukoncime program
    Konec = true;
  }

} // on_HlavniOkno_close() ------------------------ 

V tomto případě je situace taková, že je vyslán určitý signál, který nás informuje o tom, že nastala nějaká událost, a jeho vyslání nemá automaticky žádný další efekt.

Občas se však může stát i to, že je signál nejen vysílán, ale také automaticky odchytáván a po jeho vyslání je automaticky provedena nějaká akce.

Zavírání CL_Window a virtuální sloty

Příkladem výše popsaného chování je klasické okno v našem GUI a kliknutí na jeho uzavírací tlačítko. Zde je chování jiné než u CL_DisplayWindow, totiž CL_Window se automaticky zavře. Může samozřejmě nastat situace, kdy nám takovéto chování nebude vyhovovat. Potřebovali bychom nějakým způsobem signál odchytit předtím, než se dostane ke slotům, ke kterým již byl připojen.

K tomuto účelu slouží tzv. virtuální sloty. Princip je podobný jako u klasického připojení signálu do slotu, avšak trochu se liší syntaxe:

// signal uzavreni zakladniho okna pretizime, aby nedochazelo
// k nenavratnemu zruseni okna kliknutim na prislusne tlacitko
slot_ZakladniOkno_close = ZakladniOkno->sig_close().connect_virtual(this, &T_Aplikace::on_ZakladniOkno_close); 

Zde je slot_ZakladniOkno klasický slot, tj. typ CL_Slot. Změna je v tom, že místo metody connect() signálu použijeme jeho metodu connect_virtual(), která zařídí přesně to, co potřebujeme. Nejen že přetíží původní připojení tohoto signálu do slotů, navíc předá metodě, která bude volána (zde je to metoda on_ZakladniOk­no_close() třídy T_Aplikace) jako parametr referenci na CL_SlotParent_v0 (může být i v1 apod. dle typu signálu). Jedná se o jakéhosi předka vzniklého virtuálního slotu, kterého můžeme v těle metody zavolat jako funkci, čímž dosáhneme následného vykonání akcí, které by proběhly, kdybychom slot „nepřetížili“. Následující příklad kódu snad vše ozřejmí:

void T_Aplikace::on_ZakladniOkno_close(CL_SlotParent_v0& Ukonceni) {

  using namespace std;
  // Zjistime, zda chce uzivatel opravdu ukoncit program zavrenim okna
  if (CL_MessageBox::info("Zavreni okna...", "Zavreni tohoto okna je nevratne.\n"
      "Chcete ho opravdu zavrit?",
      "Ano", "Ne", "Storno", SpravceGUI) == 0) {

    // !!! zavreme zakladni okno zavolanim predka slotu
    Ukonceni();

    OknoZavreno = true;
  }
} 

Tento kód způsobí, že po kliknutí na uzavírací tlačítko okna se objeví message box s dotazem, zda si opravdu přejeme okno zavřít. Pokud odpovíme kladně, pošleme predka, tj. vyšleme signál, který jsme odchytili dřív, než se mohl někam dostat. V opačném případě se chováme, jako by nikdo na uzavírací tlačítko nekliknul, a tedy okno neuzavřeme.

CL_MessageBox

V ukázkách jste si zajisté všimli použití komponenty, kterou jsme si dosud podrobněji nepopsali, a to CL_MessageBoxu. Ten slouží k zobrazování krátkých zpráv uživateli. Může mít podobu s jedním až se třemi tlačítky. Podobu s jedním tlačítkem používáme, pokud chceme pouze zobrazit zprávu. Podobu se třemi tlačítky používame, chceme-li od uživatele odpověď typu ano/ne/storno.

Pokud je mi známo, není zatím možné message box vytvářet z GDF, což by také v jeho případě nemělo příliš velký smysl. Nejčastěji vytvoříme message box způsobem jako ve výše uvedených ukázkách kódu, tj. voláním CL_MessageBox::in­fo(). Tato metoda se vyskytuje v následujících přetížených verzích:

static int info(
  const std::string &text,
  CL_Component *parent,
  CL_StyleManager *style = NULL);

static int info(
  const std::string &title,
  const std::string &text,
  CL_Component *parent,
  CL_StyleManager *style = NULL);

static int info(
  const std::string &title,
  const std::string &text,
  const std::string &button1,
  const std::string &button2,
  const std::string &button3,
  CL_Component *parent,
  CL_StyleManager *style = NULL);

Poslední dva parametry jsou vždy ukazatel na rodičovskou komponentu a na správce stylu (nepoviný). Rodičovskou komponentou může být v podstatě cokoliv, nejčastěji to asi bude odkaz přímo na správce GUI, tj. CL_GUIManager, což je také potomek CL_Component (GUIManager je kořenovou komponentou každého GUI v ClanLibu).

Dále můžeme zadat buď jenom text zprávy, nebo text s titulkem message boxu, případně text až tří tlačítek (prázdný řetězec by měl způsobit vynechání posledního či posledních dvou tlačítek).

Metoda info vždy vrací index tlačítka, na které jsme v message boxu klikli (číslováno od nuly). Na základě této vrácené hodnoty se pak můžeme rozhodovat.

Message box můžeme vytvořit také přímo pomocí konstruktoru, který má stejné parametry jako nejširší verze metody info. Na jaké tlačítko jsme klikli, můžeme zjistit pomocí metody get_result_but­ton(), která opět vrací index tlačítka stejně jako info().

CL_RadioButton

Přepínač je poslední komponentou, jejíž popis se ještě do dnešního dílu vejde. V GDF ho můžeme popsat například takto:

<radiobutton name="RadioButton" x="315" y="360" />

Prostě udáme jeho souřadnice a jméno. Třída CL_RadioButton pak poskytuje metody:

bool is_checked() const;
void set_checked(bool check);

Pomocí nich jsme schopni zjistit, nebo nastavit stav tohoto přepínače.

Závěr

Příště budeme pokračovat v podobném duchu.

Slíbený KDevelopí projekt příkladu můžete stáhnout zde. Verze s jednoduchým makefilem je zde.

Možná jste si všimli, že tvůrci knihovny přecházejí na nový server, tak doufejme, že se jim vše podaří co nejdříve zprovoznit.

Soubory ke stažení

příklad s ručně psaným makefilem
kdevelopí projekt

Našli jste v článku chybu?
Vitalia.cz: Chtějí si léčit kvasinky. Lék je jen v Německu

Chtějí si léčit kvasinky. Lék je jen v Německu

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

Přehledná titulka, průvodci, responzivita

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

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

Podnikatel.cz: Babiše přesvědčila 89letá podnikatelka?!

Babiše přesvědčila 89letá podnikatelka?!

Vitalia.cz: Pečete cukroví a zbyl vám bílek?

Pečete cukroví a zbyl vám bílek?

Lupa.cz: Babiš: E-shopů se EET možná nebude týkat

Babiš: E-shopů se EET možná nebude týkat

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

120na80.cz: Boreliózu nelze žádným testem prokázat

Boreliózu nelze žádným testem prokázat

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

Podnikatelům dorazí varování od BSA

Lupa.cz: Seznam mění vedení. Pavel Zima v čele končí

Seznam mění vedení. Pavel Zima v čele končí

Podnikatel.cz: EET: Totálně nezvládli metodologii projektu

EET: Totálně nezvládli metodologii projektu

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

1. den EET? Problémy s pokladnami

Podnikatel.cz: Na poslední chvíli šokuje výjimkami v EET

Na poslední chvíli šokuje výjimkami v EET

Vitalia.cz: Dáte si jahody s plísní?

Dáte si jahody s plísní?

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Vitalia.cz: Baletky propagují zdravotní superpostel

Baletky propagují zdravotní superpostel

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

DigiZone.cz: Rádio Šlágr má licenci pro digi vysílání

Rádio Šlágr má licenci pro digi vysílání

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka