def __init__(self, widget: tkinter.Widget, text: str) -> None: widget.bind("<Enter>", self.enter, add=True) widget.bind("<Leave>", self.leave, add=True) widget.bind("<Motion>", self.motion, add=True) self.widget = widget self.got_mouse = False self.text = text # can be changed after creating tooltip manager
def __init__(self, widget: tkinter.Widget) -> None: widget.bind('<Enter>', self.enter, add=True) widget.bind('<Leave>', self.leave, add=True) widget.bind('<Motion>', self.motion, add=True) self.widget = widget self.got_mouse = False self.text: Optional[str] = None
def bind_ci(widget: tk.Widget, all_: bool = False, *, modifier: str = '', letter: str, callback, add: bool = False): if modifier and letter: modifier += '-' if all_: widget.bind_all(f'<{modifier}{letter.lower()}>', callback, add) widget.bind_all(f'<{modifier}{letter.upper()}>', callback, add) else: widget.bind(f'<{modifier}{letter.lower()}>', callback, add) widget.bind(f'<{modifier}{letter.upper()}>', callback, add)
def create_tooltip(widget: tk.Widget, text: str): """ Create a tooltip with text that is shown when the user hovers over widget. """ tool_tip = ToolTip(widget) # noinspection PyUnusedLocal def enter(tk_event: tk.Event): tool_tip.show_tooltip(text) # noinspection PyUnusedLocal def leave(tk_event: tk.Event): tool_tip.hide_tooltip() widget.bind('<Enter>', enter) widget.bind('<Leave>', leave)
def bind_data(self, widget: tkinter.Widget, property_name: str): """ This method binds a function to a widgets and sets the callback function. For things which are sensible this is a 2-way binding. (Anything editable, i.e. not a Label) :param widget: tkinter.Widget object :param property_name: Property to bind """ # unpythonic code, used for generic data binding as there are different # behaviours for different widgets if isinstance(widget, tkinter.Entry) or isinstance( widget, tkinter.ttk.Entry): # bind any key press to setting the contents of the widgets to the property widget.bind( "<KeyRelease>", lambda event: setattr(self.context, property_name, event.widget.get())) # insert the value in the entry val = getattr(self.context, property_name) if val: widget.delete(0, tkinter.END) widget.insert(0, val) if isinstance(widget, tkinter.Checkbutton) or isinstance( widget, tkinter.ttk.Checkbutton): # a binary value has to be bound to this, calls not on the value widget.bind( "<Button-1>", lambda event: setattr(self.context, property_name, ( not getattr(self.context, property_name)))) if isinstance(widget, tkinter.Label) or isinstance( widget, tkinter.ttk.Label): # sets the label text to be the property val = getattr(self.context, property_name) widget.config(text=str(val)) if isinstance(widget, tkinter.Listbox): # bind selection to store currently selected in the viewmodel widget.bind( "<<ListboxSelect>>", lambda event: setattr(self.context, 'current_selection', event.widget.curselection())) # add all items to listbox widget.delete(0, tkinter.END) for i, item in enumerate(getattr(self.context, property_name)): widget.insert(i, str(item)) if isinstance(widget, tkinter.Button) or isinstance( widget, tkinter.ttk.Button): # sets the button text to be the property widget.config(text=str(getattr(self.context, property_name))) # add the widgets to the properties list if property_name not in self.properties: self.properties[property_name] = [] self.properties[property_name].append(widget)
def bind_tab_key(widget: tkinter.Widget, on_tab: Callable[['tkinter.Event[Any]', bool], BreakOrNone], **bind_kwargs: Any) -> None: """A convenience function for binding Tab and Shift+Tab. Use this function like this:: def on_tab(event, shifted): # shifted is True if the user held down shift while pressing # tab, and False otherwise ... utils.bind_tab_key(some_widget, on_tab, add=True) The ``event`` argument and ``on_tab()`` return values are treated just like with regular bindings. Binding ``'<Tab>'`` works just fine everywhere, but binding ``'<Shift-Tab>'`` only works on Windows and Mac OSX. This function also works on X11. """ # there's something for this in more_functools, but it's a big # dependency for something this simple imo def callback(shifted: bool, event: 'tkinter.Event[tkinter.Misc]') -> BreakOrNone: return on_tab(event, shifted) if widget.tk.call('tk', 'windowingsystem') == 'x11': # even though the event keysym says Left, holding down the right # shift and pressing tab also works :D shift_tab = '<ISO_Left_Tab>' else: shift_tab = '<Shift-Tab>' widget.bind('<Tab>', functools.partial(callback, False), **bind_kwargs) # bindcheck: ignore widget.bind(shift_tab, functools.partial(callback, True), **bind_kwargs) # bindcheck: ignore
def __init__(self, widget: Widget, text: str, side: str = 'n', **kwargs): """\ Parameters ---------- widget : Widget The parent widget text : str The tooltip text side : str, optional (default is "n") Which side of the parent widget to show the tooltip on **kwargs : dict, optional (default is justify="left", padx=1, pady=1) tkLabel Keyword Arguments for the tooltip """ # verify value if side and side.lower() not in list('nsew'): raise ValueError('<side> parameter must be ' 'one of "n", "s", "e", or "w"') # init vars self._wgt = widget self._side = side.lower() kwargs.update(justify=kwargs.pop('justify', 'left'), padx=kwargs.pop('padx', 1), pady=kwargs.pop('pady', 1)) # create win Toplevel.__init__(self, master=widget) self.attributes("-alpha", 0.75) self.overrideredirect(True) # create lbl self._lbl = Label(master=self, text=text, **kwargs) self._lbl.pack() self.update_idletasks() self._tw = self.winfo_reqwidth() self._th = self.winfo_reqheight() self.withdraw() widget.bind("<Enter>", self.enter) widget.bind("<Leave>", self.close)
def forward_event(event_name: str, from_: tkinter.Widget, to: tkinter.Widget, *, add: bool = True) -> str: def callback(event: 'tkinter.Event[tkinter.Misc]') -> None: # make the coordinates relative to the 'to' widget x = event.x_root - to.winfo_rootx() y = event.y_root - to.winfo_rooty() # no need to specify rootx and rooty, because Tk can calculate them if isinstance(event, EventWithData): to.event_generate(event_name, x=x, y=y, data=event.data_string) else: to.event_generate(event_name, x=x, y=y) if event_name.startswith('<<'): # virtual events support data return bind_with_data(from_, event_name, callback, add=add) else: return from_.bind(event_name, callback, add=add)
def embed(widget:tkinter.Widget, default_size=None, allow_new=True, allow_save=True, allow_load=True): from tkinter import Label, Toplevel, Frame, IntVar, Spinbox, Button from tkinter.messagebox import showerror from PIL.ImageTk import PhotoImage matrix = [] buttons = [] if default_size is None: instructions = """n: New Map s: Save Map o/l: Open Map""" else: instructions = '' instructions = Label(widget, text=instructions) instructions.pack() def create_new_map(width, height): matrix[:] = create_matrix(width, height) instructions.destroy() for old_button in buttons: old_button.destroy() buttons[:] = [] for x in range(width): for y in range(height): # new_button = Button(widget, photoimage=) buttons.append() if allow_new: def new_map(event): dialog = Toplevel(widget) form = Frame(dialog) Label(form, text='Width:').grid(row=0, column=0) Label(form, text='Height:').grid(row=1, column=0) size = [1, 1] comm = (lambda ix: (lambda event=None: size.__setitem__(ix, wb.get() + (event.char if event else '')))) wv = IntVar(value=10) wb = Spinbox(form, from_=1, to=65535, command=comm(0), textvariable=wv) wb.bind('<Key>', comm(0)) wb.grid(row=0, column=1) hv = IntVar(value=10) hb = Spinbox(form, from_=1, to=65535, command=comm(1), textvariable=hv) hb.bind('<Key>', comm(1)) hb.grid(row=1, column=1) form.pack() dialog.transient(widget) dialog.grab_set() wb.focus_set() widget.wait_window(dialog) create_new_map(wv.get(), hv.get()) widget.bind('n', new_map) widget.bind('N', new_map) if allow_save: def save_map(event): ... widget.bind('s', save_map) widget.bind('S', save_map) if allow_load: def load_map(event): ... widget.bind('o', load_map) widget.bind('l', load_map) widget.bind('O', load_map) widget.bind('L', load_map) import glob images = {x: PhotoImage(file=next(glob.iglob(os.path.join('img', str(x) + '*')))) for x in matrix_labels} buttons = {'w': 'up', 'a': 'left', 's': 'down', 'd': 'right', '<space>': None}
def bind(self, widget: Widget, action: T_ActionCallable): widget.bind(self.value, action)