Python Forum
Can tkinter monitor dictionary
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Can tkinter monitor dictionary
#3
I guess you want to change the minimal amount of code to your existing program. It could be as simple as using a subclass of dict for the variable that you are observing. For example with the MyDict class below, all the changes to the dictionary will trigger a printed message. You don't need to change anything to the existing code. Just inject the MyDict object where it is needed.

You can then update a GUI instead of printing messages.
__version__ = '2020.06.21'
sentinel = object()

class Observer:
    def on_item_added(self, k, v):
        print('added item', k, v)

    def on_value_changed(self, k, v, old):
        print('value changed', k, v, old)

    def on_item_removed(self, k, v):
        print('item removed', k, v)

    def on_cleared(self):
        print('dict cleared')
    

class MyDict(dict, Observer):
    def __setitem__(self, k, v):
        w = super().get(k, sentinel)
        super().__setitem__(k, v)
        if w is sentinel:
            self.on_item_added(k, v)
        else:
            self.on_value_changed(k, v, w)

    def __delitem__(self, k):
        self.pop(k)

    def clear(self):
        super().clear()
        self.on_cleared()

    def pop(self, k, d=sentinel):
        try:
            v = super().pop(k)
        except ValueError:
            if d is sentinel:
                raise
            else:
                return d
        else:
            self.on_item_removed(k, v)
            return v

    def popitem(self):
        k, v = super().popitem()
        self.on_item_removed(k, v)
        return (k, v)
    
    def update(self, *args, **kwargs):
        if args:
            if len(args) != 1:
                raise TypeError(
                    'update expected at most 1 argument, got', len(args))
            E = args[0]
            if hasattr(E, 'keys'):
                for k in E:
                    self[k] = E[k]
            else:
                for k, v in E:
                    self[k] = v
        for k in kwargs:
            self[k] = kwargs[k]

    def setdefault(self, k, d=None):
        if k not in self:
            self[k] = d
        return self[k]
 
if __name__ == '__main__':
    d = MyDict()
    # This code is exactly the same as in an ordinary dictionary.
    d[3] = "foo"
    d.update({4:'bar', 5:'spam'})
    del d[4]
    d.clear()
    d.setdefault(8, 'eggs')
    d[8] = 9
Output:
added item 3 foo added item 4 bar added item 5 spam item removed 4 bar dict cleared added item 8 eggs value changed 8 9 eggs
Reply


Messages In This Thread
Can tkinter monitor dictionary - by personalt - Jun-20-2020, 12:09 PM
RE: Can tkinter monitor dictionary - by menator01 - Jun-20-2020, 02:06 PM
RE: Can tkinter monitor dictionary - by Gribouillis - Jun-20-2020, 02:41 PM
RE: Can tkinter monitor dictionary - by personalt - Jun-21-2020, 04:35 PM
RE: Can tkinter monitor dictionary - by Gribouillis - Jun-21-2020, 05:07 PM
RE: Can tkinter monitor dictionary - by personalt - Jul-07-2020, 12:41 AM
RE: Can tkinter monitor dictionary - by deanhystad - Jul-07-2020, 03:51 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020