Bez modelu

18. 8. 2014 19:48 (aktualizováno) Petr Blahoš

Nejprve bych rád poděkoval pajovi, který mě svými komentáři navedl na deskriptory. Vypadá to, že dost zjednoduší zápis. Ale o tom až jindy. Minule jsem slíbil, že vyzkouším jiný přístup, kdy view se tváří jako model. Můžeme jít na to: sidestep01.

Tentokrát tedy nebudeme dělat žádný oddělený model, ale naše okno naučíme normálně reagovat na přiřazení, ať už jako levou nebo pravou stranu. Server si necháme, a zase budeme chtít zobrazit 2 tabulky, jednu s postupem, druhou s opravdu provedenými operacemi. Cílem je opět to, abychom název a sériové číslo výrobku změnili přiřazením do view.article a view.sn, a s operacema či postupem manipulovali normálníma operacema jako nad listem. Hodnoty nebudeme uchovávat bokem, ale přímo v těch ovládacích prvcích. Třeba jako tady:

class MVCList(wx.ListView):
    def __init__(self, parent, id, style, columns,):
        # [...] zkráceno
        self.client_objects = {}
    def __getitem__(self, key):
        return self.client_objects[self.GetItemData(key)]
    def __setitem__(self, key, value):
        del self.client_objects[self.GetItemData(key)]
        self.client_objects[id(value)] = value
        self.SetItemData(key, id(value))
        self.set_item(key, value)
    def insert(self, key, value):
        self.InsertStringItem(key, str(value))
        self.client_objects[id(value)] = value
        self.SetItemData(key, id(value))
        self.set_item(key, value)
    def set_item(self, key, value):
        for (i, val) in enumerate(value):
            self.SetStringItem(key, i, str(val))
    def DeleteAllItems(self):
        super(MVCList, self).DeleteAllItems()
        self.client_objects.clear()
    # [...] zkráceno

Naimplementoval jsem přiřazení, mazání a přístup k prvkům pomocí [], insert, append, len. Neumí to slicy, pouze diskrétní indexy, a pokud použijete slice, tak vám to ani nevynadá, takže to nepoužívejte vůbec – je to jen na ukázku. Každopádně, když uděláme

    list.append(("Value1", "Value2", 543))
tak nám to na konec tabulky přidá řádek, del[5] smaže pátý řádek, a tak podobně.

Zbytek dělám přímo v tom hlavním okně:

    @property
    def article(self):
        return self._article.GetLabel()
    @article.setter
    def article(self, val):
        self._article.SetLabel(str(val))

Vytažení hodnoty article a nastavení hodnoty, takže můžeme dělat:

view.article = "SUPERPRODUCT01"
view.sn = 324
# nebo třeba
save_record(view.article, view.sn, view.operations)

Pro zajímavost ještě getter a setter pro list:

    @property
    def process(self):
        return self.proc_view
    @process.setter
    def process(self, val):
        self.proc_view.DeleteAllItems()
        for i in val:
            self.proc_view.append(i)

Když se podívám na výsledek, tak jsem skoro v tom stavu, který jsem chtěl. Výrobek nastavím takto:

    def set_random_product(self):
        self.article = "AAAQA%s" % random.randint(0, 9)
        self.sn = random.randint(1, 1000)

        self.process = self.server.get_process(self.article, self.sn)
        self.operations = self.server.get_product_ops(self.article, self.sn)
Přidávání a mazání operací je podobné, jako ve verzi s „horkým“ modelem.

Nemám počítadla pod tabulkama. Podle mě jediný rozumný způsob jak je udělat by bylo implementovat si „složený“ ovládací prvek, který by obsahoval tabulku a počítadlo. Protože jinak si budu muset kdo ví jak a kdo ví kde všude hlídat, jestli se v self.process nebo self.operations něco nezměnilo.

Tak tedy, dá se to použít, ale nezbavuje mě to nutnosti hlídat si, co všechno je třeba třeba udělat když se změní …

Sdílet