Návrh typu Model/Zobrazení/Ovládání (Python) Návrh typu Model/Zobrazení/Ovládání Sebastian Pölsterl sebp@k-d-w.org 2011 Marta Maria Casetti mmcasetti@gmail.com 2012 Návrh typu Model/Zobrazení/Ovládání
Přehled

Widgety TreeView i ComboBox jsou postaveny na návrhu Model/Zobrazení/Ovládání. Model (implementace Gtk.TreeModel, obvykle Gtk.TreeStore nebo Gtk.ListStore) uchovává data, Zobrazení (např. Gtk.TreeView, Gtk.ComboBox nebo Gtk.ComboBoxText) přijímá upozornění a zobrazuje obsah modelu. A konečně Ovládání mění stav modelu (přes některé metody, které model implementuje, jako je append() nebo remove()) a upozorňuje zobrazení na tyto změny (pomocí signálu, jako je "changed").

Model

Hlavní rozdíl mezi dvěma hlavními implementacemi Gtk.TreeModel je, že Gtk.ListStore obsahuje jednoduché řádky dat bez potomků, zatímco Gtk.TreeStore obsahuje sice také řádky dat, ale každý řádek může mít synovské řádky (a ty také mohou mít synovské řádky a tak dále).

Data v modelu mohou být získána nebo změněna pomocí stromového iterátoru a sloupcového indexu nebo metody Gtk.TreeIter nebo Gtk.TreePath.

Stejně jako u objektů typu seznam vestavěných v jazyce Python, můžete použít len() k získání počtu řádků a „slice“ (řez) k získání nebo nastavení hodnot. Jinak metoda append() vrací instanci Gtk.TreeIter, která ukazuje na místo, kam byl nový řádek vložen. Gtk.TreeIter můžete získat i zavoláním get_iter().

Protože Gtk.ListStore obsahuje jen jednu úroveň, tj. uzly nemají žádné potomky, je cesta v podstatě jen index řádku, ke kterému chcete přístup. V případě Gtk.TreeStore je cesta seznam indexů nebo řetězec. Forma řetězce je seznam čísel oddělených dvojtečkami. Každé číslo odkazuje na pořadí v dané úrovni. Takže cesta "0" odkazuje na kořenový uzel a cesta "2:4" odkazuje na pátého potomka třetího uzlu.

Užitečné metody pro Gtk.TreeModel:

get_iter(cesta) vrací instanci Gtk.TreeIter ukazující na cestu. Ta je očekávána v podobě seznamu čísel oddělovaného dvojtečkou nebo n-tice. Například řetězec "10:4:0" je stejná cesta jako n-tice (10, 4, 0), protože obojí vytvoří cestu do hloubky 3. úrovně k 11. potomku od kořene, 5. pátému potomku jedenáctého potomka a 1. potomku pátého potomka.

iter_next(stromový_iterátor) vrací instanci Gtk.TreeIter ukazující na uzel následující za stromovým_iterátorem v aktuální úrovni nebo None, pokud tam již další není.

iter_has_child(stromový_iterátor) vrací True jestliže má stromový_iterátor potomky, jinak False.

iter_children(stromový_iterátor) vrací instanci Gtk.TreeIter ukazující na prvního potomka stromového_iterátoru nebo None, když žádného potomka nemá.

get_iter_first() vrací instanci Gtk.TreeIter, která ukazuje na první iterátor ve stromu (tj. na cestě "0") nebo None, pokud je strom prázdný.

Užitečné metody pro Gtk.ListStore:

append(řádek) připojí nový řádek do ListStore, kde řádek může být seznam hodnot pro každý ze sloupců nebo může být řádek vynechán či None a pak bude připojen prázdný řádek. Tato metoda vrací Gtk.TreeIter ukazující na připojený řádek.

remove(iterátor) odstraní iterátor z Gtk.ListStore a vrátí True jestliže je iterátor platný nebo False jestliže není. Po odstranění je iterátor nastaven na následující platný řádek.

Užitečné metody pro Gtk.TreeStore:

append(rodič, řádek) přidá do stromového úložiště nový řádek. Argument rodič musí být platný Gtk.TreeIter. Když rodič není None, bude nový řádek přidán za posledního potomka rodiče, jinak bude přidán do nejvyšší úrovně. Argument řádek může být seznam hodnot pro jednotlivé sloupce nebo může být vynechán nebo None. V posledních dvou zmíněných případech bude připojen prázdný řádek. Metoda vrací Gtk.TreeIter ukazující na připojený řádek.

remove(iterátor) odstraní iterátor z Gtk.ListStore a vrátí True jestliže je iterátor platný nebo False jestliže není. Po odstranění je iterátor nastaven na následující platný řádek.

Zobrazení: případ TreeView

TreeView zobrazuje strukturu dceřiných a rodičovských položek v podobě stromu. Viz třeba tento příklad.

Gtk.TreeViewColumn je použito k uspořádání svislých sloupců.

Užitečné metody pro Gtk.TreeView:

set_model(model) nastaví model pro toto stromové zobrazení. Pokud již nějaký model nastavené má, tak ten bude nejdříve odebrán. Jestliže je model None, tak se zruší nastavení starého modelu.

get_model() vrací model, na kterém je strom založen, None, když model není nastaven.

append_column(sloupec) připojí sloupec do seznamu sloupců.

get_selection() vrací Gtk.TreeSelection přidružené k tomuto stromovému zobrazení.

Užitečné metody pro Gtk.TreeViewColumn:

add_attribute(vykreslovač, atribut, hodnota) přidá mapování atributu na tento sloupec. atribut je parametr vykreslovače, který má být nastaven na hodnotu.

pack_start(vykreslovač, roztáhnout) zabalí vykreslovač do začátku tohoto sloupce. Když je roztáhnout nastaveno na False, nebude si vykreslovač nárokovat víc místa, než potřebuje. Veškeré nevyužité místo je rovnoměrně rozděleno mezi buňky, kterém mají tento parametr nastavený na True.

pack_end(vykreslovač, roztáhnout) zabalí vykreslovač do konce tohoto sloupce. Když je roztáhnout nastaveno na False, nebude si vykreslovač nárokovat víc místa, než potřebuje. Veškeré nevyužité místo je rovnoměrně rozděleno mezi buňky, kterém mají tento parametr nastavený na True.

set_sort_column_id(id_slupce_řazení) nastaví sloupec z modelu, podle kterého by se měl tento sloupec (v zobrazení) řadit. Rovněž to zpřístupní záhlaví sloupce pro kliknutí.

set_sort_indicator(nastavení) nastaví, jestli se má v záhlaví sloupce zobrazovat malá šipka. Argument nastavení může být True (indikátor je zobrazen) nebo False.

set_sort_order(pořadí) změní pořadí, ve kterém je sloupec seřazen. pořadí může být Gtk.SortType.ASCENDING (vzestupné) nebo Gtk.SortType.DESCENDING (sestupné).

Zobrazení: případ ComboBox

Gtk.ComboBox poskytuje výběr z položek v rozbalovací nabídce, viz třeba tento příklad. Pro seznam s čistě textovými položkami lze použít také jednodušší Gtk.ComboBoxText. Obě verze mohou obsahovat vstupní pole.

Užitečné metody pro Gtk.ComboBox:

Statická metoda new_with_entry() vytvoří nový prázdný Gtk.ComboBox se vstupním polem. Statická metoda new_with_model(model) jej vytvoří s modelem inicializovaným na model. A statická metodat new_with_model_and_entry(model) je kombinací dvou předchozích.

get_active_iter() vrací Gtk.TreeIter ukazující na právě aktivní položku. Pokud žádná aktivní položka neexistuje, je vráceno None.

set_model(model) nastaví model použitý tímto rozbalovacím seznamem na model a zruší nastavení předchozího nastaveného modelu (pokud nějaký byl). Pokud je model None, bude jen zrušeno nastavení předchozího. Upozorňujeme, že tato funkce nemaže vykreslovače buněk.

set_entry_text_column(textový_sloupec) nastavuje sloupec modelu, který by měl tento rozbalovací seznam použít k získávání řetězců, na textový_sloupec. Tento sloupec musí být typu str (to platí v případě, že rozbalovací seznam byl vytvořen s vlastností "has-entry" nastavenou na True).

set_wrap_width(šířka) nastavuje šířku zalamování rozbalovacího seznamu na šířka. Jedná se v zásadě o upřednostňovaný počet sloupců, když chcete, aby byl rozbalený seznam rozvržen do mřížky.

Užitečné metody pro Gtk.ComboBoxText:

Statická metoda new_with_entry() vytvoří nový prázdný Gtk.ComboBoxText se vstupním polem.

append_text(text) připojí text do seznamu řetězců uchovaných v tomto rozbalovacím seznamu.

get_active_text() vrací aktuálně aktivní řetězec v rozbalovacím seznamu nebo None, když není nic vybráno. V případě, kdy má rozbalovací seznam vstupní pole, vrací tato funkce obsah tohoto pole (což nutně nemusí být žádná položka ze seznamu).

Zobrazení: vykreslování buněk

K vykreslení různých typů dat používá View objekty Gtk.CellRenderer.

Implementace Gtk.CellRenderer a užitečných metod:

Gtk.CellRendererText – vykresluje text v buňce.

Gtk.CellRendererToggle – vykresluje v buňce přepínací tlačítko nebo skupinový přepínač. Užitečné metody:

set_active(nastavení) – aktivuje nebo deaktivuje vykreslování buňky

get_active() – vrací, jestli je vykreslování buňky aktivní

set_radio(skupinový_přepínač) – pokud je skupinový_přepínač True, bude vykreslovač buňky vykreslovat skupinový přepínač (tj. navzájem se vylučující přepínače), pokud je False, bude se vykreslovat zaškrtávací políčko (samostatná volba)

get_radio() – vrací, jestli vykreslujeme skupinové přepínače místo zaškrtávacích políček.

Gtk.CellRendererPixbuf – vykresluje obrázek v buňce

Gtk.CellRendererCombo – vykresluje v buňce text; ale zatímco Gtk.CellRendererText poskytuje jednoduché vstupní pole pro úpravu textu, Gtk.CellRendererCombo poskytuje pro úpravu textu widget Gtk.ComboBox. Ten lze použít s nebo bez přidruženého widgetu Gtk.Entry, v závislosti na vlastnosti "has-entry".

Gtk.CellRendererProgress – vykresluje v buňce číselnou hodnotu v podobě ukazatele průběhu; nad ukazatelem může zobrazit text

Gtk.CellRendererSpinner – vykresluje v buňce animovanou káču

Gtk.CellRendererSpin – vykresluje v buňce číselník

Gtk.CellRendererAccel – vykresluje v buňce klávesovou zkratku

Ovládání: výběr

Většina aplikací potřebuje používat nejen zobrazení dat, ale i přijímat vstupní události od uživatelů. To udělají jednoduše tak, že získají odkaz na objekt s výběrem a napojí se na signál "changed".

select = tree.get_selection() select.connect("changed", on_tree_selection_changed)

Pak k získání dat pro vybraný řádek:

def on_tree_selection_changed(selection): model, treeiter = selection.get_selected() if treeiter != None: print "You selected", model[treeiter][0]

Užitečné metody pro Gtk.TreeSelection:

set_mode(typ) nastaví typ výběru, kde typ může být něco z

Gtk.SelectionMode.NONE – není možný žádný výběr

Gtk.SelectionMode.SINGLE – může být vybrán žádný nebo jeden prvek

Gtk.SelectionMode.BROWSE – je vybrán právě jeden prvek. V některých případech, jako na počátku nebo v průběhu vyhledávání, je možné, aby nebyl vybrán žádný prvek. To, co je opravdu vynucováno, je, že uživatel nemůže zrušit výběr aktuálně vybraného prvku, jedině může vybrat jiný.

Gtk.SelectionMode.MULTIPLE – může být vybrán libovolný počet prvků. Kliknutí přepne stav položky. Klávesu Ctrl lze používat k přidávání výběru a klávesu Shift k výběru rozsahu mezi zaměřenou a kliknutou položkou. Některé widgety mohou umožňovat výběr rozsahu prvků i postupem „klikni a táhni“.

get_selected() vrací dvojici (model, stromový_iterátor), kde model je aktuální model a stromový_iterátor je Gtk.TreeIter ukazující na aktuálně vybraný řádek nebo None, když není žádný řádek vybrán. Metoda nepracuje, když je režim výběru nastaven na Gtk.SelectionMode.MULTIPLE. V tomto případě použijte místo toho get_selected_rows(), která vrací seznam instancí Gtk.TreePath se všemi vybranými řádky.

Odkazy

GtkTreeModel

GtkTreeView

GtkTreeViewColumn

GtkComboBox

GtkCellRenderer