Пример #1
0
 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
Пример #2
0
 def __init__(self, _master_: Widget, _scene_: SceneFrame):
     _master_.update()
     super().__init__(_master_, borderwidth=2, relief="groove")
     self._master = _master_
     self._scene = _scene_
     self._build()
     pass
Пример #3
0
 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 update_image(widget: tk.Widget,
                     img,
                     encode_mode: int = cv2.IMREAD_GRAYSCALE) -> None:
        """
            表示画像の更新を行う。
            :param widget 画像を表示対象
            :param img イメージデータ
            :param encode_mode 出力画像形式 カラー / グレースケール

            note:ImageData.encode2PNMを使っている理由はexeファイルのサイズ削減のため。
                Pillowに依存しないことで1MB、実行ファイルサイズが削減されます。
        """
        assert img is not None
        # 画像出力用
        widget.np = img
        ct()
        ext = {
            cv2.IMREAD_GRAYSCALE: '.PGM',
            cv2.IMREAD_COLOR: '.PPM'
        }.get(encode_mode)
        # PGMまたはPBM形式に変換する。
        # GC対象にならないように参照を保持
        #ext = ".png"
        widget.src = tk.PhotoImage(data=ImageData.encode2PNM(img, ext))
        ct()
        widget.configure(image=widget.src)
        ct()
 def set_visible(widget: tk.Widget, visible: bool = False) -> None:
     """
         ウィンドウの表示/非表示を行う。
     """
     if visible:
         widget.deiconify()
     else:
         widget.withdraw()
Пример #6
0
def _place_widget(widget: tkinter.Widget, row: int, column: int,
                  columnspan: int, padx: int, pady: int, sticky: int):
    """Place widget on the windows (short hand for the grid command)"""
    widget.grid(row=row,
                column=column,
                columnspan=columnspan,
                padx=padx,
                pady=pady,
                sticky=sticky)
Пример #7
0
 def bind_all(widget: tk.Widget,
              modifier: str = "",
              letter: str = "",
              callback=None) -> None:
     widget.bind_all('<{0}-{1}>'.format(modifier, letter.upper()), callback)
     # numeric letter multi assign check.
     if not letter.isdecimal():
         widget.bind_all('<{0}-{1}>'.format(modifier, letter.lower()),
                         callback)
Пример #8
0
def style_menu(widget: tk.Widget) -> None:
    style = ttk.Style()
    bg = style.lookup(".", "background")
    fg = style.lookup(".", "foreground")
    abg = style.lookup(".", "lightcolor")
    if not abg:
        abg = bg
    widget.config(
        background=bg, foreground=fg, activebackground=abg, activeforeground=fg, bd=0
    )
Пример #9
0
 def __init__(self, master=None, cnf={}, **kw):
     cnf = _cnfmerge((cnf, kw))
     self.widgetName = '__dialog__'
     Widget._setup(self, master, cnf)
     self.num = self.tk.getint(
         self.tk.call('tk_dialog', self._w, cnf['title'], cnf['text'],
                      cnf['bitmap'], cnf['default'], *cnf['strings']))
     try:
         Widget.destroy(self)
     except TclError:
         pass
Пример #10
0
    def add_widget(self, widget: tk.Widget, index: int=None):
        # modify the index so that the start and abort
        # buttons are always at the end of the list
        if index is None:
            self.widgets.insert(-2, widget)
        else:
            self.widgets.insert(index, widget)

        for i, widget in enumerate(self.widgets):
            widget.grid_forget()
            widget.grid(row=i, sticky='ew')
Пример #11
0
    def add_widget(self, widget: tk.Widget, index: int=None):
        if index is None:
            logger.debug('adding widget {}'.format(widget))
            self.widgets.append(widget)
        else:
            logger.debug('adding widget {} at index {}'.format(widget, index))
            self.widgets.insert(index, widget)

        for i, widget in enumerate(self.widgets):
            widget.grid_forget()
            widget.grid(row=i, sticky='ew')
Пример #12
0
def progress_step(progress_widget: tk.Widget, increment: int = 1):
    '''Increment the progress bar.
    Arguments:
        progress_widget {ttk.Progressbar} -- The progress bar to be
            initialized.
    Keyword Arguments:
        increment {int} -- The incremental step size to use.
            (default: {1})
    '''
    progress_widget.step(increment)
    progress_widget.update_idletasks()
Пример #13
0
def grid(w: Widget, row, col, colspan=1, rowspan=1, pad=5, **kw):
    d = {
        'row': row,
        'column': col,
        'columnspan': colspan,
        'rowspan': rowspan,
        'padx': pad,
        'pady': pad,
        'sticky': 'ensw'
    }
    w.grid(**{**d, **kw})
    return w
Пример #14
0
def lock(widget: tk.Widget, state: str):
    """
    Either lock or unlock a widget based on the state string.

    :param widget: recursively lock/unlock if its a frame otherwise change the config to the specified state
    :param state: state to set the widgets to
    """
    if "TFrame" in widget.winfo_class():
        for child in widget.winfo_children():
            lock(child, state)
    else:
        widget.config(state=state)
Пример #15
0
def widget_recursive_enabler(widget: tk.Widget, enable: bool):
    '''Enable/Disable a TK widget and all its children.''' 
    # TODO: Detect if tkwidget or ttk 
    if enable:
        state = ['!disabled']
    else:
        state = ['disabled']

    for child in widget.winfo_children():
        widget_recursive_enabler(child, enable=enable)
    
    widget.state(state)
Пример #16
0
def grid(widget: Widget, row: int, column: int, r=1, c=1):
    """Syntax candy for common use of grid geometry management method.

    always has sticky set to "nsew".

    Args:
        widget: the widget to be placed.
        row: row number (0 and up).
        column: column number (0 and up).
        r: optional row span
        c: optional column span
    """
    widget.grid(row=row, column=column, rowspan=r, columnspan=c, sticky="nsew")
Пример #17
0
 def unbind_ci(widget: tk.Widget,
               all_: bool = False,
               *,
               modifier: str = '',
               letter: str,
               callback=None):
     if modifier and letter:
         modifier += '-'
     if all_:
         widget.unbind_all(f'<{modifier}{letter.lower()}>')
         widget.unbind_all(f'<{modifier}{letter.upper()}>')
     else:
         widget.unbind(f'<{modifier}{letter.lower()}>', callback)
         widget.unbind(f'<{modifier}{letter.upper()}>', callback)
Пример #18
0
def style_listbox(widget: tk.Widget) -> None:
    style = ttk.Style()
    bg = style.lookup(".", "background")
    fg = style.lookup(".", "foreground")
    bc = style.lookup(".", "bordercolor")
    if not bc:
        bc = "black"
    widget.config(
        background=bg,
        foreground=fg,
        highlightthickness=1,
        highlightcolor=bc,
        highlightbackground=bc,
        bd=0,
    )
Пример #19
0
 def position_absolute(self, widget: tkinter.Widget, x_position: int, y_position: int, x_size: int, y_size: int) \
         -> None:
     """
     Position a widget absolutely in a grid layout
     :param widget: the widget to be positioned
     :param x_position: the horizontal position of the widget in the grid
     :param y_position: the vertical position of the widget in the grid
     :param x_size: the width of the widget in the grid layout
     :param y_size: the width of the widget in the grid layout
     :return: void
     """
     widget.grid(column=x_position, row=y_position, columnspan=x_size, rowspan=y_size, sticky=W + E + N + S)
     if self.rowcounter < y_position + y_size:
         self.rowcounter = y_position + y_size
     if self.columncounter < x_position + x_size:
         self.columncounter = x_position + x_size
Пример #20
0
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)
Пример #21
0
 def pack(self, w: tk.Widget):
     rtn = w.grid(padx=PAD,
                  pady=PAD,
                  row=int(self.__counter / self.__width),
                  column=self.__counter % self.__width)
     self.__counter += 1
     return rtn
Пример #22
0
 def toggle_state(self, item: tk.Widget, state: bool = False):
     counter = self._get_counter(item)
     if not state:
         if counter.inc() == 1:
             if not isinstance(item, tuple):
                 item.configure(state=tk.DISABLED)
             else:
                 if isinstance(item[0], tk.Menu):
                     item[0].entryconfig(item[1], state=tk.DISABLED)
     else:
         if counter.dec() == 0:
             if not isinstance(item, tuple):
                 item.configure(state=tk.NORMAL)
             else:
                 if isinstance(item[0], tk.Menu):
                     item[0].entryconfig(item[1], state=tk.NORMAL)
 def bind_all(widget: tk.Widget,
              modifier: str = "",
              letter: str = "",
              callback=None) -> None:
     """
     Keyboard Shortcut Assign.
     :param widget:割り当てるウィジット
     :param modifier:キーコード修飾子 Ctrl, Shift, Altなど
     :param letter:割当文字
     :param callback:イベント発生時に呼び出されるコールバック
     :return:
     """
     widget.bind_all('<{0}-{1}>'.format(modifier, letter.upper()), callback)
     # numeric letter multi assign check.
     if not letter.isdecimal():
         widget.bind_all('<{0}-{1}>'.format(modifier, letter.lower()),
                         callback)
 def set_widget_geometry(self, widget: tk.Widget, settings: ET.Element):
     '''Apply window geometry settings given in the XML element.
     Arguments:
         widget {tk.Widget} -- The widget instance.
         settings {ET.Element} -- The widget Settings XML Element.
     '''
     options = dict()
     geometry = settings.find('Geometry')
     padding = geometry.find('Padding')
     if padding is not None:
         options.update(self.reference.resolve(padding.attrib))
     placement = geometry[0]
     options.update(self.reference.resolve(placement.attrib))
     if 'Grid' in placement.tag:
         widget.grid(**options)
     elif 'Pack' in placement.tag:
         widget.pack(**options)
     pass
Пример #25
0
    def _setup_geometry(self, obj: tk.Widget, geom: str):
        geom_match = self.__geom_re.match(geom)
        if not geom_match:
            raise RuntimeError(f"Invalid geometry: '{geom}'")
        row_pattern = geom_match["row"]
        column_pattern = geom_match["column"]

        if geom_match["sticky"] is not None:
            obj.grid(sticky=geom_match["sticky"])

        row = self._parse_axis_configuration(row_pattern)
        column = self._parse_axis_configuration(column_pattern)

        obj.grid(
            column=column.position,
            row=row.position,
            rowspan=1 + row.span,
            columnspan=1 + column.span,
        )
        obj.master.rowconfigure(row.position, weight=row.weight)
        obj.master.columnconfigure(column.position, weight=column.weight)
Пример #26
0
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
Пример #27
0
 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)
Пример #28
0
def apply_class_bindings(window: tkinter.Widget):
    """Add class level event bindings in application"""
    for className in ["TEntry", "TSpinbox", "TCombobox"]:
        window.bind_class(
            className=className, 
            sequence="<Configure>", 
            func=on_disabled_readonly_state,
            add="+"
        )

        for sequence in ["<Control-a>", "<Control-A>"]:
            window.bind_class(
                className=className, 
                sequence=sequence,
                func=on_select_all
        )
    window.unbind_class("TButton", "<Key-space>")
    window.bind_class("TButton", "<Key-Return>", lambda event: event.widget.invoke())
Пример #29
0
def _create_edit_menu(master: Widget) -> Menu:
    menu = Menu(master, tearoff=0)
    menu.add_command(label="Undo",
                     command=lambda: master.focus_get().edit_undo(),
                     underline=0,
                     accelerator=_KEYS["undo"][0])
    menu.add_command(label="Redo",
                     command=lambda: master.focus_get().edit_redo(),
                     underline=0,
                     accelerator=_KEYS["redo"][0])
    menu.add_separator()
    menu.add_command(
        label="Cut",
        command=lambda: master.focus_get().event_generate("<<Cut>>"),
        underline=2,
        accelerator=_KEYS["cut"][0])
    menu.add_command(
        label="Copy",
        command=lambda: master.focus_get().event_generate("<<Copy>>"),
        underline=0,
        accelerator=_KEYS["copy"][0])
    menu.add_command(
        label="Paste",
        command=lambda: master.focus_get().event_generate("<<Paste>>"),
        underline=0,
        accelerator=_KEYS["paste"][0])
    menu.add_separator()
    menu.add_command(
        label="Delete",
        command=lambda: master.focus_get().delete(SEL_FIRST, SEL_LAST),
        underline=0,
        accelerator=_KEYS["delete"][0])

    def before():
        text = master.focus_get()
        if not isinstance(text, Text):
            for i in 0, 1, 3, 4, 5, 7:
                menu.entryconfigure(i, state=DISABLED)
        else:
            menu.entryconfigure(0, state=_to_state(text.edit("canundo")))
            menu.entryconfigure(1, state=_to_state(text.edit("canredo")))
            has_selection = text.tag_ranges(SEL) != ()
            for i in 3, 4, 7:
                menu.entryconfigure(i, state=_to_state(has_selection))
            try:
                master.clipboard_get()
                menu.entryconfigure(5, state=NORMAL)
            except TclError:
                menu.entryconfigure(5, state=DISABLED)

    menu.configure(postcommand=before)
    return menu
Пример #30
0
    def _move(self):
        tk_main_w = Widget.nametowidget(self, '.')
        coord_x = tk_main_w.winfo_x() + 250
        coord_y = tk_main_w.winfo_y() + self.__coord_y + 150

        self.menu = Menu(self,
                         bg=config.colors["BG"],
                         activebackground=config.colors["TV_BG_HOVER"],
                         activeforeground=config.colors["FG"],
                         tearoff=False)

        for playlist in config.user_config["Playlists"]:
            if playlist != config.general["playlist"]:
                #https://stackoverflow.com/questions/11723217/python-lambda-doesnt-remember-argument-in-for-loop
                func_get_set_playlist = lambda playlist=playlist: self.__move(
                    playlist)
                self.menu.add_command(label=playlist,
                                      command=func_get_set_playlist)

        self.menu.tk_popup(coord_x, coord_y)