Source code for teek.extras.more_dialogs

import teek


class _EntryDialog:

    def __init__(self, title, text, entry_creator, validator,
                 initial_value, parent):
        self.validator = validator

        self.window = teek.Window(title)
        self.window.on_delete_window.connect(self.on_cancel)
        if parent is not None:
            self.window.transient = parent

        self.var = teek.StringVar()

        teek.Label(self.window, text).grid(row=0, column=0, columnspan=2)
        entry = entry_creator(self.window)
        entry.config['textvariable'] = self.var
        entry.grid(row=1, column=0, columnspan=2)
        entry.bind('<Return>', self.on_ok)
        entry.bind('<Escape>', self.on_cancel)

        self.ok_button = teek.Button(self.window, "OK", self.on_ok)
        self.ok_button.grid(row=3, column=0)
        teek.Button(self.window, "Cancel", self.on_cancel).grid(
            row=3, column=1)

        self.window.grid_rows[0].config['weight'] = 1
        self.window.grid_rows[2].config['weight'] = 1
        for column in self.window.grid_columns:
            column.config['weight'] = 1

        self.result = None
        self.var.write_trace.connect(self.on_var_changed)
        self.var.set(initial_value)
        self.on_var_changed(self.var)   # TODO: is this needed?

        # TODO: add a way to select stuff to teek
        self.window.geometry(300, 150)
        entry.focus()
        teek.tcl_call(None, entry, 'selection', 'range', '0', 'end')

    def on_var_changed(self, var):
        result = self.var.get()
        try:
            self.result = self.validator(result)
            self.ok_button.config['state'] = 'normal'
        except ValueError:
            self.result = None
            self.ok_button.config['state'] = 'disabled'

    def on_ok(self):
        # this state check is needed because <Return> is bound to this, and
        # that binding can run even if the button is disabled
        if self.ok_button.config['state'] == 'normal':
            self.window.destroy()

    def on_cancel(self):
        self.result = None
        self.window.destroy()

    def run(self):
        self.window.wait_window()
        return self.result


[docs]def ask_string(title, text, *, validator=str, initial_value='', parent=None): """Displays a dialog that contains a :class:`teek.Entry` widget. The ``validator`` should be a function that takes a string as an argument, and returns something useful (see below). By default, it returns the string unchanged, which is useful for asking a string from the user. If the validator raises :exc:`ValueError`, the OK button of the dialog is disabled to tell the user that the value they entered is invalid. Then the user needs to enter a valid value or cancel the dialog. This returns whatever ``validator`` returned, or ``None`` if the dialog was canceled. """ return _EntryDialog(title, text, teek.Entry, validator, initial_value, parent).run()
[docs]def ask_integer(title, text, allowed_values, *, initial_value=None, parent=None): """Displays a dialog that contains a :class:`teek.Spinbox` widget. ``allowed_values`` can be a sequence of acceptable integers or a :class:`range`. If ``initial_value`` is given, it must be in ``allowed_values``. If it's not, ``allowed_values[0]`` is used. This returns an integer in ``allowed_values``, or ``None`` if the user cancels. """ def creator(spinbox_parent): if isinstance(allowed_values, range): # range(blah, blah, 0) raises an error, so the step can't be zero if allowed_values.step < 0: raise ValueError( "ranges with negative steps are not supported") # allowed_values.stop is not same as allowed_values[-1], the -1 one # is inclusive return teek.Spinbox( spinbox_parent, from_=allowed_values[0], to=allowed_values[-1], increment=allowed_values.step) return teek.Spinbox(spinbox_parent, values=allowed_values) def validator(value): int_value = int(value) if int_value not in allowed_values: raise ValueError return int_value if initial_value is None: initial_value = allowed_values[0] elif initial_value not in allowed_values: raise ValueError("initial value %r not in %r" % (initial_value, allowed_values)) return _EntryDialog(title, text, creator, validator, initial_value, parent).run()