robertlugg / easygui

easygui for Python
http://easygui.readthedocs.org/en/master/
BSD 3-Clause "New" or "Revised" License
457 stars 116 forks source link

Enhancement #111: Accept dict to support separate choice text and returned values #112

Closed spyoungtech closed 8 years ago

spyoungtech commented 8 years ago

This enhancement makes a change to the buttonbox choicebox and multchoicebox functions so that a dict-like object can be passed into the choices parameter, where the keys represent the text of the choice to be displayed and the corresponding values are returned when that choice is selected, I.E. choices = {choice_text: return_value} See #111 for more detail.

This change should make it easier to get the desired values returned from dialogs, rather than needing to convert responses into appropriate values. It also allows for changing the button text and hotkeys easily, without altering the returned value and subsequent programming logic. (see #111 for more detail)

One caveat is that dictionaries do not preserve order. So if choices need to preserve order, an OrderedDict should be used. In Python 3.6 all dicts will be ordered, but OrderedDict should still be used for backwards compatibility.

The following is an example that uses this feature to replicate ccbox and indexbox boxes.

import easygui
from collections import OrderedDict

#CCbox
choices = {"C[o]ntinue": True, "C[a]ncel": False}
cc = easygui.buttonbox(msg="Shall I continue?", choices=choices)

#indexbox
choices = OrderedDict((item, index) for index, item in enumerate(["zero", "one", "two", "three"]))
choice_index = easygui.buttonbox(msg="Choose something", choices=choices)

If cancel_choice is received in a buttonbox reply, if cancel_choice is a key in the choices dict, the value of choices[reply] will be returned, else cancel_choice is returned. Similarly, if None is received by a choicebox or multchoicebox, if None is a key in choices choices[None] is returned, otherwise None is returned. I believe this is a sensible behavior, but am not opposed to changes.

If accepted, the docstrings for these functions should reflect the change and demos should be provided. I can push that change out as well if desired.

spyoungtech commented 8 years ago

Gotcha. I originally did just that, but ultimately decided to put it up at the function mainly for readability and simplicity. I'll make the change and implement it in the ButtonBox/ChoiceBox classes.

spyoungtech commented 8 years ago

@jjdenis I pushed those changes there. Check it out and let me know what you think.

jjdenis commented 8 years ago

Hello @spyoungtech ! I have pushed your changes to the branch called 'develop'.

I have also done some refactoring so the code is easier to read, modify and, hopefully, re-refactor.

I have also streamlined and demoed its use with callbacks.

Feedback would be greatly appreciated, @robertlugg.

I have tested the code in linux, but testing in osx and windows would be greatly appreciated too.