peterbrittain / asciimatics

A cross platform package to do curses-like operations, plus higher level APIs and widgets to create text UIs and ASCII art animations
Apache License 2.0
3.62k stars 237 forks source link

Adding a parameter for the Widget event #335

Closed DaveMaks closed 2 years ago

DaveMaks commented 2 years ago

Hey! Very cool library There is a proposal in Widget to add the name of the called object to the callbacks. Thus, it will be possible to dynamically create fields and manage all with one callback)

https://github.com/peterbrittain/asciimatics/blob/770a097cb532cc1fdbcf5f7889bfcdeeddd92b3c/asciimatics/widgets/text.py#L184-L185

adding only one parameter

if old_value != self._value and self._on_change:
            self._on_change(self)

Thank you!

peterbrittain commented 2 years ago

Thanks.

Just a quick question: why not use a method on the object for the callback instead of passing in a separate function (that then needs the reference to the object to interact with it)?

DaveMaks commented 2 years ago

Probably because I'm just learning Python) Are you talking about such a decision?

def __init__(self, screen, config: ConfigModel):
...
        for i in range(0, 10):
                layout.add_widget(Text("Text " + i+":", "txtBox_" + i, on_change=self._change_txtBox))
...
  def _change_txtBox(self):
        self.save()

then it will return a Frame object

Alternative way to manipulate an object:

    def _change_txtBox(self, obj: Text):
        self.save()
        try:
            data = int(self.data[obj.name])
            if (data > 99999):
                raise Exception("loooong...")
        except Exception as ex:
            obj.value = str(99999)
            obj._is_valid = False
peterbrittain commented 2 years ago

Ok... I see now. I suspect that this comes down to the wider state you want to enforce in the callback. Typically, I'd expect you to want to handle state across multiple objects and so passing the changed widget is of little benefit.

Looking at your example, if you just need to enforce limits on the entered text, why not use a validator? See forms.py for an example of how to use them.

However, there are some other use cases you might need. LMK if you have something else in mind and I'll see how we can tweak something...

peterbrittain commented 2 years ago

Did the validator give you what you need? I'll leave this open a few more days for you to experiment and then close if I hear nothing...

peterbrittain commented 2 years ago

I'm assuming the validator did the trick. Please feel free to re-open if not...