Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
tk.py197 linesDownload Raw Back to tqdm
1"""2Tkinter GUI progressbar decorator for iterators.3 4Usage:5>>> from tqdm.tk import trange, tqdm6>>> for i in trange(10):7...     ...8"""9import re10import sys11import tkinter12import tkinter.ttk as ttk13from warnings import warn14 15from .std import TqdmExperimentalWarning, TqdmWarning16from .std import tqdm as std_tqdm17 18__author__ = {"github.com/": ["richardsheridan", "casperdcl"]}19__all__ = ['tqdm_tk', 'ttkrange', 'tqdm', 'trange']20 21 22class tqdm_tk(std_tqdm):  # pragma: no cover23    """24    Experimental Tkinter GUI version of tqdm!25 26    Note: Window interactivity suffers if `tqdm_tk` is not running within27    a Tkinter mainloop and values are generated infrequently. In this case,28    consider calling `tqdm_tk.refresh()` frequently in the Tk thread.29    """30 31    # TODO: @classmethod: write()?32 33    def __init__(self, *args, **kwargs):34        """35        This class accepts the following parameters *in addition* to36        the parameters accepted by `tqdm`.37 38        Parameters39        ----------40        grab  : bool, optional41            Grab the input across all windows of the process.42        tk_parent  : `tkinter.Wm`, optional43            Parent Tk window.44        cancel_callback  : Callable, optional45            Create a cancel button and set `cancel_callback` to be called46            when the cancel or window close button is clicked.47        """48        kwargs = kwargs.copy()49        kwargs['gui'] = True50        # convert disable = None to False51        kwargs['disable'] = bool(kwargs.get('disable', False))52        self._warn_leave = 'leave' in kwargs53        grab = kwargs.pop('grab', False)54        tk_parent = kwargs.pop('tk_parent', None)55        self._cancel_callback = kwargs.pop('cancel_callback', None)56        super().__init__(*args, **kwargs)57 58        if self.disable:59            return60 61        if tk_parent is None:  # Discover parent widget62            try:63                tk_parent = tkinter._default_root64            except AttributeError:65                raise AttributeError(66                    "`tk_parent` required when using `tkinter.NoDefaultRoot()`")67            if tk_parent is None:  # use new default root window as display68                self._tk_window = tkinter.Tk()69            else:  # some other windows already exist70                self._tk_window = tkinter.Toplevel()71        else:72            self._tk_window = tkinter.Toplevel(tk_parent)73 74        warn("GUI is experimental/alpha", TqdmExperimentalWarning, stacklevel=2)75        self._tk_dispatching = self._tk_dispatching_helper()76 77        self._tk_window.protocol("WM_DELETE_WINDOW", self.cancel)78        self._tk_window.wm_title(self.desc)79        self._tk_window.wm_attributes("-topmost", 1)80        self._tk_window.after(0, lambda: self._tk_window.wm_attributes("-topmost", 0))81        self._tk_n_var = tkinter.DoubleVar(self._tk_window, value=0)82        self._tk_text_var = tkinter.StringVar(self._tk_window)83        pbar_frame = ttk.Frame(self._tk_window, padding=5)84        pbar_frame.pack()85        _tk_label = ttk.Label(pbar_frame, textvariable=self._tk_text_var,86                              wraplength=600, anchor="center", justify="center")87        _tk_label.pack()88        self._tk_pbar = ttk.Progressbar(89            pbar_frame, variable=self._tk_n_var, length=450)90        if self.total is not None:91            self._tk_pbar.configure(maximum=self.total)92        else:93            self._tk_pbar.configure(mode="indeterminate")94        self._tk_pbar.pack()95        if self._cancel_callback is not None:96            _tk_button = ttk.Button(pbar_frame, text="Cancel", command=self.cancel)97            _tk_button.pack()98        if grab:99            self._tk_window.grab_set()100 101    def close(self):102        if self.disable:103            return104 105        self.disable = True106 107        with self.get_lock():108            self._instances.remove(self)109 110        def _close():111            self._tk_window.after('idle', self._tk_window.destroy)112            if not self._tk_dispatching:113                self._tk_window.update()114 115        self._tk_window.protocol("WM_DELETE_WINDOW", _close)116 117        # if leave is set but we are self-dispatching, the left window is118        # totally unresponsive unless the user manually dispatches119        if not self.leave:120            _close()121        elif not self._tk_dispatching:122            if self._warn_leave:123                warn("leave flag ignored if not in tkinter mainloop",124                     TqdmWarning, stacklevel=2)125            _close()126 127    def clear(self, *_, **__):128        pass129 130    def display(self, *_, **__):131        self._tk_n_var.set(self.n)132        d = self.format_dict133        # remove {bar}134        d['bar_format'] = (d['bar_format'] or "{l_bar}<bar/>{r_bar}").replace(135            "{bar}", "<bar/>")136        msg = self.format_meter(**d)137        if '<bar/>' in msg:138            msg = "".join(re.split(r'\|?<bar/>\|?', msg, maxsplit=1))139        self._tk_text_var.set(msg)140        if not self._tk_dispatching:141            self._tk_window.update()142 143    def set_description(self, desc=None, refresh=True):144        self.set_description_str(desc, refresh)145 146    def set_description_str(self, desc=None, refresh=True):147        self.desc = desc148        if not self.disable:149            self._tk_window.wm_title(desc)150            if refresh and not self._tk_dispatching:151                self._tk_window.update()152 153    def cancel(self):154        """155        `cancel_callback()` followed by `close()`156        when close/cancel buttons clicked.157        """158        if self._cancel_callback is not None:159            self._cancel_callback()160        self.close()161 162    def reset(self, total=None):163        """164        Resets to 0 iterations for repeated use.165 166        Parameters167        ----------168        total  : int or float, optional. Total to use for the new bar.169        """170        if hasattr(self, '_tk_pbar'):171            if total is None:172                self._tk_pbar.configure(maximum=100, mode="indeterminate")173            else:174                self._tk_pbar.configure(maximum=total, mode="determinate")175        super().reset(total=total)176 177    @staticmethod178    def _tk_dispatching_helper():179        """determine if Tkinter mainloop is dispatching events"""180        codes = {tkinter.mainloop.__code__, tkinter.Misc.mainloop.__code__}181        for frame in sys._current_frames().values():182            while frame:183                if frame.f_code in codes:184                    return True185                frame = frame.f_back186        return False187 188 189def ttkrange(*args, **kwargs):190    """Shortcut for `tqdm.tk.tqdm(range(*args), **kwargs)`."""191    return tqdm_tk(range(*args), **kwargs)192 193 194# Aliases195tqdm = tqdm_tk196trange = ttkrange197 
codekingpro/portable-devtools · Team Ai