Jak vytvořit dobré GUI
Grafické uživatelské rozhraní by mělo být snadno ovladatelné, přehledné a intuitivní. Pro toolkity a desktopová prostředí obvykle existují pravidla, jak mají aplikace vypadat a fungovat. Např. pro GNOME je to dokument GNOME Human Interface Guidelines. Podobně styl KDE aplikací definuje dokument KDE User Interface Guidelines. Je vhodné se těchto pravidel držet, protože uživatelé mají zažitý určitý způsob ovládání grafického prostředí, v němž pracují, a jsou zvyklí na standardní vzhled a rozmístění jednotlivých ovládacích prvků GUI. Samozřejmě existují situace, kdy je vhodné některé pravidlo porušit. Ale programátor by pro to měl mít dostatečně dobrý důvod. Takovým důvodem není, že se mu alternativní vzhled GUI prostě zdá lepší. Každému se líbí něco jiného a standardní pravidla jsou dobrým kompromisem. Nestandardní chování aplikace nutí uživatele učit se nová pravidla a navíc si pamatovat, že platí pouze pro tuto jednu aplikaci.
Jednotlivé programy by neměly zapadnout do celého grafického uživatelského prostředí jen vzhledově, ale i funkčně. Např. je potřeba, aby aplikace šla přidat do menu a aby se její ikona správně zobrazovala v panelu. Každá aplikace by měla používat stejný způsob konfigurace jako ostatní komponenty desktopu a brát ohled na globální nastavení, např. stylu widgetů, klávesových zkratek nebo jazyka. Integrovaná desktopová prostředí obvykle obsahují mechanismus pro komunikaci a propojování aplikací a pro vkládání dokumentů z jedné aplikace do jiné. V GNOME se používá CORBA, KDE má vlastní nástroje DCOP a KParts. Každá aplikace, u níž to má jen trochu smysl, by tyto komunikační mechanismy měla používat. Už při psaní programu je dobré myslet na pozdější lokalizaci do jiných jazyků. Ideální je, když lze lokalizaci provést pouhým přeložením souboru textů používaných v programu, bez zásahu do kódu.
Na začátku KDE User Interface Guidelines je definováno několik obecných pravidel, kterých je dobré se při návrhu aplikace držet. Tato pravidla do značné míry platí pro veškerý software, i když nepoužívá GUI. Program by měl:
- být vhodný pro daný účel: Neměl by nabízet nadbytečné funkce, jež matou uživatele.
- být pochopitelný: Když uživatel program použije poprvé, měl by být schopen rychle zjistit, jak funguje, a naučit se ho používat.
- umožňovat snadnou navigaci: Uživatel by měl stále vědět, kde se nachází. Navigace uživatele mezi částmi aplikace by neměla být příliš omezována.
- odpovídat očekáváním: Program by měl fungovat konzistentně.
- být tolerantní k chybám: Uživatelé dělají chyby. Program by měl na chyby rozumně zareagovat a poskytovat funkci Undo.
- poskytovat zpětnou vazbu: Aplikace by měla uživateli okamžitě oznamovat, jaké funkce provádí.
Typická GUI aplikace má hlavní okno s menu a toolbarem v horní části a se stavovým řádkem na dolním okraji. Správné menu obsahuje veškeré možné akce. Pokud nějakou akci nelze v určitém okamžiku provést, příslušná položka menu by měla být zakázaná, ale stále viditelná. V menu je dobré dodržovat obvyklé uspořádání položek a rozdělení do submenu. Dobrým zvykem je u všech položek, které po aktivaci nejprve otevřou dialog, psát na konci jména tři tečky. V menu tedy je „New“ a „Save“, ale „Open…“ a „Save As…“. Do stavového řádku se zapisují méně důležité informace pro uživatele o aktuálním stavu programu a o prováděných akcích. Zásadní zprávy, o kterých si chce být programátor jist, že je uživatel nepřehlédne, je třeba zobrazit ve formě modálního dialogu. Hlavní okno aplikace by mělo být rozumně použitelné i v malém rozlišení obrazovky (800×600 nebo dokonce 640×480) a zároveň by mělo být schopno využít libovolně velký prostor při maximálním zvětšení na obrazovce s velkým rozlišením.
Program v X by měl po celou dobu běhu reagovat na podněty uživatele a podle potřeby překreslovat svá okna. Řízení se musí dostatečně často vracet do cyklu pro zpracování událostí. Handlery událostí proto nesmí běžet moc dlouho. Jestliže je nutné provést časově náročnější akci jako čtení souboru nebo složitější matematický výpočet, je potřeba ji rozdělit na menší úseky, volat je pomocí časovače nebo jako idle funkci a mezitím se vracet do zpracování událostí. Další varianta je přesunout dlouhotrvající výpočet do samostatného vlákna či procesu. Když je program něčím zaměstnán a nemůže provádět požadavky uživatele, měl by to dát vizuálně najevo. Pokud tento stav trvá maximálně pár sekund, stačí změnit tvar kurzoru, obvykle na symbol hodin. Pro delší časy se používá progress bar. Ten je obvykle k dispozici ve dvou módech. V jednom ukazuje, jaká část práce je hotova a kolik zbývá, ve druhém pouze indikuje, že program stále pracuje. První mód je lepší, ale jen za předpokladu, že zobrazená hodnota dává dobrý odhad, jak dlouho bude muset uživatel ještě čekat.
Dialogová okna je lepší vytvářet jako nemodální, protože takové dialogy neomezují interakci uživatele s programem. Modální dialogy jsou vhodné pouze v situaci, když program potřebuje, aby uživatel zadal nějaké hodnoty dříve, než může pokračovat dál. Toolkity poskytují řadu standardních dialogů pro zobrazování zpráv, výběr souborů nebo fontů, nastavení barev apod. Tyto standardní dialogy je vhodné používat, protože to přispívá ke konzistenci aplikace se zbytkem uživatelského prostředí. Správný dialog by měl jít zobrazit i v rozlišení 640×480, ale zároveň by mělo být možné ho zvětšit na celou obrazovku. Při zvětšování je třeba přidělit nejvíc místa widgetům obsahujícím největší množství dat, např. dlouhému seznamu.
Otevřené systémy
X Window System je dobrým příkladem otevřeného systému. Zde je třeba zdůraznit, že otevřený program není totéž, co open source program. Leckterý proprietární komerční software je více otevřený než některé open source programy. Zde termín „otevřený“ neznamená software, který je možné používat zadarmo nebo jehož zdrojový kód je zveřejněný. Jde o to, že otevřený program či systém používá zveřejněné a dobře dokumentované formáty dat a rozhraní. Tím je usnadněna spolupráce s dalšími programy a možnost použití různých implementací téže funkcionality od různých výrobců nebo na různých platformách.
Otevřené systémy bývají modulární, s jasně oddělenými moduly komunikujícími přes dobře definovaná rozhraní. To umožňuje podle potřeby používat různé varianty týchž modulů. V X jsou jasně oddělené nižší vrstvy (X protokol a Xlib) od vyšších vrstev (toolkity a window manager). Uživatel si může vybrat z velkého množství window managerů podle svého vkusu a programátor má na výběr z řady toolkitů. Programy používající různé toolkity mohou nejen běžet současně, ale umí si i navzájem předávat data. X klient a X server mohou spolupracovat, i když jsou spuštěny na odlišných architekturách, např. klient na nějakém superpočítači a server na unixové pracovní stanici, na PC s Linuxem nebo dokonce s Windows.
Důležitou vlastností otevřeného softwaru je kvalitní dokumentace. Zde open source často zaostává. Pro ilustraci tohoto faktu se stačí podívat do manuálových stránek Linuxu na jedné a komerčních Unixů na druhé straně. Nedostatečná dokumentace je častá právě u programů s GUI. Důvod je jasný – program s řádkovým rozhraním obvykle nejde rozumně používat, pokud není k dispozici popis přepínačů nebo příkazů, jimiž jej lze ovládat. U grafických programů mají jejich autoři tendenci spoléhat na intuitivnost uživatelského rozhraní a pak opomenou zdokumentovat i věci, jež intuitivní nejsou. Často chybí i popis konfiguračních souborů, a tak ten, kdo nechce používat klikací rozhraní pro konfiguraci programu, má smůlu.
Nedostatečná bývá nejen uživatelská, ale v ještě větší míře i programátorská dokumentace. Řada programátorů se bohužel mylně domnívá, že rozumně strukturovaný a komentovaný zdrojový text je dostatečnou programátorskou dokumentací. Zvláště špatné je, když neexistuje kompletní specifikace rozhraní nějakého modulu nebo knihovny a programátor musí jeho fungování luštit ze zdrojového kódu, místo aby se soustředil na vývoj svého programu. Navíc pak není vždy jasné, co je správné chování nějaké funkce a co chyba nebo implementační detail, který se může v další verzi změnit. Právě rozdíly v úrovni dokumentace jsou jedním z hlavních důvodů, proč se mi Qt líbí víc než GTK+.
Grafické a textové rozhraní
Pod pojmem textové nebo řádkové rozhraní zde mám na mysli ovládání programu pomocí parametrů na příkazové řádce a textových příkazů. Program, bežící sice v textovém režimu, ale používající ovládání pomocí menu a myši, se od plně grafických programů liší pouze méně atraktivním vzhledem, nikoliv stylem fungování.
Mezi uživateli počítačů je rozšířeno přesvědčení, že příkazový řádek je čímsi zastaralým a kvalitní moderní program musí mít grafické rozhraní. Zastánci tohoto názoru říkají, že GUI má výhodu v tom, že je snadné na naučení a uživatelsky přívětivé. První tvrzení je obvykle pravdivé, druhé však ne vždy. Grafické rozhraní umožňuje snadno provádět jednotlivé operace, pro něž existují položky menu. Problém nastane, když je potřeba provést komplexnější nebo opakovanou operaci. Z uživatele se pak stává cvičená opice, která opakovaně mechanicky kliká na stejné položky menu a vyplňuje stejné dialogy.
Představme si, že v grafickém editoru chceme změnit velikost obrázku. Vybereme v menu položku „Open“ a v dialogovém okně vybereme soubor s obrázkem. Po otevření souboru najdeme v menu funkci „Resize“, která si ještě otevře dialog pro zadání nové velikosti obrázku. Celou akci završíme kliknutím na „Save“. Potud je všechno v pořádku. Ovšem co když takto chceme upravit ne jeden, ale sto obrázků? V tu chvíli je lepší vrátit se k řádkovým utilitám a shellu. Změnu velikosti všech obrázků provedeme jediným příkazem
for f in *.jpg; do convert $f -resize 800x600 resized$f; done
Lze samozřejmě namítnout, že taková hromadná operace je často používaná, a proto ji leckterý grafický editor umí udělat tak, že si uživatel vybere seznam souborů a nechá provést požadovanou operaci na všechny. Jenomže množina funkcí programu je vždy omezená. Na druhou stranu řádkové programy mohou být pomocí shellu neomezeně kombinovány. Textové ovládání může být pro zkušeného uživatele příjemnější i pro provádění jednotlivých akcí. Napsat příkaz s parametry je totiž často rychlejší než vybrat položku z rozvětvené struktury menu a vyplnit parametry v dialogovém okně. To asi potvrdí každý znalec TeXu, který se kdy pokoušel vyrobit vzorec pomocí myši v editoru rovnic z MS nebo Open Office. I textové programy, které interaktivně komunikují s uživatelem, lze spouštět dávkově s použitím nástrojů jako je expect.
Další oblastí, kde grafické rozhraní často selhává, je manipulace s konfigurací programů. Uživatel je odkázán na sadu dialogů, kde může nastavovat jednotlivé konfigurační hodnoty, což vypadá na první pohled dobře, avšak najít určitou položku nebo nastavit množinu položek na stejnou hodnotu v rozsáhlé konfiguraci nemusí být snadné. S textovým konfiguračním souborem takový problém odpadá, protože stačí v textovém editoru použít funkci pro hledání a nahrazování textu. Velmi užitečné je zaznamenávat posloupnost změn v konfiguraci, archivovat její jednotlivé verze a umět zobrazit rozdíly mezi nimi. S graficky ovládanou konfigurací ukládanou do kdovíjakých binárních souborů to je obtížné. Při použití textových konfiguračních souborů stačí nainstalovat si RCS a po každé úpravě některého souboru napsat
ci -l soubor
Celkově se o mnohých programech s grafickým uživatelským rozhraním dá říct, že i když se snaží působit profesionálně, jsou to ve skutečnosti amatérské nástroje. Amatér, který věci příliš nerozumí a nehodlá se moc učit, potřebuje nástroj, který je jednoduchý. Přitom mu nevadí, že tento nástroj je dost omezený. Profesionál, jenž se svým nástrojem pracuje denně, se ho bude raději déle učit používat, když to bude vyváženo vyšší efektivitou práce s ním.
Samozřejmě existují programy, u nichž má čistě grafické rozhraní dobrý smysl. Naopak u některých programů nemá GUI smysl vůbec žádný. U velkého množství aplikací je však nejlepší spojit oba způsoby ovládání – grafický i textový. Uživatel tak může s programem začít snadno pracovat pomocí funkcí dostupných v menu a postupně se podle potřeby učit řádkové rozhraní poskytující přístup k pokročilejším schopnostem programu.
Dobrým příkladem kombinace textového a grafického rozhraní je debugger ddd. Ve skutečnosti je to Xová nadstavba nad řádkovým debuggerem gdb. Umožňuje v jednom okně zobrazovat zdrojový text a nastavovat breakpointy, v dalším okně zobrazovat hodnoty proměnných, operace jako spuštění, přerušení a krokování programu jsou dostupné pomocí tlačítek. Ale má také textové okno, v němž lze psát příkazy progdb. Dalším příkladem úspěšné kombinace obou přístupů k uživatelskému rozhraní je textový editor gvim.
Každý program v X by měl dovolit nastavení alespoň základních parametrů na příkazovém řádku. Jedná se např. o identifikaci displeje (X serveru), k němuž se má program připojit, nebo o seznam souborů, se kterými bude pracovat. Užitečné je, když se dá program spustit v dávkovém režimu tak, že provede akce specifikované na příkazovém řádku a skončí. Nejlepší je přidat ke grafickému programu možnost skriptování, tj. propojit ho s interpretem nějakého programovacího jazyka a vyexportovat do interpretu pro použití ve skriptech pokud možno veškeré operace, jež program umí dělat.
Závěr
Tento seriál článků si v žádném případě nekladl za cíl být vyčerpávajícím návodem na psaní programů pro X Window System. Šlo mi o to, ukázat základní informace o X z pohledu programátora. Úvod do GTK+, Qt a Xlib by měl usnadnit čtenáři orientaci v dané problematice a poskytnout východisko k dalšímu samostatnému studiu a experimentování. Na mé webové stránce www.ms.mff.cuni.cz/~beran/vyuka/X/ jsou k dispozici poznámky k přednáškám, z nichž jsem vycházel při psaní článků. Nemají sice formu souvislého textu, avšak místy jdou více do podrobností. Na stejné stránce lze najít i sadu ukázkových programů demonstrujících možnosti obou probíraných toolkitů i Xlib a odkazy na některé internetové zdroje o X.
K dispozici je též archiv celého seriálu.