wxWidgets („Windows and X widgets“, dříve známý jako wxWindows) je free software/open source multiplatformní widget toolkit. Je to knihovna základních elementů pro tvorbu grafického uživatelského rozhraní (GUI).

wxWidgets
Logo
VývojářwxWidgets vývojáři
Aktuální verze3.2.6 (9. září 2024)
Operační systémmultiplatformní software
Vyvíjeno vC++
Typ softwaruVývojářská knihovna
LicencewxWindows Library Licence
Webwww.wxwidgets.org
Některá data mohou pocházet z datové položky.

Vývoj začal v roce 1992 díky Julianu Smartovi, který je dodnes vývojářem jádra.

wxWidgets umožňuje zkompilovat a spustit program na několika počítačových platformách s minimálními nebo žádnými změnami kódu. To zahrnuje systémy jako Windows, Macintosh, Linux/Unix (X11, Motif, a GTK+), OpenVMS a OS/2. Verze pro embedded systémy je ve vývoji.

Knihovna je implementována v C++, ale její používání je možné v mnoha běžně používaných programovacích jazycích, mezi nimi jsou například: Python (wxPython), C#, Erlang (wxErlang), Haskell (wxHaskell), Lua (wxLua), Perl (wxPerl), Ruby (wxRuby), Smalltalk (wxSqueak), Java (wx4j) a také JavaScript (wxJS).

wxWidgets je nejlépe popsán jako nativní toolkit. Místo napodobování grafiky prvků používá nativní grafické prvky na podporovaných platformách.

Jméno změněno z wxWindows na wxWidgets

editovat

20. února 2004 vývojáři wxWindows oznámili, že projekt změnil jméno na wxWidgets, jako výsledek tlaku Microsoftu. Julian Smart chtěl respektovat obchodní známku Microsoftu ve Velké BritániiWindows.

Hierarchie toolkitu

editovat

wxWidgets obsahuje několik důležitých tříd, jsou to především:

  • wxString – implementace textových řetězců
  • wxObject – předek veškerých tříd ve wxWidgets, které používají běhové informace o typech
  • wxEvtHandler – třída, která má na starosti předávání událostí
  • wxWindow – objekty, které mají grafickou reprezentaci jsou potomky této třídy

Jednoduchý program

editovat

Standardní C++ program začíná ve funkci main, ta se na různých platformách a při různém použití může jmenovat jinak (např. ve Windows se jedná o WinMain). V této hlavní funkci je třeba zinicializovat smyčku pro vyzvedávání zpráv od operačního systému a vytvořit okno aplikace. WxWidgets tuto funkcionalitu velmi dobře zapouzdřují a programátor se nemusí starat, jak se toto implementuje na jiných platformách.

Příklad jednoduché aplikace:

#include <wx/app.h>
#include <wx/frame.h>

class MyApp: public wxApp
{
public:
  MyApp() {}
  ~MyApp() {}
  virtual bool OnInit() 
  {
  bool wasSuccess = false;
  wxFrame * frame = new wxFrame(0,wxID_ANY,_T("NOVÉ OKNO"));
 
  if (frame) // kontrola alokace paměti
  {
    SetTopWindow(frame); // zaregistrování okna jako nejvyšší okno aplikace
    frame->Show(true);
    wasSuccess = true;
  }

  return wasSuccess;
  }
};
IMPLEMENT_APP(MyApp)

Třída wxApp má tyto úkoly:

  • nastavit a získat globální vlastnosti aplikace
  • zajistit komunikaci s operačním systémem např. vytvoření tzv. „Event Loop“, což je nekonečná smyčka čekající na zprávy od operačního systému, které následně převádí na události pro tento toolkit
  • provést kód v metodě OnInit, tu definuje programátor, pokud vrátí false, dáme wxWidgets najevo, že se nezdařila inicializace a aplikace se ukončí
  • zpracovávat události, které nejsou zachyceny v jiných objektech v aplikaci

Vkládání ovládacích prvků

editovat

Ovládací prvky se vytvářejí pomocí operátoru new. V konstruktoru se musí uvést ukazatel na rodičovské okno (oknem se zde rozumí objekt, jenž je potomkem wxWindow). Tím je dáno v jakém okně bude ovládací prvek vložený. Rodičovské okno se postará ve svém destruktoru o uvolnění všech objektů v něm vložených.

Příklad vložení tlačítka:

 new wxButton(this, wxID_ANY,_T("Tlačítko")); // this je potomkem wxWindow

Rozvržení ovládacích prvků

editovat

Obecně platí, že komponentám není dobré nastavovat absolutní velikosti a pozice, protože v rámci různých jazyků a nastavení zobrazovacího zařízení mohou mít jiné velikosti, než se kterými vývojář počítal. Ve wxWidgets tuto správu zajišťuje tzv. wxSizer, což je abstraktní třída, která obsahuje předpis [rozhraní] pro ostatní specializované sizery.

Mezi ty základní patří tyto třídy:

  • wxBoxSizer – ten umí řadit prvky vertikálně, nebo horizontálně za sebe, podle nastavení
  • wxGridSizer – sestavuje prvky do tabulky, kde se velikost určuje podle nejširšího a nejvyššího ovládacího prvku
  • wxFlexGridSizer – dělá také z ovládacích prvků tabulku, kde všechny prvky v jedné řádce mají stejnou výšku a všechny prvky v jednom sloupci šířku

Sizer dostává události o změně velikosti okna a upravuje velikosti a pozice prvků v něm vložených. Prvkem vloženým do sizeru může být i jiný sizer, ten má potom na starosti velikost a pozice svých prvků v přidělené buňce. Oknu, ve kterém má sizer působit, se musí předat na sizer ukazatel funkcí SetSizer, kterou má v sobě už wxWindow. Okno, ke kterému sizer náleží, si zajistí samo jeho uvolnění z paměti v případě zničení okna.

Příklad použití wxBoxSizeru (operace probíhají v konstruktoru nějakého okna):

 wxSizer * sizer = new wxBoxSizer(wxHORIZONTAL);
 sizer->Add(new wxButton(this, wxID_NEW,_T("Tlačítko jedna"))); //vložení tlačítka do sizeru

 SetSizer(sizer); //nastaví oknu sizer pro správu rozložení ovládacích prvků
 sizer->SetSizeHints(this); //nastaví oknu minimální možnou velikost v závislosti na vložených prvcích
 Layout(); //provede první přepočítání rozvržení

Zachytávání událostí

editovat

Primárně k zachytávání událostí slouží statické tabulky událostí. Tyto tabulky obsahují identifikátor události, identifikátor ovládacího prvku a funkci, která se má zavolat po vyvolání události. Nad statickou tabulkou probíhá během překladu typová kontrola, takže se nám nemůže podařit přeložit program, který má událost připojenou na špatně deklarovanou funkci. Tuto vlastnost umožňují vlastnosti jazyka C++, které umožňují vytvářet definice typu funkcí.

Pokud chceme vytvářet tabulku událostí, musíme vytvořit potomka třídy wxEventHandler, nebo využijme nějakého jejího existujícího potomka. Tento nový wxEventHandler lze metodou PushEventHandler dosadit do okna a v tom případě se bude prohledávat i jeho tabulka událostí. Těchto event handlerů můžeme vložit několik, takže se pak vytvoří řetěz, který se bude prohledávat v případě vyvolání události.

Všechny ovládací prvky jsou potomky wxEventHandleru, tzn., že při použití dědičnosti z jakéhokoliv okna můžeme vytvořit novou statickou tabulku událostí. Při vyvolání události se nejprve prochází tabulka událostí prvku který ji vyvolal a při nezachycení se prohledávají předkové, až když událost dorazí do wxWindow a stále se nenalezla vhodná kombinace v tabulce událostí, tak se událost postoupí nadřazenému prvku. Pokud událost nezachytí žádné okno je událost postoupena do objektu zastupující aplikaci, což je potomek wxApp. Je také možné po zachycení události nechat událost propagovat v hierarchii dále. Toho dosáhneme zavoláním metody Skip na wxEvent objektu.

Statická tabulka událostí se vytváří na dvou úrovních, poprvé je jí potřeba deklarovat v hlavičkovém souboru, kde do se kódu nové třídy vloží DECLARE_EVENT_TABLE.

Příklad deklarace statické tabulky událostí:

class wxCustomEventHandler : public wxEvtHandler
{
public:
 wxCustomEventHandler();
 virtual ~wxCustomEventHandler();
private:
 void onButton(wxCommandEvent & event);

 DECLARE_EVENT_TABLE();
};

Dále je nutné tabulku definovat v implementačním souboru.

Příklad definice:

BEGIN_EVENT_TABLE(wxCustomEventHandler, wxEvtHandler)
 EVT_BUTTON(wxID_BACKWARD, wxCustomEventHandler::onButton)
END_EVENT_TABLE()

Další možností je připojovat a odpojovat spracovatele událostí za běhu aplikace pomocí metod Connect a Disconnect. Tato možnost je dobrá zejména při tvorbě vlastních ovládacích prvků.

Internacionalizace

editovat

Ve wxWidges je internacionalizace řešena pomocí třídy wxLocale, instance této třídy reprezentuje zvolené národní prostředí v aplikaci. Díky ní, se například datum formátuje specificky dle zvolené země. Pro lokalizaci textů můžeme využít makra „_“, které zkracuje volání funkce wxGetTranslation, jež má jediný parametr a tím je klíč k textu anebo přímo metody třídy wxLocale::GetString.

Příklad inicializace wxLocale:

wxLocale * locale = new wxLocale();
locale->Init(wxLANGUAGE_CZECH); //nastavení aktuálního jazyka aplikace

/*složka v pracovním adresáři aplikace, ve které se budou hledat jazykové katalogy*/
locale->AddCatalogLookupPathPrefix(_T("lang/"));

locale->AddCatalog(_T("default")); //název souboru jazykového katalogu bez koncovky mo

Příklad použití lokalizovatelného řetězce:

 wxString label = _("Jméno: ");

Pro tvorbu katalogů s překladem aplikace je vhodné použít buď přímo textových nástrojů gettext pro vyhledání klíčů ve zdrojových souborech a vygenerování „po“ souboru. Nebo lépe nějaké uživatelské nadstavby, kterou je například Poedit. V tomto nástroji je možné nastavit masku vyhledávaných funkcí/maker použitých pro lokalizaci a následně vygenerovat a spravovat jazykové katalogy. Program řeší i situace odebrání textových řetězců, takže lze katalogy udržovat jednoduše synchronizované. Pokud se lokalizační klíče generují automaticky za běhu aplikace musí se „po“ soubor vytvořit ručně.

Software založený na wxWidgets

editovat

Další software založený na wxWidgets naleznete zde.

Reference

editovat

V tomto článku byl použit překlad textu z článku wxWidgets na anglické Wikipedii.

Literatura

editovat
  • SMART, Julian, HOCK, Kevin. Cross-Platform GUI Programming with wxWidgets. 1st edition. United States of America : Pearson Education, Inc., 2005. 541 s. ISBN 0-13-147381-6.

Související články

editovat

Externí odkazy

editovat