hoffstadt / DearPyGui

Dear PyGui: A fast and powerful Graphical User Interface Toolkit for Python with minimal dependencies
https://dearpygui.readthedocs.io/en/latest/
MIT License
12.62k stars 669 forks source link

set_value to call item's callback #2210

Open cromachina opened 8 months ago

cromachina commented 8 months ago

Is your feature request related to a problem? Please describe.

DearPyGui version: 1.10.1

I would like to update some other field, like a text field based on the result of a file dialog, for example. However, when the text field is updated, its callback will do some extra processing, like saving the value to some preferences object.

Currently, the file dialog's ok callback will call set_value on the text field, but the text field's callback is not called.

Describe the solution you'd like

A keyword option in set_value such that it calls the item's callback:

dpg.set_value(text_field, 'foo', notify=True)

Or maybe a separate function:

dpg.notify_value(text_field, 'foo')

Describe alternatives you've considered

notify_value could possibly be implemented like this by a user, but then the callback is not called from DPG's worker thread:

import dearpygui.dearpygui as dpg
import inspect

def notify_value(item, value):
    dpg.set_value(item, value)
    cb = dpg.get_item_callback(item)
    if cb is not None:
        args = (item, value, dpg.get_item_user_data(item))[:len(inspect.signature(cb).parameters)]
        cb(*args)

dpg.create_context()
dpg.create_viewport(title='test', width=600, height=600)
dpg.setup_dearpygui()

def on_text_update(sender, app_data):
    print('I was updated!', sender, app_data)
    # Save updated value to preferences object, for example...

def on_ok_click():
    notify_value(text_field, 'foo')

with dpg.window(tag='window'):
    text_field = dpg.add_input_text(label='File', callback=on_text_update)
    dpg.add_button(label='Simulate File Dialog Finished', callback=on_ok_click)

dpg.show_viewport()
dpg.set_primary_window('window', True)
dpg.start_dearpygui()
dpg.destroy_context()
v-ein commented 8 months ago

Callbacks are intended for your code to react to user actions - i.e. to something outside of your control. From your app's point of view, such events occur at random moments, and you have no a priori knowledge on when something is going to occur. That's why we have to use callbacks for that.

However, when your own code calls set_value, it is entirely under your control and you know exactly when (or where in the code) this is going to happen. There's no need for a callback - you can explicitly call the same function as you have specified as the callback. If needed, you can provide it with extra info to differentiate between user action and programmatic change.

Doing something like this on DPG side is possible, but brings little value as compared to extra complexity in the API and implementation. It's just not worth it. To give you a little exaggerated analogy, it's like requesting a filesystem driver to be able to parse JPEG files on its own, and return uncompressed bitmap image. While it's possible, none of filesystem vendors would agree to do that, because it is application's responsibility, not driver's, to decode file contents.

v-ein commented 7 months ago

Is there any reason this ticket stays open?

v-ein commented 7 months ago

@cromachina have you had a chance to read my comments? Do you need more help, explanation or something?

cromachina commented 7 months ago

If you are a maintainer, then you should close it as "wont fix", if you don't want to implement such a change. I have nothing else to add to this issue. Thank you for your consideration.

stevewells20 commented 1 week ago

@v-ein, I understand your point of view, but you are arguing in favor of opinionated personal principles over usability. The point of callbacks is to tie a event to an action. You pointed out user-actions, which are only one of many examples of an event. You argue that DPG should only support an event if it is user generated, which is a highly opinionated take on this, one that many will not share.

I think it makes much more sense to allow (not force) a callback trigger when the value of a widget is changed. Right now you are arguing that it is better to force programmers to not be able to do this, and your reasoning for that is it "brings little value as compared to extra complexity in the API and implementation. It's just not worth it."; it doesn't bring value to you, but does it bring value to others? And I'd love to know why you think that implementing a function such as "notify_value" would add significant complexity to the API? In evaluating it, what points of complexity did you identify it as creating?

I understand that this feature would not fit into your style of programming, but trying to shut down conversation around it so aggressively seems like quite an over-reaction.