Edit on GitHub

sysmon_pytk.modals

Modal dialogs.

 1# SPDX-FileCopyrightText: © 2024 Stacey Adams <stacey.belle.rose@gmail.com>
 2# SPDX-License-Identifier: MIT
 3
 4"""
 5Modal dialogs.
 6"""
 7
 8from . import messagebox
 9from ._base_modal import ModalDialog
10from .about_modal import AboutDialog, AboutMetadata, LicenseMetadata
11from .cpu_modal import CpuDialog
12from .disk_usage_modal import DiskUsageDialog
13from .font_modal import FontChooser
14from .mem_usage_modal import MemUsageDialog
15from .settings_modal import SettingsDialog
16from .temperature_modal import TempDetailsDialog
17
18__all__ = [
19    "ModalDialog",
20    "AboutDialog",
21    "AboutMetadata",
22    "LicenseMetadata",
23    "CpuDialog",
24    "DiskUsageDialog",
25    "FontChooser",
26    "MemUsageDialog",
27    "SettingsDialog",
28    "TempDetailsDialog",
29    "messagebox"
30]
class ModalDialog(sysmon_pytk.widgets.buttons.ButtonMixin, tkinter.Toplevel):
 30class ModalDialog(ButtonMixin, tk.Toplevel, metaclass=ABCMeta):
 31    """
 32    Base class for modal dialogs.
 33
 34    Attributes
 35    ----------
 36    parent : Misc, optional
 37        The parent widget.
 38    iconpath : str, optional
 39        The path to the icon to display in the window title bar.
 40    internal_frame : Frame
 41        A `Frame` to manage the widgets added to the dialog.
 42    base_font : Font
 43        Standard font to use for widgets.
 44    large_font : Font
 45        Large font to use for headers.
 46    bold_font : Font
 47        Bold font to use for widgets.
 48    fixed_font : Font
 49        Fixed font to use for widgets.
 50    _events : list[str]
 51        A list of event sequences to trigger after save and dismiss.
 52    """
 53
 54    def __init__(
 55        self, parent: Misc | None = None, *, title: str | None = None,
 56        iconpath: str | None = None, class_: str = "ModalDialog"
 57    ) -> None:
 58        """
 59        Construct a modal dialog.
 60
 61        Parameters
 62        ----------
 63        parent : Misc, optional
 64            The parent widget.
 65        title : str, optional
 66            The title to display in the window title bar.
 67        iconpath : str, optional
 68            The path to the icon to display in the window title bar.
 69        class_ : str, default = "ModalDialog"
 70            The class name of this modal dialog, used with the option database
 71            for styling.
 72        """
 73        super().__init__(parent, class_=class_)
 74        self.parent = parent
 75        self.iconpath = iconpath
 76        self._events: list[str] = []
 77        self.title(title)
 78        if self.iconpath is not None:
 79            self.iconphoto(False, tk.PhotoImage(file=self.iconpath))
 80        self.internal_frame = ttk.Frame(self)
 81        self.internal_frame.grid(sticky=tk.NSEW)
 82        self.load_fonts()
 83        self.bind_events()
 84        self.create_widgets()
 85        self.update_screen()
 86        top = self.winfo_toplevel()
 87        top.rowconfigure(0, weight=1)
 88        top.columnconfigure(0, weight=1)
 89        self.make_modal()
 90        self.wait_window()
 91
 92    @final
 93    def load_fonts(self) -> None:
 94        """
 95        Load the standard fonts from the `sysmon_pytk.style_manager.StyleManager`.
 96        """
 97        self.base_font = StyleManager.get_base_font()
 98        self.large_font = StyleManager.get_large_font()
 99        self.bold_font = StyleManager.get_bold_font()
100        self.fixed_font = StyleManager.get_fixed_font()
101
102    @final
103    def bind_events(self) -> None:
104        """
105        Bind window events.
106        """
107        self.protocol("WM_DELETE_WINDOW", self.dismiss)
108        self.bind("<KeyPress-Escape>", self.dismiss)
109        self.bind("<KeyPress-Return>", self.save_and_dismiss)
110        self.bind("<KeyPress-KP_Enter>", self.save_and_dismiss)
111
112    @final
113    def make_modal(self) -> None:
114        """
115        Make this behave like a modal window.
116        """
117        self.transient(self.parent)  # type: ignore[arg-type]
118        self.wait_visibility()
119        self.grab_set()
120        self.minsize(self.winfo_width(), self.winfo_height())
121
122    @final
123    def dismiss(self, *_args) -> None:
124        """
125        Dismiss the modal dialog.
126
127        This should be bound to Cancel and Close buttons in subclasses.
128        """
129        self.grab_release()
130        self.destroy()
131
132    @final
133    def save_and_dismiss(self, *_args) -> None:
134        """
135        Save what was entered in the modal dialog and dismiss it.
136
137        This should be bound to OK and Save buttons in subclasses.
138        """
139        self.on_save()
140        self.dismiss()
141        if self.parent:
142            for event in self._events:
143                self.parent.event_generate(event)
144
145    @final
146    def save_dismiss_event(self, event_str: str) -> None:
147        """
148        Accumulate a list of events to trigger on dismissal when saving.
149        """
150        if event_str not in self._events:
151            self._events.append(event_str)
152
153    @final
154    def add_close_button(self) -> None:
155        """
156        Add a Close button to the bottom row of the modal dialog.
157        """
158        buttons = [
159            ButtonDefinition(text=_("Close"), command=self.dismiss),
160        ]
161        self.add_buttons(self.internal_frame, buttons=buttons, default=0)
162
163    @final
164    def add_ok_cancel_buttons(self) -> None:
165        """
166        Add OK and Cancel buttons to the bottom row of the modal dialog.
167        """
168        buttons = [
169            ButtonDefinition(text=_("Cancel"), command=self.dismiss),
170            ButtonDefinition(text=_("OK"), command=self.save_and_dismiss),
171        ]
172        self.add_buttons(self.internal_frame, buttons=buttons, default=1)
173
174    @final
175    def add_sizegrip(self) -> None:
176        """
177        Add a ttk.Sizegrip widget to the bottom row of the modal dialog.
178        """
179        max_columns, max_rows = self.internal_frame.grid_size()
180        ttk.Sizegrip(self.internal_frame).grid(
181            row=max_rows, column=max_columns-1, sticky=tk.SE, padx=INTERNAL_PAD/2,
182            pady=INTERNAL_PAD/2
183        )
184
185    @abstractmethod
186    def on_save(self) -> None:
187        """
188        Save what was entered in the modal dialog.
189        """
190
191    @abstractmethod
192    def create_widgets(self) -> None:
193        """
194        Create the widgets to be displayed in the modal dialog.
195        """
196
197    @abstractmethod
198    def update_screen(self) -> None:
199        """
200        Update the modal dialog window.
201        """

Base class for modal dialogs.

Attributes
  • parent (Misc, optional): The parent widget.
  • iconpath (str, optional): The path to the icon to display in the window title bar.
  • internal_frame (Frame): A Frame to manage the widgets added to the dialog.
  • base_font (Font): Standard font to use for widgets.
  • large_font (Font): Large font to use for headers.
  • bold_font (Font): Bold font to use for widgets.
  • fixed_font (Font): Fixed font to use for widgets.
  • _events (list[str]): A list of event sequences to trigger after save and dismiss.
ModalDialog( parent: tkinter.Misc | None = None, *, title: str | None = None, iconpath: str | None = None, class_: str = 'ModalDialog')
54    def __init__(
55        self, parent: Misc | None = None, *, title: str | None = None,
56        iconpath: str | None = None, class_: str = "ModalDialog"
57    ) -> None:
58        """
59        Construct a modal dialog.
60
61        Parameters
62        ----------
63        parent : Misc, optional
64            The parent widget.
65        title : str, optional
66            The title to display in the window title bar.
67        iconpath : str, optional
68            The path to the icon to display in the window title bar.
69        class_ : str, default = "ModalDialog"
70            The class name of this modal dialog, used with the option database
71            for styling.
72        """
73        super().__init__(parent, class_=class_)
74        self.parent = parent
75        self.iconpath = iconpath
76        self._events: list[str] = []
77        self.title(title)
78        if self.iconpath is not None:
79            self.iconphoto(False, tk.PhotoImage(file=self.iconpath))
80        self.internal_frame = ttk.Frame(self)
81        self.internal_frame.grid(sticky=tk.NSEW)
82        self.load_fonts()
83        self.bind_events()
84        self.create_widgets()
85        self.update_screen()
86        top = self.winfo_toplevel()
87        top.rowconfigure(0, weight=1)
88        top.columnconfigure(0, weight=1)
89        self.make_modal()
90        self.wait_window()

Construct a modal dialog.

Parameters
  • parent (Misc, optional): The parent widget.
  • title (str, optional): The title to display in the window title bar.
  • iconpath (str, optional): The path to the icon to display in the window title bar.
  • class_ (str, default = "ModalDialog"): The class name of this modal dialog, used with the option database for styling.
@final
def load_fonts(self) -> None:
 92    @final
 93    def load_fonts(self) -> None:
 94        """
 95        Load the standard fonts from the `sysmon_pytk.style_manager.StyleManager`.
 96        """
 97        self.base_font = StyleManager.get_base_font()
 98        self.large_font = StyleManager.get_large_font()
 99        self.bold_font = StyleManager.get_bold_font()
100        self.fixed_font = StyleManager.get_fixed_font()

Load the standard fonts from the sysmon_pytk.style_manager.StyleManager.

@final
def bind_events(self) -> None:
102    @final
103    def bind_events(self) -> None:
104        """
105        Bind window events.
106        """
107        self.protocol("WM_DELETE_WINDOW", self.dismiss)
108        self.bind("<KeyPress-Escape>", self.dismiss)
109        self.bind("<KeyPress-Return>", self.save_and_dismiss)
110        self.bind("<KeyPress-KP_Enter>", self.save_and_dismiss)

Bind window events.

@final
def make_modal(self) -> None:
112    @final
113    def make_modal(self) -> None:
114        """
115        Make this behave like a modal window.
116        """
117        self.transient(self.parent)  # type: ignore[arg-type]
118        self.wait_visibility()
119        self.grab_set()
120        self.minsize(self.winfo_width(), self.winfo_height())

Make this behave like a modal window.

@final
def dismiss(self, *_args) -> None:
122    @final
123    def dismiss(self, *_args) -> None:
124        """
125        Dismiss the modal dialog.
126
127        This should be bound to Cancel and Close buttons in subclasses.
128        """
129        self.grab_release()
130        self.destroy()

Dismiss the modal dialog.

This should be bound to Cancel and Close buttons in subclasses.

@final
def save_and_dismiss(self, *_args) -> None:
132    @final
133    def save_and_dismiss(self, *_args) -> None:
134        """
135        Save what was entered in the modal dialog and dismiss it.
136
137        This should be bound to OK and Save buttons in subclasses.
138        """
139        self.on_save()
140        self.dismiss()
141        if self.parent:
142            for event in self._events:
143                self.parent.event_generate(event)

Save what was entered in the modal dialog and dismiss it.

This should be bound to OK and Save buttons in subclasses.

@final
def save_dismiss_event(self, event_str: str) -> None:
145    @final
146    def save_dismiss_event(self, event_str: str) -> None:
147        """
148        Accumulate a list of events to trigger on dismissal when saving.
149        """
150        if event_str not in self._events:
151            self._events.append(event_str)

Accumulate a list of events to trigger on dismissal when saving.

@final
def add_close_button(self) -> None:
153    @final
154    def add_close_button(self) -> None:
155        """
156        Add a Close button to the bottom row of the modal dialog.
157        """
158        buttons = [
159            ButtonDefinition(text=_("Close"), command=self.dismiss),
160        ]
161        self.add_buttons(self.internal_frame, buttons=buttons, default=0)

Add a Close button to the bottom row of the modal dialog.

@final
def add_ok_cancel_buttons(self) -> None:
163    @final
164    def add_ok_cancel_buttons(self) -> None:
165        """
166        Add OK and Cancel buttons to the bottom row of the modal dialog.
167        """
168        buttons = [
169            ButtonDefinition(text=_("Cancel"), command=self.dismiss),
170            ButtonDefinition(text=_("OK"), command=self.save_and_dismiss),
171        ]
172        self.add_buttons(self.internal_frame, buttons=buttons, default=1)

Add OK and Cancel buttons to the bottom row of the modal dialog.

@final
def add_sizegrip(self) -> None:
174    @final
175    def add_sizegrip(self) -> None:
176        """
177        Add a ttk.Sizegrip widget to the bottom row of the modal dialog.
178        """
179        max_columns, max_rows = self.internal_frame.grid_size()
180        ttk.Sizegrip(self.internal_frame).grid(
181            row=max_rows, column=max_columns-1, sticky=tk.SE, padx=INTERNAL_PAD/2,
182            pady=INTERNAL_PAD/2
183        )

Add a ttk.Sizegrip widget to the bottom row of the modal dialog.

@abstractmethod
def on_save(self) -> None:
185    @abstractmethod
186    def on_save(self) -> None:
187        """
188        Save what was entered in the modal dialog.
189        """

Save what was entered in the modal dialog.

@abstractmethod
def create_widgets(self) -> None:
191    @abstractmethod
192    def create_widgets(self) -> None:
193        """
194        Create the widgets to be displayed in the modal dialog.
195        """

Create the widgets to be displayed in the modal dialog.

@abstractmethod
def update_screen(self) -> None:
197    @abstractmethod
198    def update_screen(self) -> None:
199        """
200        Update the modal dialog window.
201        """

Update the modal dialog window.

Inherited Members
sysmon_pytk.widgets.buttons.ButtonMixin
add_buttons
init_standard_buttons
tkinter.BaseWidget
destroy
tkinter.Misc
deletecommand
tk_strictMotif
tk_bisque
tk_setPalette
wait_variable
waitvar
wait_window
wait_visibility
setvar
getvar
getboolean
focus_set
focus
focus_force
focus_get
focus_displayof
focus_lastfor
tk_focusFollowsMouse
tk_focusNext
tk_focusPrev
after
after_idle
after_cancel
bell
clipboard_get
clipboard_clear
clipboard_append
grab_current
grab_release
grab_set
grab_set_global
grab_status
option_add
option_clear
option_get
option_readfile
selection_clear
selection_get
selection_handle
selection_own
selection_own_get
send
lower
tkraise
lift
winfo_atom
winfo_atomname
winfo_cells
winfo_children
winfo_class
winfo_colormapfull
winfo_containing
winfo_depth
winfo_exists
winfo_fpixels
winfo_geometry
winfo_height
winfo_id
winfo_interps
winfo_ismapped
winfo_manager
winfo_name
winfo_parent
winfo_pathname
winfo_pixels
winfo_pointerx
winfo_pointerxy
winfo_pointery
winfo_reqheight
winfo_reqwidth
winfo_rgb
winfo_rootx
winfo_rooty
winfo_screen
winfo_screencells
winfo_screendepth
winfo_screenheight
winfo_screenmmheight
winfo_screenmmwidth
winfo_screenvisual
winfo_screenwidth
winfo_server
winfo_toplevel
winfo_viewable
winfo_visual
winfo_visualid
winfo_visualsavailable
winfo_vrootheight
winfo_vrootwidth
winfo_vrootx
winfo_vrooty
winfo_width
winfo_x
winfo_y
update
update_idletasks
bindtags
bind
unbind
bind_all
unbind_all
bind_class
unbind_class
mainloop
quit
nametowidget
register
configure
config
cget
keys
pack_propagate
propagate
pack_slaves
slaves
place_slaves
grid_anchor
anchor
grid_bbox
bbox
grid_columnconfigure
columnconfigure
grid_location
grid_propagate
grid_rowconfigure
rowconfigure
grid_size
size
grid_slaves
event_add
event_delete
event_generate
event_info
image_names
image_types
tkinter.Wm
wm_aspect
aspect
wm_attributes
attributes
wm_client
client
wm_colormapwindows
colormapwindows
wm_command
command
wm_deiconify
deiconify
wm_focusmodel
focusmodel
wm_forget
forget
wm_frame
frame
wm_geometry
geometry
wm_grid
grid
wm_group
group
wm_iconbitmap
iconbitmap
wm_iconify
iconify
wm_iconmask
iconmask
wm_iconname
iconname
wm_iconphoto
iconphoto
wm_iconposition
iconposition
wm_iconwindow
iconwindow
wm_manage
manage
wm_maxsize
maxsize
wm_minsize
minsize
wm_overrideredirect
overrideredirect
wm_positionfrom
positionfrom
wm_protocol
protocol
wm_resizable
resizable
wm_sizefrom
sizefrom
wm_state
state
wm_title
title
wm_transient
transient
wm_withdraw
withdraw
class AboutDialog(sysmon_pytk.modals.ModalDialog):
 88class AboutDialog(ModalDialog):
 89    """
 90    Display metadata about the application in a modal dialog.
 91
 92    Attributes
 93    ----------
 94    about : AboutMetadata
 95        Metadata about the application to be displayed.
 96    logo : PhotoImage
 97        A logo to be displayed.
 98    """
 99
100    def __init__(
101        self, parent: Misc | None, about: AboutMetadata, iconpath: str | None = None
102    ) -> None:
103        """
104        Construct a modal dialog containing metadata about the application.
105
106        Parameters
107        ----------
108        parent : Misc, optional
109            The parent widget.
110        about : AboutMetadata
111            The metadata about the application.
112        iconpath : str, optional
113            The path to the icon to display in the window title bar.
114        """
115        self.about = about
116        title = _("About {}").format(about.app_name).strip()
117        self.logo = tk.PhotoImage(file=get_full_path("images/icon-lg.png"))
118        super().__init__(parent, title=title, iconpath=iconpath, class_="AboutBox")
119
120    def update_screen(self) -> None:
121        """
122        Update the modal dialog window.
123
124        This dialog does not require screen updates.
125        """
126
127    def on_save(self) -> None:
128        """
129        Save what was entered in the modal dialog.
130
131        This dialog does not need a save feature.
132        """
133
134    def create_widgets(self) -> None:
135        """
136        Create the widgets to be displayed in the modal dialog.
137        """
138        self.internal_frame.rowconfigure(0, weight=1)
139        self.internal_frame.columnconfigure(0, weight=1)
140        notebook = ttk.Notebook(self.internal_frame)
141        notebook.grid(
142            row=0, sticky=tk.NSEW, padx=INTERNAL_PAD/2, pady=INTERNAL_PAD/2
143        )
144        notebook.add(
145            self.create_about_tab(notebook), text=self.title(), sticky=tk.NSEW
146        )
147        notebook.add(
148            self.create_translators_tab(notebook), text=_("Translators"),
149            sticky=tk.NSEW
150        )
151        if self.about.license is not None:
152            notebook.add(
153                self.create_license_tab(notebook, self.about.license),
154                text=_("License"), sticky=tk.NSEW
155            )
156        notebook.enable_traversal()
157        self.add_close_button()
158        self.add_sizegrip()
159
160    def create_about_tab(self, notebook: ttk.Notebook) -> ttk.Frame:
161        """
162        Create the About page of the Notebook widget.
163        """
164        text = ScrollingText(
165            notebook, font=self.base_font, height=11, width=50, wrap=tk.WORD,
166            undo=False, relief=tk.FLAT, spacing1=INTERNAL_PAD
167        )
168        tab = text.get_frame()
169        text.image_create(tk.END, image=self.logo)
170        text.insert(tk.END, "\n")
171        text.insert(tk.END, self.about.get_name() + "\n", "large")
172        text.insert(tk.END, _("Version {}").format(self.about.get_version_string()) + "\n")
173        copyright_text = self.about.get_copyright_text()
174        if copyright_text:
175            text.insert(tk.END, copyright_text + "\n")
176        if self.about.url:
177            token = uuid4().hex
178            text.insert(tk.END, _("Source Code"), ("link", token))
179            text.insert(tk.END, self.about.url, "linkurl")
180            text.insert(tk.END, "\n")
181            TextToolTip(text, self.about.url, token)
182        text.tag_add("center", "1.0", "end-1c")
183        text.insert(tk.END, self.about.description)
184        text.config(state=tk.DISABLED, padx=INTERNAL_PAD)
185        return tab
186
187    def create_translators_tab(self, notebook: ttk.Notebook) -> ttk.Frame:
188        """
189        Create the Translators page of the Notebook widget.
190        """
191        text = ScrollingText(
192            notebook, font=self.base_font, height=10, width=50, wrap=tk.WORD,
193            undo=False, relief=tk.FLAT
194        )
195        tab = text.get_frame()
196        for language, translator_list in TRANSLATORS.items():
197            text.insert(tk.END, f"{language}: ", "bold")
198            for idx, translator in enumerate(translator_list):
199                self._add_translator(text, translator, idx, len(translator_list))
200        text.delete("end-1c")  # remove the final "\n"
201        text.config(state=tk.DISABLED, spacing1=4, spacing2=4, spacing3=4)
202        return tab
203
204    def _add_translator(
205        self, text: tk.Text, translator: Translator, idx: int, max_items: int
206    ) -> None:
207        text.insert(tk.END, translator.name)
208        if translator.github_username:
209            token = uuid4().hex
210            text.insert(tk.END, " (")
211            text.insert(tk.END, f"{translator.github_username} @ GitHub", ("link", token))
212            text.insert(tk.END, translator.github_url(), "linkurl")
213            text.insert(tk.END, ")")
214            TextToolTip(text, translator.github_url(), token)
215        if idx < max_items-1:
216            text.insert(tk.END, ", ")
217        else:
218            text.insert(tk.END, "\n")
219
220    def create_license_tab(
221        self, notebook: ttk.Notebook, license_data: LicenseMetadata
222    ) -> ttk.Frame:
223        """
224        Create the License details page of the Notebook widget.
225        """
226        text = ScrollingText(
227            notebook, font=self.base_font, height=15, width=50, wrap=tk.WORD,
228            undo=False, relief=tk.FLAT
229        )
230        tab = text.get_frame()
231        if license_data.full_license:
232            license_text = [
233                paragraph.replace(
234                    "\n", " "
235                ) for paragraph in license_data.full_license.split("\n\n")
236            ]
237            text.insert(tk.END, "\n\n".join(license_text))
238        elif license_data.license_name:
239            text.config(spacing1=4, spacing2=4, spacing3=4, height=5)
240            text.insert(tk.END, license_data.license_name + "\n")
241            if license_data.license_url:
242                token = uuid4().hex
243                text.insert(tk.END, _("Full license text available here"), ("link", token))
244                text.insert(tk.END, license_data.license_url, "linkurl")
245                TextToolTip(text, license_data.license_url, token)
246            text.tag_add("center", "1.0", "end-1c")
247        text.config(state=tk.DISABLED)
248        return tab

Display metadata about the application in a modal dialog.

Attributes
  • about (AboutMetadata): Metadata about the application to be displayed.
  • logo (PhotoImage): A logo to be displayed.
AboutDialog( parent: tkinter.Misc | None, about: AboutMetadata, iconpath: str | None = None)
100    def __init__(
101        self, parent: Misc | None, about: AboutMetadata, iconpath: str | None = None
102    ) -> None:
103        """
104        Construct a modal dialog containing metadata about the application.
105
106        Parameters
107        ----------
108        parent : Misc, optional
109            The parent widget.
110        about : AboutMetadata
111            The metadata about the application.
112        iconpath : str, optional
113            The path to the icon to display in the window title bar.
114        """
115        self.about = about
116        title = _("About {}").format(about.app_name).strip()
117        self.logo = tk.PhotoImage(file=get_full_path("images/icon-lg.png"))
118        super().__init__(parent, title=title, iconpath=iconpath, class_="AboutBox")

Construct a modal dialog containing metadata about the application.

Parameters
  • parent (Misc, optional): The parent widget.
  • about (AboutMetadata): The metadata about the application.
  • iconpath (str, optional): The path to the icon to display in the window title bar.
def update_screen(self) -> None:
120    def update_screen(self) -> None:
121        """
122        Update the modal dialog window.
123
124        This dialog does not require screen updates.
125        """

Update the modal dialog window.

This dialog does not require screen updates.

def on_save(self) -> None:
127    def on_save(self) -> None:
128        """
129        Save what was entered in the modal dialog.
130
131        This dialog does not need a save feature.
132        """

Save what was entered in the modal dialog.

This dialog does not need a save feature.

def create_widgets(self) -> None:
134    def create_widgets(self) -> None:
135        """
136        Create the widgets to be displayed in the modal dialog.
137        """
138        self.internal_frame.rowconfigure(0, weight=1)
139        self.internal_frame.columnconfigure(0, weight=1)
140        notebook = ttk.Notebook(self.internal_frame)
141        notebook.grid(
142            row=0, sticky=tk.NSEW, padx=INTERNAL_PAD/2, pady=INTERNAL_PAD/2
143        )
144        notebook.add(
145            self.create_about_tab(notebook), text=self.title(), sticky=tk.NSEW
146        )
147        notebook.add(
148            self.create_translators_tab(notebook), text=_("Translators"),
149            sticky=tk.NSEW
150        )
151        if self.about.license is not None:
152            notebook.add(
153                self.create_license_tab(notebook, self.about.license),
154                text=_("License"), sticky=tk.NSEW
155            )
156        notebook.enable_traversal()
157        self.add_close_button()
158        self.add_sizegrip()

Create the widgets to be displayed in the modal dialog.

def create_about_tab(self, notebook: tkinter.ttk.Notebook) -> tkinter.ttk.Frame:
160    def create_about_tab(self, notebook: ttk.Notebook) -> ttk.Frame:
161        """
162        Create the About page of the Notebook widget.
163        """
164        text = ScrollingText(
165            notebook, font=self.base_font, height=11, width=50, wrap=tk.WORD,
166            undo=False, relief=tk.FLAT, spacing1=INTERNAL_PAD
167        )
168        tab = text.get_frame()
169        text.image_create(tk.END, image=self.logo)
170        text.insert(tk.END, "\n")
171        text.insert(tk.END, self.about.get_name() + "\n", "large")
172        text.insert(tk.END, _("Version {}").format(self.about.get_version_string()) + "\n")
173        copyright_text = self.about.get_copyright_text()
174        if copyright_text:
175            text.insert(tk.END, copyright_text + "\n")
176        if self.about.url:
177            token = uuid4().hex
178            text.insert(tk.END, _("Source Code"), ("link", token))
179            text.insert(tk.END, self.about.url, "linkurl")
180            text.insert(tk.END, "\n")
181            TextToolTip(text, self.about.url, token)
182        text.tag_add("center", "1.0", "end-1c")
183        text.insert(tk.END, self.about.description)
184        text.config(state=tk.DISABLED, padx=INTERNAL_PAD)
185        return tab

Create the About page of the Notebook widget.

def create_translators_tab(self, notebook: tkinter.ttk.Notebook) -> tkinter.ttk.Frame:
187    def create_translators_tab(self, notebook: ttk.Notebook) -> ttk.Frame:
188        """
189        Create the Translators page of the Notebook widget.
190        """
191        text = ScrollingText(
192            notebook, font=self.base_font, height=10, width=50, wrap=tk.WORD,
193            undo=False, relief=tk.FLAT
194        )
195        tab = text.get_frame()
196        for language, translator_list in TRANSLATORS.items():
197            text.insert(tk.END, f"{language}: ", "bold")
198            for idx, translator in enumerate(translator_list):
199                self._add_translator(text, translator, idx, len(translator_list))
200        text.delete("end-1c")  # remove the final "\n"
201        text.config(state=tk.DISABLED, spacing1=4, spacing2=4, spacing3=4)
202        return tab

Create the Translators page of the Notebook widget.

def create_license_tab( self, notebook: tkinter.ttk.Notebook, license_data: LicenseMetadata) -> tkinter.ttk.Frame:
220    def create_license_tab(
221        self, notebook: ttk.Notebook, license_data: LicenseMetadata
222    ) -> ttk.Frame:
223        """
224        Create the License details page of the Notebook widget.
225        """
226        text = ScrollingText(
227            notebook, font=self.base_font, height=15, width=50, wrap=tk.WORD,
228            undo=False, relief=tk.FLAT
229        )
230        tab = text.get_frame()
231        if license_data.full_license:
232            license_text = [
233                paragraph.replace(
234                    "\n", " "
235                ) for paragraph in license_data.full_license.split("\n\n")
236            ]
237            text.insert(tk.END, "\n\n".join(license_text))
238        elif license_data.license_name:
239            text.config(spacing1=4, spacing2=4, spacing3=4, height=5)
240            text.insert(tk.END, license_data.license_name + "\n")
241            if license_data.license_url:
242                token = uuid4().hex
243                text.insert(tk.END, _("Full license text available here"), ("link", token))
244                text.insert(tk.END, license_data.license_url, "linkurl")
245                TextToolTip(text, license_data.license_url, token)
246            text.tag_add("center", "1.0", "end-1c")
247        text.config(state=tk.DISABLED)
248        return tab

Create the License details page of the Notebook widget.

Inherited Members
ModalDialog
load_fonts
bind_events
make_modal
dismiss
save_and_dismiss
save_dismiss_event
add_close_button
add_ok_cancel_buttons
add_sizegrip
sysmon_pytk.widgets.buttons.ButtonMixin
add_buttons
init_standard_buttons
tkinter.BaseWidget
destroy
tkinter.Misc
deletecommand
tk_strictMotif
tk_bisque
tk_setPalette
wait_variable
waitvar
wait_window
wait_visibility
setvar
getvar
getboolean
focus_set
focus
focus_force
focus_get
focus_displayof
focus_lastfor
tk_focusFollowsMouse
tk_focusNext
tk_focusPrev
after
after_idle
after_cancel
bell
clipboard_get
clipboard_clear
clipboard_append
grab_current
grab_release
grab_set
grab_set_global
grab_status
option_add
option_clear
option_get
option_readfile
selection_clear
selection_get
selection_handle
selection_own
selection_own_get
send
lower
tkraise
lift
winfo_atom
winfo_atomname
winfo_cells
winfo_children
winfo_class
winfo_colormapfull
winfo_containing
winfo_depth
winfo_exists
winfo_fpixels
winfo_geometry
winfo_height
winfo_id
winfo_interps
winfo_ismapped
winfo_manager
winfo_name
winfo_parent
winfo_pathname
winfo_pixels
winfo_pointerx
winfo_pointerxy
winfo_pointery
winfo_reqheight
winfo_reqwidth
winfo_rgb
winfo_rootx
winfo_rooty
winfo_screen
winfo_screencells
winfo_screendepth
winfo_screenheight
winfo_screenmmheight
winfo_screenmmwidth
winfo_screenvisual
winfo_screenwidth
winfo_server
winfo_toplevel
winfo_viewable
winfo_visual
winfo_visualid
winfo_visualsavailable
winfo_vrootheight
winfo_vrootwidth
winfo_vrootx
winfo_vrooty
winfo_width
winfo_x
winfo_y
update
update_idletasks
bindtags
bind
unbind
bind_all
unbind_all
bind_class
unbind_class
mainloop
quit
nametowidget
register
configure
config
cget
keys
pack_propagate
propagate
pack_slaves
slaves
place_slaves
grid_anchor
anchor
grid_bbox
bbox
grid_columnconfigure
columnconfigure
grid_location
grid_propagate
grid_rowconfigure
rowconfigure
grid_size
size
grid_slaves
event_add
event_delete
event_generate
event_info
image_names
image_types
tkinter.Wm
wm_aspect
aspect
wm_attributes
attributes
wm_client
client
wm_colormapwindows
colormapwindows
wm_command
command
wm_deiconify
deiconify
wm_focusmodel
focusmodel
wm_forget
forget
wm_frame
frame
wm_geometry
geometry
wm_grid
grid
wm_group
group
wm_iconbitmap
iconbitmap
wm_iconify
iconify
wm_iconmask
iconmask
wm_iconname
iconname
wm_iconphoto
iconphoto
wm_iconposition
iconposition
wm_iconwindow
iconwindow
wm_manage
manage
wm_maxsize
maxsize
wm_minsize
minsize
wm_overrideredirect
overrideredirect
wm_positionfrom
positionfrom
wm_protocol
protocol
wm_resizable
resizable
wm_sizefrom
sizefrom
wm_state
state
wm_title
title
wm_transient
transient
wm_withdraw
withdraw
@dataclasses.dataclass
class AboutMetadata:
44@dataclasses.dataclass
45class AboutMetadata:
46    """
47    Metadata about the application.
48    """
49
50    app_name: str
51    """The application name."""
52    version: str
53    """The current version of the application."""
54    author: str
55    """The author of the application."""
56    copyright_year: str
57    """The copyright year of the application."""
58    description: str
59    """A description of the application."""
60    url: str
61    """A URL that points to the source code repository for the application."""
62    license: LicenseMetadata | None = None
63    """License metadata about the application."""
64
65    def get_copyright_text(self) -> str:
66        """
67        Build the copyright text based on year and author.
68        """
69        if self.author:
70            if self.copyright_year:
71                return f{self.copyright_year} {self.author}"
72            return f{self.author}"
73        return ""
74
75    def get_name(self) -> str:
76        """
77        Return the app name meta data if available; otherwise, main script name.
78        """
79        return self.app_name if self.app_name else get_main_script()
80
81    def get_version_string(self) -> str:
82        """
83        Return a string containing the version if available; otherwise, 0.0.1.
84        """
85        return self.version if self.version else "0.0.1"

Metadata about the application.

app_name: str

The application name.

version: str

The current version of the application.

author: str

The author of the application.

copyright_year: str

The copyright year of the application.

description: str

A description of the application.

url: str

A URL that points to the source code repository for the application.

license: LicenseMetadata | None = None

License metadata about the application.

def get_name(self) -> str:
75    def get_name(self) -> str:
76        """
77        Return the app name meta data if available; otherwise, main script name.
78        """
79        return self.app_name if self.app_name else get_main_script()

Return the app name meta data if available; otherwise, main script name.

def get_version_string(self) -> str:
81    def get_version_string(self) -> str:
82        """
83        Return a string containing the version if available; otherwise, 0.0.1.
84        """
85        return self.version if self.version else "0.0.1"

Return a string containing the version if available; otherwise, 0.0.1.

@dataclasses.dataclass
class LicenseMetadata:
30@dataclasses.dataclass
31class LicenseMetadata:
32    """
33    Metadata about the license used by the application.
34    """
35
36    full_license: str
37    """The full license text for the application. Can be an empty string."""
38    license_name: str
39    """The name of the license used by the application."""
40    license_url: str
41    """A URL pointing to an online copy of the license text."""

Metadata about the license used by the application.

full_license: str

The full license text for the application. Can be an empty string.

license_name: str

The name of the license used by the application.

license_url: str

A URL pointing to an online copy of the license text.

class CpuDialog(sysmon_pytk.modals.ModalDialog):
 28class CpuDialog(ModalDialog):
 29    """
 30    Display individual CPU core usage details in a modal dialog.
 31
 32    Attributes
 33    ----------
 34    cpu_count : int
 35        The number of logical CPUs in the system.
 36    """
 37
 38    MAX_COLUMNS = 4
 39
 40    def __init__(
 41        self, parent: Misc | None = None, *, title: str | None = None,
 42        iconpath: str | None = None
 43    ) -> None:
 44        """
 45        Construct a modal dialog containing information about CPU usage.
 46
 47        Parameters
 48        ----------
 49        parent : Misc, optional
 50            The parent widget.
 51        title : str, optional
 52            The title to display in the window title bar.
 53        iconpath : str, optional
 54            The path to the icon to display in the window title bar.
 55        """
 56        self._max_used_column = 0
 57        super().__init__(parent, title=title, iconpath=iconpath)
 58
 59    def on_save(self) -> None:
 60        """
 61        Save what was entered in the modal dialog.
 62
 63        This dialog does not need a save feature.
 64        """
 65
 66    def create_widgets(self) -> None:
 67        """
 68        Create the widgets to be displayed in the modal dialog.
 69        """
 70        self.cpu_count = psutil.cpu_count()
 71        self.internal_frame.columnconfigure(0, weight=1)
 72        self.internal_frame.columnconfigure(1, weight=1)
 73        self.internal_frame.columnconfigure(2, weight=1)
 74        self.internal_frame.columnconfigure(3, weight=1)
 75        self._meter_rows: list[int] = []
 76        self._meters: list[Meter] = []
 77        self._freqmeters: list[Meter] = []
 78        ttk.Label(
 79            self.internal_frame, text=_common.get_processor_name(),
 80            font=self.large_font, anchor=tk.CENTER
 81        ).grid(columnspan=self.MAX_COLUMNS, sticky=tk.EW, ipady=_common.INTERNAL_PAD)
 82        ttk.Label(
 83            self.internal_frame, text=_("per-core CPU Usage"),
 84            font=self.large_font, anchor=tk.CENTER
 85        ).grid(columnspan=self.MAX_COLUMNS, row=1, sticky=tk.EW)
 86        row = 2
 87        row = self._create_usage_widgets(row) + 1
 88        ttk.Label(
 89            self.internal_frame, text=_("per-core CPU Frequency (in MHz)"),
 90            font=self.large_font, anchor=tk.CENTER
 91        ).grid(columnspan=self.MAX_COLUMNS, row=row, sticky=tk.EW)
 92        row = self._create_freq_widgets(row+1) + 1
 93        for meter_row in self._meter_rows:
 94            self.internal_frame.rowconfigure(meter_row, weight=1)
 95        self.add_close_button()
 96        self.add_sizegrip()
 97
 98    def _create_usage_widgets(self, start_row: int) -> int:
 99        row = start_row
100        col = 0
101        for core in range(self.cpu_count):
102            meter = Meter(
103                self.internal_frame, width=220, height=165, unit="%",
104                label=_("CPU #{}").format(core)
105            )
106            meter.grid(row=row, column=col, sticky=tk.NSEW, ipady=_common.INTERNAL_PAD)
107            if row not in self._meter_rows:
108                self._meter_rows.append(row)
109            self._meters.append(meter)
110            self._max_used_column = max(self._max_used_column, col)
111            col += 1
112            if col == self.MAX_COLUMNS:
113                col = 0
114                row += 1
115        return row
116
117    def _create_freq_widgets(self, start_row: int) -> int:
118        row = start_row
119        col = 0
120        freqs = psutil.cpu_freq(percpu=True)
121        for core in range(self.cpu_count):
122            meter = Meter(
123                self.internal_frame, width=220, height=165, unit="",
124                label=_("CPU #{}").format(core),
125                min_value=freqs[core].min, max_value=freqs[core].max  # type: ignore[attr-defined]
126            )
127            meter.grid(row=row, column=col, sticky=tk.NSEW, ipady=_common.INTERNAL_PAD)
128            if row not in self._meter_rows:
129                self._meter_rows.append(row)
130            self._freqmeters.append(meter)
131            self._max_used_column = max(self._max_used_column, col)
132            col += 1
133            if col == self.MAX_COLUMNS:
134                col = 0
135                row += 1
136        return row
137
138    def update_screen(self) -> None:
139        """
140        Update the modal dialog window.
141        """
142        usage = psutil.cpu_percent(interval=None, percpu=True)
143        for core in range(self.cpu_count):
144            self._meters[core].set_value(usage[core])
145        freqs = psutil.cpu_freq(percpu=True)
146        for core in range(self.cpu_count):
147            self._freqmeters[core].set_value(freqs[core].current)  # type: ignore[attr-defined]
148        self.after(_common.REFRESH_INTERVAL, self.update_screen)

Display individual CPU core usage details in a modal dialog.

Attributes
  • cpu_count (int): The number of logical CPUs in the system.
CpuDialog( parent: tkinter.Misc | None = None, *, title: str | None = None, iconpath: str | None = None)
40    def __init__(
41        self, parent: Misc | None = None, *, title: str | None = None,
42        iconpath: str | None = None
43    ) -> None:
44        """
45        Construct a modal dialog containing information about CPU usage.
46
47        Parameters
48        ----------
49        parent : Misc, optional
50            The parent widget.
51        title : str, optional
52            The title to display in the window title bar.
53        iconpath : str, optional
54            The path to the icon to display in the window title bar.
55        """
56        self._max_used_column = 0
57        super().__init__(parent, title=title, iconpath=iconpath)

Construct a modal dialog containing information about CPU usage.

Parameters
  • parent (Misc, optional): The parent widget.
  • title (str, optional): The title to display in the window title bar.
  • iconpath (str, optional): The path to the icon to display in the window title bar.
def on_save(self) -> None:
59    def on_save(self) -> None:
60        """
61        Save what was entered in the modal dialog.
62
63        This dialog does not need a save feature.
64        """

Save what was entered in the modal dialog.

This dialog does not need a save feature.

def create_widgets(self) -> None:
66    def create_widgets(self) -> None:
67        """
68        Create the widgets to be displayed in the modal dialog.
69        """
70        self.cpu_count = psutil.cpu_count()
71        self.internal_frame.columnconfigure(0, weight=1)
72        self.internal_frame.columnconfigure(1, weight=1)
73        self.internal_frame.columnconfigure(2, weight=1)
74        self.internal_frame.columnconfigure(3, weight=1)
75        self._meter_rows: list[int] = []
76        self._meters: list[Meter] = []
77        self._freqmeters: list[Meter] = []
78        ttk.Label(
79            self.internal_frame, text=_common.get_processor_name(),
80            font=self.large_font, anchor=tk.CENTER
81        ).grid(columnspan=self.MAX_COLUMNS, sticky=tk.EW, ipady=_common.INTERNAL_PAD)
82        ttk.Label(
83            self.internal_frame, text=_("per-core CPU Usage"),
84            font=self.large_font, anchor=tk.CENTER
85        ).grid(columnspan=self.MAX_COLUMNS, row=1, sticky=tk.EW)
86        row = 2
87        row = self._create_usage_widgets(row) + 1
88        ttk.Label(
89            self.internal_frame, text=_("per-core CPU Frequency (in MHz)"),
90            font=self.large_font, anchor=tk.CENTER
91        ).grid(columnspan=self.MAX_COLUMNS, row=row, sticky=tk.EW)
92        row = self._create_freq_widgets(row+1) + 1
93        for meter_row in self._meter_rows:
94            self.internal_frame.rowconfigure(meter_row, weight=1)
95        self.add_close_button()
96        self.add_sizegrip()

Create the widgets to be displayed in the modal dialog.

def update_screen(self) -> None:
138    def update_screen(self) -> None:
139        """
140        Update the modal dialog window.
141        """
142        usage = psutil.cpu_percent(interval=None, percpu=True)
143        for core in range(self.cpu_count):
144            self._meters[core].set_value(usage[core])
145        freqs = psutil.cpu_freq(percpu=True)
146        for core in range(self.cpu_count):
147            self._freqmeters[core].set_value(freqs[core].current)  # type: ignore[attr-defined]
148        self.after(_common.REFRESH_INTERVAL, self.update_screen)

Update the modal dialog window.

Inherited Members
ModalDialog
load_fonts
bind_events
make_modal
dismiss
save_and_dismiss
save_dismiss_event
add_close_button
add_ok_cancel_buttons
add_sizegrip
sysmon_pytk.widgets.buttons.ButtonMixin
add_buttons
init_standard_buttons
tkinter.BaseWidget
destroy
tkinter.Misc
deletecommand
tk_strictMotif
tk_bisque
tk_setPalette
wait_variable
waitvar
wait_window
wait_visibility
setvar
getvar
getboolean
focus_set
focus
focus_force
focus_get
focus_displayof
focus_lastfor
tk_focusFollowsMouse
tk_focusNext
tk_focusPrev
after
after_idle
after_cancel
bell
clipboard_get
clipboard_clear
clipboard_append
grab_current
grab_release
grab_set
grab_set_global
grab_status
option_add
option_clear
option_get
option_readfile
selection_clear
selection_get
selection_handle
selection_own
selection_own_get
send
lower
tkraise
lift
winfo_atom
winfo_atomname
winfo_cells
winfo_children
winfo_class
winfo_colormapfull
winfo_containing
winfo_depth
winfo_exists
winfo_fpixels
winfo_geometry
winfo_height
winfo_id
winfo_interps
winfo_ismapped
winfo_manager
winfo_name
winfo_parent
winfo_pathname
winfo_pixels
winfo_pointerx
winfo_pointerxy
winfo_pointery
winfo_reqheight
winfo_reqwidth
winfo_rgb
winfo_rootx
winfo_rooty
winfo_screen
winfo_screencells
winfo_screendepth
winfo_screenheight
winfo_screenmmheight
winfo_screenmmwidth
winfo_screenvisual
winfo_screenwidth
winfo_server
winfo_toplevel
winfo_viewable
winfo_visual
winfo_visualid
winfo_visualsavailable
winfo_vrootheight
winfo_vrootwidth
winfo_vrootx
winfo_vrooty
winfo_width
winfo_x
winfo_y
update
update_idletasks
bindtags
bind
unbind
bind_all
unbind_all
bind_class
unbind_class
mainloop
quit
nametowidget
register
configure
config
cget
keys
pack_propagate
propagate
pack_slaves
slaves
place_slaves
grid_anchor
anchor
grid_bbox
bbox
grid_columnconfigure
columnconfigure
grid_location
grid_propagate
grid_rowconfigure
rowconfigure
grid_size
size
grid_slaves
event_add
event_delete
event_generate
event_info
image_names
image_types
tkinter.Wm
wm_aspect
aspect
wm_attributes
attributes
wm_client
client
wm_colormapwindows
colormapwindows
wm_command
command
wm_deiconify
deiconify
wm_focusmodel
focusmodel
wm_forget
forget
wm_frame
frame
wm_geometry
geometry
wm_grid
grid
wm_group
group
wm_iconbitmap
iconbitmap
wm_iconify
iconify
wm_iconmask
iconmask
wm_iconname
iconname
wm_iconphoto
iconphoto
wm_iconposition
iconposition
wm_iconwindow
iconwindow
wm_manage
manage
wm_maxsize
maxsize
wm_minsize
minsize
wm_overrideredirect
overrideredirect
wm_positionfrom
positionfrom
wm_protocol
protocol
wm_resizable
resizable
wm_sizefrom
sizefrom
wm_state
state
wm_title
title
wm_transient
transient
wm_withdraw
withdraw
class DiskUsageDialog(sysmon_pytk.modals.ModalDialog):
 27class DiskUsageDialog(ModalDialog):
 28    """
 29    Display disk usage in a modal dialog.
 30    """
 31
 32    def __init__(
 33        self, parent: Misc | None = None, *, title: str | None = None,
 34        iconpath: str | None = None
 35    ) -> None:
 36        """
 37        Construct a modal dialog containing information about disk usage.
 38
 39        Parameters
 40        ----------
 41        parent : Misc, optional
 42            The parent widget.
 43        title : str, optional
 44            The title to display in the window title bar.
 45        iconpath : str, optional
 46            The path to the icon to display in the window title bar.
 47        """
 48        self._update_job: str | None = None
 49        super().__init__(parent, title=title, iconpath=iconpath)
 50
 51    def on_save(self) -> None:
 52        """
 53        Save what was entered in the modal dialog.
 54
 55        This dialog does not need a save feature.
 56        """
 57
 58    def create_widgets(self) -> None:
 59        """
 60        Create the widgets to be displayed in the modal dialog.
 61        """
 62        self._diskmounts: list[str] = []
 63        self._diskusages: list[tk.IntVar] = []
 64        self._diskusagefmts: list[tk.StringVar] = []
 65        self._disklabels: list[ttk.Label] = []
 66        for part in psutil.disk_partitions():
 67            self._diskmounts.append(part.mountpoint)
 68            self._diskusages.append(tk.IntVar())
 69            self._diskusagefmts.append(tk.StringVar())
 70        self.internal_frame.columnconfigure(0, weight=1)
 71        ttk.Label(
 72            self.internal_frame, text=_("Disk Usage"), font=self.large_font,
 73            anchor=tk.CENTER
 74        ).grid(columnspan=2, sticky=tk.NSEW, ipady=_common.INTERNAL_PAD)
 75        self._create_mount_widgets()
 76        for i in range(1, 2*len(self._diskmounts) + 1):
 77            self.internal_frame.rowconfigure(i, weight=1)
 78        self.add_close_button()
 79        self.add_sizegrip()
 80
 81    def _create_mount_widgets(self) -> None:
 82        for col, mountpoint in enumerate(self._diskmounts):
 83            ttk.Label(
 84                self.internal_frame, text=mountpoint, anchor=tk.SW,
 85                font=self.base_font
 86            ).grid(row=2*col + 1, column=0, sticky=tk.NSEW)
 87            ttk.Progressbar(
 88                self.internal_frame, length=300, orient=tk.HORIZONTAL,
 89                variable=self._diskusages[col]
 90            ).grid(row=2*col + 2, column=0, sticky=tk.NSEW)
 91            usagelabel = ttk.Label(
 92                self.internal_frame, textvariable=self._diskusagefmts[col],
 93                anchor=tk.E, font=self.fixed_font
 94            )
 95            self._disklabels.append(usagelabel)
 96            usagelabel.grid(
 97                row=2*col + 2, column=1, padx=_common.INTERNAL_PAD,
 98                sticky=tk.NSEW
 99            )
100
101    def reset(self) -> None:
102        """
103        Reset the dialog.
104        """
105        if self._update_job is not None:
106            self.after_cancel(self._update_job)
107            self._update_job = None
108        self.internal_frame.destroy()
109        self.create_widgets()
110        self.update_screen()
111
112    def check_mount_points(self) -> bool:
113        """
114        Check to see if any additional mount points have appeared.
115        """
116        return any(
117            part.mountpoint not in self._diskmounts for part in psutil.disk_partitions()
118        )
119
120    def update_screen(self) -> None:
121        """
122        Update the modal dialog window.
123        """
124        if self.check_mount_points():
125            self.reset()
126            return
127        # process the mount points
128        try:
129            for col, mountpoint in enumerate(self._diskmounts):
130                usage = psutil.disk_usage(mountpoint).percent
131                self._diskusages[col].set(round(usage))
132                self._diskusagefmts[col].set(_common.disk_usage(mountpoint))
133                self._disklabels[col].configure(style=self._get_alert_style(usage))
134        except FileNotFoundError:
135            # disk was unmounted, reset the widget
136            self.reset()
137            return
138        self._update_job = self.after(_common.REFRESH_INTERVAL, self.update_screen)
139
140    @classmethod
141    def _get_alert_style(cls, usage: float) -> str:
142        if usage >= _common.DISK_ALERT_LEVEL:
143            return "Alert.TLabel"
144        if usage >= _common.DISK_WARN_LEVEL:
145            return "Warn.TLabel"
146        return "Safe.TLabel"

Display disk usage in a modal dialog.

DiskUsageDialog( parent: tkinter.Misc | None = None, *, title: str | None = None, iconpath: str | None = None)
32    def __init__(
33        self, parent: Misc | None = None, *, title: str | None = None,
34        iconpath: str | None = None
35    ) -> None:
36        """
37        Construct a modal dialog containing information about disk usage.
38
39        Parameters
40        ----------
41        parent : Misc, optional
42            The parent widget.
43        title : str, optional
44            The title to display in the window title bar.
45        iconpath : str, optional
46            The path to the icon to display in the window title bar.
47        """
48        self._update_job: str | None = None
49        super().__init__(parent, title=title, iconpath=iconpath)

Construct a modal dialog containing information about disk usage.

Parameters
  • parent (Misc, optional): The parent widget.
  • title (str, optional): The title to display in the window title bar.
  • iconpath (str, optional): The path to the icon to display in the window title bar.
def on_save(self) -> None:
51    def on_save(self) -> None:
52        """
53        Save what was entered in the modal dialog.
54
55        This dialog does not need a save feature.
56        """

Save what was entered in the modal dialog.

This dialog does not need a save feature.

def create_widgets(self) -> None:
58    def create_widgets(self) -> None:
59        """
60        Create the widgets to be displayed in the modal dialog.
61        """
62        self._diskmounts: list[str] = []
63        self._diskusages: list[tk.IntVar] = []
64        self._diskusagefmts: list[tk.StringVar] = []
65        self._disklabels: list[ttk.Label] = []
66        for part in psutil.disk_partitions():
67            self._diskmounts.append(part.mountpoint)
68            self._diskusages.append(tk.IntVar())
69            self._diskusagefmts.append(tk.StringVar())
70        self.internal_frame.columnconfigure(0, weight=1)
71        ttk.Label(
72            self.internal_frame, text=_("Disk Usage"), font=self.large_font,
73            anchor=tk.CENTER
74        ).grid(columnspan=2, sticky=tk.NSEW, ipady=_common.INTERNAL_PAD)
75        self._create_mount_widgets()
76        for i in range(1, 2*len(self._diskmounts) + 1):
77            self.internal_frame.rowconfigure(i, weight=1)
78        self.add_close_button()
79        self.add_sizegrip()

Create the widgets to be displayed in the modal dialog.

def reset(self) -> None:
101    def reset(self) -> None:
102        """
103        Reset the dialog.
104        """
105        if self._update_job is not None:
106            self.after_cancel(self._update_job)
107            self._update_job = None
108        self.internal_frame.destroy()
109        self.create_widgets()
110        self.update_screen()

Reset the dialog.

def check_mount_points(self) -> bool:
112    def check_mount_points(self) -> bool:
113        """
114        Check to see if any additional mount points have appeared.
115        """
116        return any(
117            part.mountpoint not in self._diskmounts for part in psutil.disk_partitions()
118        )

Check to see if any additional mount points have appeared.

def update_screen(self) -> None:
120    def update_screen(self) -> None:
121        """
122        Update the modal dialog window.
123        """
124        if self.check_mount_points():
125            self.reset()
126            return
127        # process the mount points
128        try:
129            for col, mountpoint in enumerate(self._diskmounts):
130                usage = psutil.disk_usage(mountpoint).percent
131                self._diskusages[col].set(round(usage))
132                self._diskusagefmts[col].set(_common.disk_usage(mountpoint))
133                self._disklabels[col].configure(style=self._get_alert_style(usage))
134        except FileNotFoundError:
135            # disk was unmounted, reset the widget
136            self.reset()
137            return
138        self._update_job = self.after(_common.REFRESH_INTERVAL, self.update_screen)

Update the modal dialog window.

Inherited Members
ModalDialog
load_fonts
bind_events
make_modal
dismiss
save_and_dismiss
save_dismiss_event
add_close_button
add_ok_cancel_buttons
add_sizegrip
sysmon_pytk.widgets.buttons.ButtonMixin
add_buttons
init_standard_buttons
tkinter.BaseWidget
destroy
tkinter.Misc
deletecommand
tk_strictMotif
tk_bisque
tk_setPalette
wait_variable
waitvar
wait_window
wait_visibility
setvar
getvar
getboolean
focus_set
focus
focus_force
focus_get
focus_displayof
focus_lastfor
tk_focusFollowsMouse
tk_focusNext
tk_focusPrev
after
after_idle
after_cancel
bell
clipboard_get
clipboard_clear
clipboard_append
grab_current
grab_release
grab_set
grab_set_global
grab_status
option_add
option_clear
option_get
option_readfile
selection_clear
selection_get
selection_handle
selection_own
selection_own_get
send
lower
tkraise
lift
winfo_atom
winfo_atomname
winfo_cells
winfo_children
winfo_class
winfo_colormapfull
winfo_containing
winfo_depth
winfo_exists
winfo_fpixels
winfo_geometry
winfo_height
winfo_id
winfo_interps
winfo_ismapped
winfo_manager
winfo_name
winfo_parent
winfo_pathname
winfo_pixels
winfo_pointerx
winfo_pointerxy
winfo_pointery
winfo_reqheight
winfo_reqwidth
winfo_rgb
winfo_rootx
winfo_rooty
winfo_screen
winfo_screencells
winfo_screendepth
winfo_screenheight
winfo_screenmmheight
winfo_screenmmwidth
winfo_screenvisual
winfo_screenwidth
winfo_server
winfo_toplevel
winfo_viewable
winfo_visual
winfo_visualid
winfo_visualsavailable
winfo_vrootheight
winfo_vrootwidth
winfo_vrootx
winfo_vrooty
winfo_width
winfo_x
winfo_y
update
update_idletasks
bindtags
bind
unbind
bind_all
unbind_all
bind_class
unbind_class
mainloop
quit
nametowidget
register
configure
config
cget
keys
pack_propagate
propagate
pack_slaves
slaves
place_slaves
grid_anchor
anchor
grid_bbox
bbox
grid_columnconfigure
columnconfigure
grid_location
grid_propagate
grid_rowconfigure
rowconfigure
grid_size
size
grid_slaves
event_add
event_delete
event_generate
event_info
image_names
image_types
tkinter.Wm
wm_aspect
aspect
wm_attributes
attributes
wm_client
client
wm_colormapwindows
colormapwindows
wm_command
command
wm_deiconify
deiconify
wm_focusmodel
focusmodel
wm_forget
forget
wm_frame
frame
wm_geometry
geometry
wm_grid
grid
wm_group
group
wm_iconbitmap
iconbitmap
wm_iconify
iconify
wm_iconmask
iconmask
wm_iconname
iconname
wm_iconphoto
iconphoto
wm_iconposition
iconposition
wm_iconwindow
iconwindow
wm_manage
manage
wm_maxsize
maxsize
wm_minsize
minsize
wm_overrideredirect
overrideredirect
wm_positionfrom
positionfrom
wm_protocol
protocol
wm_resizable
resizable
wm_sizefrom
sizefrom
wm_state
state
wm_title
title
wm_transient
transient
wm_withdraw
withdraw
class FontChooser(sysmon_pytk.modals.ModalDialog):
 31class FontChooser(ModalDialog):
 32    """
 33    Font chooser dialog.
 34
 35    Attributes
 36    ----------
 37    current_font : FontDescription, optional
 38        The currently selected font.
 39    fontchoices : List[str]
 40        A list of font families available on the system.
 41    fontname : str
 42        The font name.
 43    fontsize : IntVar
 44        The font size.
 45    fontstyle : StringVar
 46        The font style.
 47    underline : BooleanVar
 48        A flag indicating whether the font uses underline.
 49    overstrike : BooleanVar
 50        A flag indicating whether the font uses strikethrough.
 51    preview_font : Font
 52        A font using the currently selected details. Used to show the user
 53        what a sample text looks like.
 54    """
 55
 56    PREVIEW_TEXT = "AaÁáÅåCcÇçNnÑñSsẞßUuÜü 0123456789"
 57
 58    def __init__(
 59        self, parent: Misc | None = None, *,
 60        current_font: FontDescription | None = None,
 61        iconpath: str | None = None
 62    ) -> None:
 63        """
 64        Construct a FontChooser dialog.
 65
 66        Parameters
 67        ----------
 68        parent : Misc, optional
 69            The parent widget.
 70        current_font : FontDescription, optional
 71            The currently selected font.
 72        iconpath : str
 73            The path to the icon to display in the window title bar.
 74        """
 75        title = _("Choose Font")
 76        self.current_font = current_font
 77        self.fontchoices = list(set(font.families()))
 78        self.fontchoices.sort()
 79        self.fontsize = tk.IntVar()
 80        self.fontstyle = tk.StringVar()
 81        self.underline = tk.BooleanVar()
 82        self.overstrike = tk.BooleanVar()
 83        if self.current_font is not None:
 84            self.fontname: str | None = self.current_font.family
 85            self.fontstyle.set(str(self.current_font.get_style()))
 86            self.fontsize.set(self.current_font.size)
 87            self.underline.set(self.current_font.underline)
 88            self.overstrike.set(self.current_font.overstrike)
 89            self.preview_font = self.current_font.get_font()
 90        else:
 91            # default selections
 92            self.fontname = None
 93            self.fontstyle.set(str(FontStyle.REGULAR))
 94            self.fontsize.set(12)
 95            self.underline.set(False)
 96            self.overstrike.set(False)
 97            self.preview_font = self.base_font
 98        self.fontsize.trace_add("write", self._update_preview)
 99        self.fontstyle.trace_add("write", self._update_preview)
100        self.underline.trace_add("write", self._update_preview)
101        self.overstrike.trace_add("write", self._update_preview)
102        super().__init__(parent, title=title, iconpath=iconpath, class_="FontChooser")
103
104    def update_screen(self) -> None:
105        """
106        Update the modal dialog window.
107
108        This dialog does not require screen updates.
109        """
110
111    def create_widgets(self) -> None:
112        """
113        Create the widgets that are displayed in the dialog.
114        """
115        self.internal_frame.rowconfigure(1, weight=1)
116        self.internal_frame.columnconfigure(0, weight=1)
117        self._create_font_family_widget_frame()
118        self._create_font_option_widgets()
119        self._create_font_size_widgets()
120        self._create_font_preview_widgets()
121        self.add_ok_cancel_buttons()
122        self.add_sizegrip()
123
124    def _create_font_family_widget_frame(self) -> None:
125        familyframe = ttk.Frame(self.internal_frame)
126        familyframe.grid(
127            row=0, rowspan=2, sticky=tk.NSEW,
128            padx=(_common.INTERNAL_PAD, 0), pady=(_common.INTERNAL_PAD, 0)
129        )
130        familyframe.rowconfigure(1, weight=1)
131        familyframe.columnconfigure(0, weight=1)
132        ttk.Label(
133            familyframe, text=_("Font"), font=self.base_font
134        ).grid(row=0, sticky=tk.NSEW)
135        choicesvar = tk.StringVar(value=self.fontchoices)  # type: ignore[arg-type]
136        lbox = tk.Listbox(
137            familyframe, listvariable=choicesvar, height=10, width=30, bd=1,
138            exportselection=0, relief=tk.FLAT, background="#555555",
139            font=self.base_font
140        )
141        bg1 = StyleManager.test_dark_mode("#333333", "#ffffff")
142        bg2 = StyleManager.test_dark_mode("#444444", "#eeeeff")
143        for idx, item in enumerate(self.fontchoices):
144            item_bg = bg1 if idx % 2 else bg2
145            lbox.itemconfig(idx, background=item_bg)
146            if item == self.fontname:
147                lbox.selection_set(idx)
148                lbox.see(idx)
149        lbox.grid(row=1, column=0, sticky=tk.NSEW)
150        scroll = ttk.Scrollbar(familyframe, orient=tk.VERTICAL)
151        scroll.grid(row=1, column=1, sticky=tk.NS)
152        lbox.config(yscrollcommand=scroll.set)
153        scroll.config(command=lbox.yview)
154        lbox.bind("<<ListboxSelect>>", self._on_select)
155
156    def _create_font_option_widgets(self) -> None:
157        styleframe = ttk.LabelFrame(
158            self.internal_frame,
159            labelwidget=ttk.Label(
160                self.internal_frame, text=_("Style"), font=self.base_font
161            )
162        )
163        styleframe.grid(
164            row=0, column=1, sticky=tk.NSEW,
165            padx=_common.INTERNAL_PAD, pady=_common.INTERNAL_PAD
166        )
167        ttk.Radiobutton(
168            styleframe, text=_("Regular"), value=FontStyle.REGULAR.value,
169            variable=self.fontstyle
170        ).grid(row=1, padx=_common.INTERNAL_PAD, sticky=tk.NSEW)
171        ttk.Radiobutton(
172            styleframe, text=_("Bold"), value=FontStyle.BOLD.value,
173            variable=self.fontstyle
174        ).grid(row=2, padx=_common.INTERNAL_PAD, sticky=tk.NSEW)
175        ttk.Radiobutton(
176            styleframe, text=_("Italic"), value=FontStyle.ITALIC.value,
177            variable=self.fontstyle
178        ).grid(row=3, padx=_common.INTERNAL_PAD, sticky=tk.NSEW)
179        ttk.Radiobutton(
180            styleframe, text=_("Bold Italic"), value=FontStyle.BOLD_ITALIC.value,
181            variable=self.fontstyle
182        ).grid(row=4, padx=_common.INTERNAL_PAD, sticky=tk.NSEW)
183
184        effectsframe = ttk.LabelFrame(
185            self.internal_frame,
186            labelwidget=ttk.Label(
187                self.internal_frame, text=_("Effects"), font=self.base_font
188            )
189        )
190        effectsframe.grid(
191            row=1, column=1, sticky=tk.N, padx=_common.INTERNAL_PAD
192        )
193        ttk.Checkbutton(
194            effectsframe, text=_("Underline"), variable=self.underline,
195            style="Switch.TCheckbutton"
196        ).grid(row=0, column=0, padx=_common.INTERNAL_PAD, sticky=tk.W)
197        ttk.Checkbutton(
198            effectsframe, text=_("Overstrike"), variable=self.overstrike,
199            style="Switch.TCheckbutton"
200        ).grid(row=1, column=0, padx=_common.INTERNAL_PAD, sticky=tk.W)
201
202    def _create_font_size_widgets(self) -> None:
203        ScaleSpinner(
204            self.internal_frame, self.fontsize, text=_("Size"), length=71*4,
205            from_=1, to=72, as_int=True
206        ).grid(
207            row=2, columnspan=2, sticky=tk.NSEW, padx=_common.INTERNAL_PAD,
208            pady=(_common.INTERNAL_PAD, 0)
209        )
210
211    def _create_font_preview_widgets(self) -> None:
212        previewframe = ttk.LabelFrame(
213            self.internal_frame, height=150, width=500,
214            labelwidget=ttk.Label(
215                self.internal_frame, text=_("Preview"), font=self.base_font
216            )
217        )
218        previewframe.grid(
219            row=3, columnspan=2, sticky=tk.NSEW,
220            padx=_common.INTERNAL_PAD, pady=(0, _common.INTERNAL_PAD)
221        )
222        previewframe.columnconfigure(0, weight=1)
223        previewframe.rowconfigure(0, weight=1)
224        previewframe.grid_propagate(False)
225        ttk.Label(
226            previewframe, text=self.PREVIEW_TEXT, font=self.preview_font,
227            anchor=tk.CENTER
228        ).grid(sticky=tk.NSEW)
229
230    def _update_preview(self, *_args) -> None:
231        try:
232            fontstyle = FontStyle(self.fontstyle.get())
233        except ValueError:
234            fontstyle = FontStyle.REGULAR
235        if self.fontname:
236            self.preview_font.configure(
237                family=self.fontname,
238                size=self.fontsize.get(),
239                weight=fontstyle.get_weight(),
240                slant=fontstyle.get_slant(),
241                underline=self.underline.get(),
242                overstrike=self.overstrike.get()
243            )
244
245    def _on_select(self, event: Event[Listbox]) -> None:
246        value = event.widget.get(event.widget.curselection()[0])
247        self.fontname = value
248        self._update_preview()
249
250    def on_save(self) -> None:
251        """
252        Update `self.current_font` based on currently selected options.
253        """
254        weight: FontWeight = "normal"
255        slant: FontSlant = "roman"
256        if self.fontstyle.get() == FontStyle.BOLD:
257            weight = "bold"
258        elif self.fontstyle.get() == FontStyle.ITALIC:
259            slant = "italic"
260        elif self.fontstyle.get() == FontStyle.BOLD_ITALIC:
261            weight = "bold"
262            slant = "italic"
263        self.current_font = FontDescription(
264            family=self.fontname,
265            size=self.fontsize.get(),
266            weight=weight,
267            slant=slant,
268            underline=self.underline.get(),
269            overstrike=self.overstrike.get()
270        ) if self.fontname is not None else None
271
272    def get_font(self) -> FontDescription | None:
273        """
274        Get the full font specification based on user's choices.
275        """
276        return self.current_font

Font chooser dialog.

Attributes
  • current_font (FontDescription, optional): The currently selected font.
  • fontchoices (List[str]): A list of font families available on the system.
  • fontname (str): The font name.
  • fontsize (IntVar): The font size.
  • fontstyle (StringVar): The font style.
  • underline (BooleanVar): A flag indicating whether the font uses underline.
  • overstrike (BooleanVar): A flag indicating whether the font uses strikethrough.
  • preview_font (Font): A font using the currently selected details. Used to show the user what a sample text looks like.
FontChooser( parent: tkinter.Misc | None = None, *, current_font: sysmon_pytk.font_utils.FontDescription | None = None, iconpath: str | None = None)
 58    def __init__(
 59        self, parent: Misc | None = None, *,
 60        current_font: FontDescription | None = None,
 61        iconpath: str | None = None
 62    ) -> None:
 63        """
 64        Construct a FontChooser dialog.
 65
 66        Parameters
 67        ----------
 68        parent : Misc, optional
 69            The parent widget.
 70        current_font : FontDescription, optional
 71            The currently selected font.
 72        iconpath : str
 73            The path to the icon to display in the window title bar.
 74        """
 75        title = _("Choose Font")
 76        self.current_font = current_font
 77        self.fontchoices = list(set(font.families()))
 78        self.fontchoices.sort()
 79        self.fontsize = tk.IntVar()
 80        self.fontstyle = tk.StringVar()
 81        self.underline = tk.BooleanVar()
 82        self.overstrike = tk.BooleanVar()
 83        if self.current_font is not None:
 84            self.fontname: str | None = self.current_font.family
 85            self.fontstyle.set(str(self.current_font.get_style()))
 86            self.fontsize.set(self.current_font.size)
 87            self.underline.set(self.current_font.underline)
 88            self.overstrike.set(self.current_font.overstrike)
 89            self.preview_font = self.current_font.get_font()
 90        else:
 91            # default selections
 92            self.fontname = None
 93            self.fontstyle.set(str(FontStyle.REGULAR))
 94            self.fontsize.set(12)
 95            self.underline.set(False)
 96            self.overstrike.set(False)
 97            self.preview_font = self.base_font
 98        self.fontsize.trace_add("write", self._update_preview)
 99        self.fontstyle.trace_add("write", self._update_preview)
100        self.underline.trace_add("write", self._update_preview)
101        self.overstrike.trace_add("write", self._update_preview)
102        super().__init__(parent, title=title, iconpath=iconpath, class_="FontChooser")

Construct a FontChooser dialog.

Parameters
  • parent (Misc, optional): The parent widget.
  • current_font (FontDescription, optional): The currently selected font.
  • iconpath (str): The path to the icon to display in the window title bar.
def update_screen(self) -> None:
104    def update_screen(self) -> None:
105        """
106        Update the modal dialog window.
107
108        This dialog does not require screen updates.
109        """

Update the modal dialog window.

This dialog does not require screen updates.

def create_widgets(self) -> None:
111    def create_widgets(self) -> None:
112        """
113        Create the widgets that are displayed in the dialog.
114        """
115        self.internal_frame.rowconfigure(1, weight=1)
116        self.internal_frame.columnconfigure(0, weight=1)
117        self._create_font_family_widget_frame()
118        self._create_font_option_widgets()
119        self._create_font_size_widgets()
120        self._create_font_preview_widgets()
121        self.add_ok_cancel_buttons()
122        self.add_sizegrip()

Create the widgets that are displayed in the dialog.

def on_save(self) -> None:
250    def on_save(self) -> None:
251        """
252        Update `self.current_font` based on currently selected options.
253        """
254        weight: FontWeight = "normal"
255        slant: FontSlant = "roman"
256        if self.fontstyle.get() == FontStyle.BOLD:
257            weight = "bold"
258        elif self.fontstyle.get() == FontStyle.ITALIC:
259            slant = "italic"
260        elif self.fontstyle.get() == FontStyle.BOLD_ITALIC:
261            weight = "bold"
262            slant = "italic"
263        self.current_font = FontDescription(
264            family=self.fontname,
265            size=self.fontsize.get(),
266            weight=weight,
267            slant=slant,
268            underline=self.underline.get(),
269            overstrike=self.overstrike.get()
270        ) if self.fontname is not None else None

Update self.current_font based on currently selected options.

def get_font(self) -> sysmon_pytk.font_utils.FontDescription | None:
272    def get_font(self) -> FontDescription | None:
273        """
274        Get the full font specification based on user's choices.
275        """
276        return self.current_font

Get the full font specification based on user's choices.

Inherited Members
ModalDialog
load_fonts
bind_events
make_modal
dismiss
save_and_dismiss
save_dismiss_event
add_close_button
add_ok_cancel_buttons
add_sizegrip
sysmon_pytk.widgets.buttons.ButtonMixin
add_buttons
init_standard_buttons
tkinter.BaseWidget
destroy
tkinter.Misc
deletecommand
tk_strictMotif
tk_bisque
tk_setPalette
wait_variable
waitvar
wait_window
wait_visibility
setvar
getvar
getboolean
focus_set
focus
focus_force
focus_get
focus_displayof
focus_lastfor
tk_focusFollowsMouse
tk_focusNext
tk_focusPrev
after
after_idle
after_cancel
bell
clipboard_get
clipboard_clear
clipboard_append
grab_current
grab_release
grab_set
grab_set_global
grab_status
option_add
option_clear
option_get
option_readfile
selection_clear
selection_get
selection_handle
selection_own
selection_own_get
send
lower
tkraise
lift
winfo_atom
winfo_atomname
winfo_cells
winfo_children
winfo_class
winfo_colormapfull
winfo_containing
winfo_depth
winfo_exists
winfo_fpixels
winfo_geometry
winfo_height
winfo_id
winfo_interps
winfo_ismapped
winfo_manager
winfo_name
winfo_parent
winfo_pathname
winfo_pixels
winfo_pointerx
winfo_pointerxy
winfo_pointery
winfo_reqheight
winfo_reqwidth
winfo_rgb
winfo_rootx
winfo_rooty
winfo_screen
winfo_screencells
winfo_screendepth
winfo_screenheight
winfo_screenmmheight
winfo_screenmmwidth
winfo_screenvisual
winfo_screenwidth
winfo_server
winfo_toplevel
winfo_viewable
winfo_visual
winfo_visualid
winfo_visualsavailable
winfo_vrootheight
winfo_vrootwidth
winfo_vrootx
winfo_vrooty
winfo_width
winfo_x
winfo_y
update
update_idletasks
bindtags
bind
unbind
bind_all
unbind_all
bind_class
unbind_class
mainloop
quit
nametowidget
register
configure
config
cget
keys
pack_propagate
propagate
pack_slaves
slaves
place_slaves
grid_anchor
anchor
grid_bbox
bbox
grid_columnconfigure
columnconfigure
grid_location
grid_propagate
grid_rowconfigure
rowconfigure
grid_size
size
grid_slaves
event_add
event_delete
event_generate
event_info
image_names
image_types
tkinter.Wm
wm_aspect
aspect
wm_attributes
attributes
wm_client
client
wm_colormapwindows
colormapwindows
wm_command
command
wm_deiconify
deiconify
wm_focusmodel
focusmodel
wm_forget
forget
wm_frame
frame
wm_geometry
geometry
wm_grid
grid
wm_group
group
wm_iconbitmap
iconbitmap
wm_iconify
iconify
wm_iconmask
iconmask
wm_iconname
iconname
wm_iconphoto
iconphoto
wm_iconposition
iconposition
wm_iconwindow
iconwindow
wm_manage
manage
wm_maxsize
maxsize
wm_minsize
minsize
wm_overrideredirect
overrideredirect
wm_positionfrom
positionfrom
wm_protocol
protocol
wm_resizable
resizable
wm_sizefrom
sizefrom
wm_state
state
wm_title
title
wm_transient
transient
wm_withdraw
withdraw
class MemUsageDialog(sysmon_pytk.modals.ModalDialog):
 23class MemUsageDialog(ModalDialog):
 24    """
 25    Display memory usage in a modal dialog.
 26    """
 27
 28    def on_save(self) -> None:
 29        """
 30        Save what was entered in the modal dialog.
 31
 32        This dialog does not need a save feature.
 33        """
 34
 35    def create_widgets(self) -> None:
 36        """
 37        Create the widgets to be displayed in the modal dialog.
 38        """
 39        mem = psutil.virtual_memory()
 40        swap = psutil.swap_memory()
 41        self._names: list[str] = []
 42        self._metrics: list[tk.StringVar] = []
 43        self._swaps: list[str] = []
 44        self._swap_metrics: list[tk.StringVar] = []
 45        for item in mem._asdict():
 46            self._names.append(item)
 47            self._metrics.append(tk.StringVar())
 48        for item in swap._asdict():
 49            self._swaps.append(item)
 50            self._swap_metrics.append(tk.StringVar())
 51        self.internal_frame.columnconfigure(0, weight=1)
 52        self.internal_frame.columnconfigure(2, weight=4)
 53        self.internal_frame.columnconfigure(3, weight=1)
 54        ttk.Label(
 55            self.internal_frame, text=_("Memory Statistics"), font=self.large_font,
 56            anchor=tk.CENTER
 57        ).grid(row=0, column=0, columnspan=5, ipady=_common.INTERNAL_PAD, sticky=tk.NSEW)
 58        ttk.Label(
 59            self.internal_frame, text=_("Virtual Memory"), font=self.bold_font,
 60            anchor=tk.CENTER
 61        ).grid(row=1, column=0, columnspan=2, sticky=tk.NSEW)
 62        ttk.Label(self.internal_frame, text="").grid(row=1, column=2)
 63        ttk.Label(
 64            self.internal_frame, text=_("Swap Memory"), font=self.bold_font,
 65            anchor=tk.CENTER
 66        ).grid(row=1, column=3, columnspan=2, sticky=tk.NSEW)
 67        self.internal_frame.columnconfigure(2, minsize=4*_common.INTERNAL_PAD)
 68        self._create_detail_widgets()
 69        max_list = max(len(self._names), len(self._swaps))
 70        for i in range(2, max_list+2):
 71            self.internal_frame.rowconfigure(i, weight=1)
 72        self.add_close_button()
 73        self.add_sizegrip()
 74
 75    def _create_detail_widgets(self) -> None:
 76        for count, name in enumerate(self._names):
 77            ttk.Label(
 78                self.internal_frame, text=name.capitalize(), anchor=tk.W,
 79                font=self.base_font
 80            ).grid(row=count+2, column=0, sticky=tk.NSEW, padx=_common.INTERNAL_PAD)
 81            ttk.Label(
 82                self.internal_frame, textvariable=self._metrics[count], anchor=tk.E,
 83                font=self.fixed_font
 84            ).grid(row=count+2, column=1, sticky=tk.NSEW, padx=_common.INTERNAL_PAD)
 85        for count, name in enumerate(self._swaps):
 86            ttk.Label(
 87                self.internal_frame, text=name.capitalize(), anchor=tk.W,
 88                font=self.base_font
 89            ).grid(row=count+2, column=3, sticky=tk.NSEW, padx=_common.INTERNAL_PAD)
 90            ttk.Label(
 91                self.internal_frame, textvariable=self._swap_metrics[count],
 92                font=self.fixed_font, anchor=tk.E
 93            ).grid(row=count+2, column=4, sticky=tk.NSEW, padx=_common.INTERNAL_PAD)
 94
 95    def update_screen(self) -> None:
 96        """
 97        Update the modal dialog window.
 98        """
 99        mem = psutil.virtual_memory()
100        swap = psutil.swap_memory()
101        for count, item in enumerate(mem._asdict().items()):
102            self._metrics[count].set(self._format_mem_item(item))
103        for count, item in enumerate(swap._asdict().items()):
104            self._swap_metrics[count].set(self._format_mem_item(item))
105        self.after(_common.REFRESH_INTERVAL, self.update_screen)
106
107    def _format_mem_item(self, item: tuple) -> str:
108        return _common.bytes2human(item[1]) if item[0] != "percent" else f"{item[1]}%"

Display memory usage in a modal dialog.

def on_save(self) -> None:
28    def on_save(self) -> None:
29        """
30        Save what was entered in the modal dialog.
31
32        This dialog does not need a save feature.
33        """

Save what was entered in the modal dialog.

This dialog does not need a save feature.

def create_widgets(self) -> None:
35    def create_widgets(self) -> None:
36        """
37        Create the widgets to be displayed in the modal dialog.
38        """
39        mem = psutil.virtual_memory()
40        swap = psutil.swap_memory()
41        self._names: list[str] = []
42        self._metrics: list[tk.StringVar] = []
43        self._swaps: list[str] = []
44        self._swap_metrics: list[tk.StringVar] = []
45        for item in mem._asdict():
46            self._names.append(item)
47            self._metrics.append(tk.StringVar())
48        for item in swap._asdict():
49            self._swaps.append(item)
50            self._swap_metrics.append(tk.StringVar())
51        self.internal_frame.columnconfigure(0, weight=1)
52        self.internal_frame.columnconfigure(2, weight=4)
53        self.internal_frame.columnconfigure(3, weight=1)
54        ttk.Label(
55            self.internal_frame, text=_("Memory Statistics"), font=self.large_font,
56            anchor=tk.CENTER
57        ).grid(row=0, column=0, columnspan=5, ipady=_common.INTERNAL_PAD, sticky=tk.NSEW)
58        ttk.Label(
59            self.internal_frame, text=_("Virtual Memory"), font=self.bold_font,
60            anchor=tk.CENTER
61        ).grid(row=1, column=0, columnspan=2, sticky=tk.NSEW)
62        ttk.Label(self.internal_frame, text="").grid(row=1, column=2)
63        ttk.Label(
64            self.internal_frame, text=_("Swap Memory"), font=self.bold_font,
65            anchor=tk.CENTER
66        ).grid(row=1, column=3, columnspan=2, sticky=tk.NSEW)
67        self.internal_frame.columnconfigure(2, minsize=4*_common.INTERNAL_PAD)
68        self._create_detail_widgets()
69        max_list = max(len(self._names), len(self._swaps))
70        for i in range(2, max_list+2):
71            self.internal_frame.rowconfigure(i, weight=1)
72        self.add_close_button()
73        self.add_sizegrip()

Create the widgets to be displayed in the modal dialog.

def update_screen(self) -> None:
 95    def update_screen(self) -> None:
 96        """
 97        Update the modal dialog window.
 98        """
 99        mem = psutil.virtual_memory()
100        swap = psutil.swap_memory()
101        for count, item in enumerate(mem._asdict().items()):
102            self._metrics[count].set(self._format_mem_item(item))
103        for count, item in enumerate(swap._asdict().items()):
104            self._swap_metrics[count].set(self._format_mem_item(item))
105        self.after(_common.REFRESH_INTERVAL, self.update_screen)

Update the modal dialog window.

Inherited Members
ModalDialog
ModalDialog
load_fonts
bind_events
make_modal
dismiss
save_and_dismiss
save_dismiss_event
add_close_button
add_ok_cancel_buttons
add_sizegrip
sysmon_pytk.widgets.buttons.ButtonMixin
add_buttons
init_standard_buttons
tkinter.BaseWidget
destroy
tkinter.Misc
deletecommand
tk_strictMotif
tk_bisque
tk_setPalette
wait_variable
waitvar
wait_window
wait_visibility
setvar
getvar
getboolean
focus_set
focus
focus_force
focus_get
focus_displayof
focus_lastfor
tk_focusFollowsMouse
tk_focusNext
tk_focusPrev
after
after_idle
after_cancel
bell
clipboard_get
clipboard_clear
clipboard_append
grab_current
grab_release
grab_set
grab_set_global
grab_status
option_add
option_clear
option_get
option_readfile
selection_clear
selection_get
selection_handle
selection_own
selection_own_get
send
lower
tkraise
lift
winfo_atom
winfo_atomname
winfo_cells
winfo_children
winfo_class
winfo_colormapfull
winfo_containing
winfo_depth
winfo_exists
winfo_fpixels
winfo_geometry
winfo_height
winfo_id
winfo_interps
winfo_ismapped
winfo_manager
winfo_name
winfo_parent
winfo_pathname
winfo_pixels
winfo_pointerx
winfo_pointerxy
winfo_pointery
winfo_reqheight
winfo_reqwidth
winfo_rgb
winfo_rootx
winfo_rooty
winfo_screen
winfo_screencells
winfo_screendepth
winfo_screenheight
winfo_screenmmheight
winfo_screenmmwidth
winfo_screenvisual
winfo_screenwidth
winfo_server
winfo_toplevel
winfo_viewable
winfo_visual
winfo_visualid
winfo_visualsavailable
winfo_vrootheight
winfo_vrootwidth
winfo_vrootx
winfo_vrooty
winfo_width
winfo_x
winfo_y
update
update_idletasks
bindtags
bind
unbind
bind_all
unbind_all
bind_class
unbind_class
mainloop
quit
nametowidget
register
configure
config
cget
keys
pack_propagate
propagate
pack_slaves
slaves
place_slaves
grid_anchor
anchor
grid_bbox
bbox
grid_columnconfigure
columnconfigure
grid_location
grid_propagate
grid_rowconfigure
rowconfigure
grid_size
size
grid_slaves
event_add
event_delete
event_generate
event_info
image_names
image_types
tkinter.Wm
wm_aspect
aspect
wm_attributes
attributes
wm_client
client
wm_colormapwindows
colormapwindows
wm_command
command
wm_deiconify
deiconify
wm_focusmodel
focusmodel
wm_forget
forget
wm_frame
frame
wm_geometry
geometry
wm_grid
grid
wm_group
group
wm_iconbitmap
iconbitmap
wm_iconify
iconify
wm_iconmask
iconmask
wm_iconname
iconname
wm_iconphoto
iconphoto
wm_iconposition
iconposition
wm_iconwindow
iconwindow
wm_manage
manage
wm_maxsize
maxsize
wm_minsize
minsize
wm_overrideredirect
overrideredirect
wm_positionfrom
positionfrom
wm_protocol
protocol
wm_resizable
resizable
wm_sizefrom
sizefrom
wm_state
state
wm_title
title
wm_transient
transient
wm_withdraw
withdraw
class SettingsDialog(sysmon_pytk.modals.ModalDialog):
 39class SettingsDialog(ModalDialog):
 40    """
 41    Manage application settings in a modal dialog.
 42
 43    Attributes
 44    ----------
 45    settings : Settings
 46        The application settings to manage.
 47    always_on_top : IntVar
 48        A flag to indicate whether the application should always float on top
 49        of other windows.
 50    add_menu_icon : IntVar
 51        A flag to indicate whether the application should add a menu icon.
 52    fonts : dict[str, str]
 53        A dictionary containing the currently-selected fonts, regular and monospace.
 54    langbox : DropDown
 55        A dropdown widget to manage the user's choice of language.
 56    themebox : DropDown
 57        A dropdown widget to manage the user's choice of theme.
 58    font_button : Button
 59        A button to open a `FontChooser` to manage the regular application font.
 60    fixed_font_button : Button
 61        A button to open a `FontChooser` to manage the monospace application font.
 62    """
 63
 64    def __init__(
 65        self, settings: Settings, parent: Misc | None = None,
 66        title: str | None = None, iconpath: str | None = None
 67    ) -> None:
 68        """
 69        Construct a Settings dialog.
 70
 71        Parameters
 72        ----------
 73        settings : Settings
 74            The application settings to manage.
 75        parent : Misc, optional
 76            The parent widget.
 77        title : str, optional
 78            The title to display in the window title bar.
 79        iconpath : str, optional
 80            The path to the icon to display in the window title bar.
 81        """
 82        self.settings = settings
 83        self.always_on_top = tk.IntVar()
 84        self.always_on_top.set(self.settings.always_on_top)
 85        self.add_menu_icon = tk.IntVar()
 86        self.add_menu_icon.set(self.settings.add_menu_icon)
 87        self.fonts = {
 88            "regular": self.settings.regular_font.get_full_font().get_string(),
 89            "fixed": self.settings.fixed_font.get_full_font().get_string()
 90        }
 91        super().__init__(parent, title=title, iconpath=iconpath)
 92
 93    def update_screen(self) -> None:
 94        """
 95        Update the modal dialog window.
 96
 97        This dialog does not require screen updates.
 98        """
 99
100    def create_widgets(self) -> None:
101        """
102        Create the widgets to be displayed in the modal dialog.
103        """
104        for row in range(1, 7):
105            self.internal_frame.rowconfigure(row, weight=1)
106        self.internal_frame.columnconfigure(2, weight=1)
107        ttk.Label(
108            self.internal_frame, text=_("Language"), font=self.base_font
109        ).grid(row=1, column=1, sticky=tk.E, padx=_common.INTERNAL_PAD)
110        self.langbox = DropDown(
111            self.internal_frame, dictionary=LANGUAGES, state=["readonly"],
112            exportselection=0, font=self.base_font
113        )
114        self.langbox.set(self.settings.language)
115        self.langbox.grid(
116            row=1, column=2, sticky=tk.EW, pady=_common.INTERNAL_PAD,
117            padx=(0, _common.INTERNAL_PAD)
118        )
119        self.langbox.bind(
120            "<<ComboboxSelected>>", lambda event: event.widget.selection_clear()
121        )
122        ttk.Label(
123            self.internal_frame, text=_("Theme"), font=self.base_font
124        ).grid(row=2, column=1, sticky=tk.E, padx=_common.INTERNAL_PAD)
125        # Language translation is used as keys, and English is used as values
126        # so that English is stored in the settings file, while allowing the
127        # user to choose their theme based on their selected language.
128        self.themebox = DropDown(
129            self.internal_frame, dictionary=THEMES, state=["readonly"],
130            exportselection=0, font=self.base_font
131        )
132        self.themebox.set(self.settings.theme)
133        self.themebox.grid(
134            row=2, column=2, sticky=tk.EW, pady=_common.INTERNAL_PAD,
135            padx=(0, _common.INTERNAL_PAD)
136        )
137        self.themebox.bind(
138            "<<ComboboxSelected>>", lambda event: event.widget.selection_clear()
139        )
140        ttk.Checkbutton(
141            self.internal_frame, text=_("Always on top"), variable=self.always_on_top,
142            style="Switch.TCheckbutton"
143        ).grid(
144            row=3, column=2, sticky=tk.EW, padx=_common.INTERNAL_PAD,
145            pady=_common.INTERNAL_PAD
146        )
147        ttk.Label(
148            self.internal_frame, text=_("Regular Font"), font=self.base_font
149        ).grid(row=4, column=1, sticky=tk.E, padx=_common.INTERNAL_PAD)
150        self.font_button = ttk.Button(
151            self.internal_frame, text=self.fonts["regular"], command=self.show_font_chooser
152        )
153        self.font_button.grid(
154            row=4, column=2, sticky=tk.EW, padx=_common.INTERNAL_PAD,
155            pady=_common.INTERNAL_PAD
156        )
157        ttk.Label(
158            self.internal_frame, text=_("Monospace Font"), font=self.base_font
159        ).grid(row=5, column=1, sticky=tk.E, padx=_common.INTERNAL_PAD)
160        self.fixed_font_button = ttk.Button(
161            self.internal_frame, text=self.fonts["fixed"], command=self.show_fixedfont_chooser
162        )
163        self.fixed_font_button.grid(
164            row=5, column=2, sticky=tk.EW, padx=_common.INTERNAL_PAD,
165            pady=_common.INTERNAL_PAD
166        )
167        ttk.Checkbutton(
168            self.internal_frame, text=_("Add to desktop menu system"),
169            variable=self.add_menu_icon, style="Switch.TCheckbutton",
170        ).grid(
171            row=6, column=1, columnspan=2, sticky=tk.NS+tk.E, padx=_common.INTERNAL_PAD,
172            pady=_common.INTERNAL_PAD
173        )
174        self.add_ok_cancel_buttons()
175        self.add_sizegrip()
176
177    def show_font_chooser(self, *_args) -> None:
178        """
179        Show a font chooser dialog.
180        """
181        chooser = FontChooser(
182            self.parent, current_font=self.settings.regular_font.get_full_font(),
183            iconpath=self.iconpath
184        )
185        chosen_font = chooser.get_font()
186        if chosen_font:
187            self.settings.regular_font.set_full_font(chosen_font)
188            self.font_button.config(
189                text=self.settings.regular_font.get_full_font().get_string()
190            )
191        else:
192            self.font_button.config(
193                text=_("Select a font")
194            )
195
196    def show_fixedfont_chooser(self, *_args) -> None:
197        """
198        Show a font chooser dialog.
199        """
200        chooser = FontChooser(
201            self.parent, current_font=self.settings.fixed_font.get_full_font(),
202            iconpath=self.iconpath
203        )
204        chosen_font = chooser.get_font()
205        if chosen_font:
206            self.settings.fixed_font.set_full_font(chosen_font)
207            self.fixed_font_button.config(
208                text=self.settings.fixed_font.get_full_font().get_string()
209            )
210        else:
211            self.font_button.config(
212                text=_("Select a font")
213            )
214
215    def on_save(self, *_args) -> None:
216        """
217        Save the entered settings.
218        """
219        old_language = self.settings.language
220        self.update_settings()
221        self.generate_change_events(old_language)
222
223    def update_settings(self) -> None:
224        """
225        Update the app settings.
226        """
227        self.settings.language = self.langbox.get()
228        self.settings.theme = self.themebox.get()
229        self.settings.always_on_top = self.always_on_top.get()
230        if self.add_menu_icon.get():
231            result = desktop_menu.install_desktop_file(self)
232            self.settings.add_menu_icon = 1 if result else 0
233        else:
234            desktop_menu.uninstall_desktop_file()
235            self.settings.add_menu_icon = 0
236        self.settings.write_settings()
237
238    def generate_change_events(self, old_language: str) -> None:
239        """
240        Generate change events based on the new settings.
241        """
242        if old_language != self.langbox.get():
243            self.save_dismiss_event("<<LanguageChanged>>")
244        new_regular_font = self.settings.regular_font.get_full_font().get_string()
245        new_fixed_font = self.settings.fixed_font.get_full_font().get_string()
246        if self.fonts["regular"] != new_regular_font:
247            self.save_dismiss_event("<<FontChanged>>")
248        if self.fonts["fixed"] != new_fixed_font:
249            self.save_dismiss_event("<<FontChanged>>")
250        self.save_dismiss_event("<<SettingsChanged>>")

Manage application settings in a modal dialog.

Attributes
  • settings (Settings): The application settings to manage.
  • always_on_top (IntVar): A flag to indicate whether the application should always float on top of other windows.
  • add_menu_icon (IntVar): A flag to indicate whether the application should add a menu icon.
  • fonts (dict[str, str]): A dictionary containing the currently-selected fonts, regular and monospace.
  • langbox (DropDown): A dropdown widget to manage the user's choice of language.
  • themebox (DropDown): A dropdown widget to manage the user's choice of theme.
  • font_button (Button): A button to open a FontChooser to manage the regular application font.
  • fixed_font_button (Button): A button to open a FontChooser to manage the monospace application font.
SettingsDialog( settings: sysmon_pytk.settings.Settings, parent: tkinter.Misc | None = None, title: str | None = None, iconpath: str | None = None)
64    def __init__(
65        self, settings: Settings, parent: Misc | None = None,
66        title: str | None = None, iconpath: str | None = None
67    ) -> None:
68        """
69        Construct a Settings dialog.
70
71        Parameters
72        ----------
73        settings : Settings
74            The application settings to manage.
75        parent : Misc, optional
76            The parent widget.
77        title : str, optional
78            The title to display in the window title bar.
79        iconpath : str, optional
80            The path to the icon to display in the window title bar.
81        """
82        self.settings = settings
83        self.always_on_top = tk.IntVar()
84        self.always_on_top.set(self.settings.always_on_top)
85        self.add_menu_icon = tk.IntVar()
86        self.add_menu_icon.set(self.settings.add_menu_icon)
87        self.fonts = {
88            "regular": self.settings.regular_font.get_full_font().get_string(),
89            "fixed": self.settings.fixed_font.get_full_font().get_string()
90        }
91        super().__init__(parent, title=title, iconpath=iconpath)

Construct a Settings dialog.

Parameters
  • settings (Settings): The application settings to manage.
  • parent (Misc, optional): The parent widget.
  • title (str, optional): The title to display in the window title bar.
  • iconpath (str, optional): The path to the icon to display in the window title bar.
def update_screen(self) -> None:
93    def update_screen(self) -> None:
94        """
95        Update the modal dialog window.
96
97        This dialog does not require screen updates.
98        """

Update the modal dialog window.

This dialog does not require screen updates.

def create_widgets(self) -> None:
100    def create_widgets(self) -> None:
101        """
102        Create the widgets to be displayed in the modal dialog.
103        """
104        for row in range(1, 7):
105            self.internal_frame.rowconfigure(row, weight=1)
106        self.internal_frame.columnconfigure(2, weight=1)
107        ttk.Label(
108            self.internal_frame, text=_("Language"), font=self.base_font
109        ).grid(row=1, column=1, sticky=tk.E, padx=_common.INTERNAL_PAD)
110        self.langbox = DropDown(
111            self.internal_frame, dictionary=LANGUAGES, state=["readonly"],
112            exportselection=0, font=self.base_font
113        )
114        self.langbox.set(self.settings.language)
115        self.langbox.grid(
116            row=1, column=2, sticky=tk.EW, pady=_common.INTERNAL_PAD,
117            padx=(0, _common.INTERNAL_PAD)
118        )
119        self.langbox.bind(
120            "<<ComboboxSelected>>", lambda event: event.widget.selection_clear()
121        )
122        ttk.Label(
123            self.internal_frame, text=_("Theme"), font=self.base_font
124        ).grid(row=2, column=1, sticky=tk.E, padx=_common.INTERNAL_PAD)
125        # Language translation is used as keys, and English is used as values
126        # so that English is stored in the settings file, while allowing the
127        # user to choose their theme based on their selected language.
128        self.themebox = DropDown(
129            self.internal_frame, dictionary=THEMES, state=["readonly"],
130            exportselection=0, font=self.base_font
131        )
132        self.themebox.set(self.settings.theme)
133        self.themebox.grid(
134            row=2, column=2, sticky=tk.EW, pady=_common.INTERNAL_PAD,
135            padx=(0, _common.INTERNAL_PAD)
136        )
137        self.themebox.bind(
138            "<<ComboboxSelected>>", lambda event: event.widget.selection_clear()
139        )
140        ttk.Checkbutton(
141            self.internal_frame, text=_("Always on top"), variable=self.always_on_top,
142            style="Switch.TCheckbutton"
143        ).grid(
144            row=3, column=2, sticky=tk.EW, padx=_common.INTERNAL_PAD,
145            pady=_common.INTERNAL_PAD
146        )
147        ttk.Label(
148            self.internal_frame, text=_("Regular Font"), font=self.base_font
149        ).grid(row=4, column=1, sticky=tk.E, padx=_common.INTERNAL_PAD)
150        self.font_button = ttk.Button(
151            self.internal_frame, text=self.fonts["regular"], command=self.show_font_chooser
152        )
153        self.font_button.grid(
154            row=4, column=2, sticky=tk.EW, padx=_common.INTERNAL_PAD,
155            pady=_common.INTERNAL_PAD
156        )
157        ttk.Label(
158            self.internal_frame, text=_("Monospace Font"), font=self.base_font
159        ).grid(row=5, column=1, sticky=tk.E, padx=_common.INTERNAL_PAD)
160        self.fixed_font_button = ttk.Button(
161            self.internal_frame, text=self.fonts["fixed"], command=self.show_fixedfont_chooser
162        )
163        self.fixed_font_button.grid(
164            row=5, column=2, sticky=tk.EW, padx=_common.INTERNAL_PAD,
165            pady=_common.INTERNAL_PAD
166        )
167        ttk.Checkbutton(
168            self.internal_frame, text=_("Add to desktop menu system"),
169            variable=self.add_menu_icon, style="Switch.TCheckbutton",
170        ).grid(
171            row=6, column=1, columnspan=2, sticky=tk.NS+tk.E, padx=_common.INTERNAL_PAD,
172            pady=_common.INTERNAL_PAD
173        )
174        self.add_ok_cancel_buttons()
175        self.add_sizegrip()

Create the widgets to be displayed in the modal dialog.

def show_font_chooser(self, *_args) -> None:
177    def show_font_chooser(self, *_args) -> None:
178        """
179        Show a font chooser dialog.
180        """
181        chooser = FontChooser(
182            self.parent, current_font=self.settings.regular_font.get_full_font(),
183            iconpath=self.iconpath
184        )
185        chosen_font = chooser.get_font()
186        if chosen_font:
187            self.settings.regular_font.set_full_font(chosen_font)
188            self.font_button.config(
189                text=self.settings.regular_font.get_full_font().get_string()
190            )
191        else:
192            self.font_button.config(
193                text=_("Select a font")
194            )

Show a font chooser dialog.

def show_fixedfont_chooser(self, *_args) -> None:
196    def show_fixedfont_chooser(self, *_args) -> None:
197        """
198        Show a font chooser dialog.
199        """
200        chooser = FontChooser(
201            self.parent, current_font=self.settings.fixed_font.get_full_font(),
202            iconpath=self.iconpath
203        )
204        chosen_font = chooser.get_font()
205        if chosen_font:
206            self.settings.fixed_font.set_full_font(chosen_font)
207            self.fixed_font_button.config(
208                text=self.settings.fixed_font.get_full_font().get_string()
209            )
210        else:
211            self.font_button.config(
212                text=_("Select a font")
213            )

Show a font chooser dialog.

def on_save(self, *_args) -> None:
215    def on_save(self, *_args) -> None:
216        """
217        Save the entered settings.
218        """
219        old_language = self.settings.language
220        self.update_settings()
221        self.generate_change_events(old_language)

Save the entered settings.

def update_settings(self) -> None:
223    def update_settings(self) -> None:
224        """
225        Update the app settings.
226        """
227        self.settings.language = self.langbox.get()
228        self.settings.theme = self.themebox.get()
229        self.settings.always_on_top = self.always_on_top.get()
230        if self.add_menu_icon.get():
231            result = desktop_menu.install_desktop_file(self)
232            self.settings.add_menu_icon = 1 if result else 0
233        else:
234            desktop_menu.uninstall_desktop_file()
235            self.settings.add_menu_icon = 0
236        self.settings.write_settings()

Update the app settings.

def generate_change_events(self, old_language: str) -> None:
238    def generate_change_events(self, old_language: str) -> None:
239        """
240        Generate change events based on the new settings.
241        """
242        if old_language != self.langbox.get():
243            self.save_dismiss_event("<<LanguageChanged>>")
244        new_regular_font = self.settings.regular_font.get_full_font().get_string()
245        new_fixed_font = self.settings.fixed_font.get_full_font().get_string()
246        if self.fonts["regular"] != new_regular_font:
247            self.save_dismiss_event("<<FontChanged>>")
248        if self.fonts["fixed"] != new_fixed_font:
249            self.save_dismiss_event("<<FontChanged>>")
250        self.save_dismiss_event("<<SettingsChanged>>")

Generate change events based on the new settings.

Inherited Members
ModalDialog
load_fonts
bind_events
make_modal
dismiss
save_and_dismiss
save_dismiss_event
add_close_button
add_ok_cancel_buttons
add_sizegrip
sysmon_pytk.widgets.buttons.ButtonMixin
add_buttons
init_standard_buttons
tkinter.BaseWidget
destroy
tkinter.Misc
deletecommand
tk_strictMotif
tk_bisque
tk_setPalette
wait_variable
waitvar
wait_window
wait_visibility
setvar
getvar
getboolean
focus_set
focus
focus_force
focus_get
focus_displayof
focus_lastfor
tk_focusFollowsMouse
tk_focusNext
tk_focusPrev
after
after_idle
after_cancel
bell
clipboard_get
clipboard_clear
clipboard_append
grab_current
grab_release
grab_set
grab_set_global
grab_status
option_add
option_clear
option_get
option_readfile
selection_clear
selection_get
selection_handle
selection_own
selection_own_get
send
lower
tkraise
lift
winfo_atom
winfo_atomname
winfo_cells
winfo_children
winfo_class
winfo_colormapfull
winfo_containing
winfo_depth
winfo_exists
winfo_fpixels
winfo_geometry
winfo_height
winfo_id
winfo_interps
winfo_ismapped
winfo_manager
winfo_name
winfo_parent
winfo_pathname
winfo_pixels
winfo_pointerx
winfo_pointerxy
winfo_pointery
winfo_reqheight
winfo_reqwidth
winfo_rgb
winfo_rootx
winfo_rooty
winfo_screen
winfo_screencells
winfo_screendepth
winfo_screenheight
winfo_screenmmheight
winfo_screenmmwidth
winfo_screenvisual
winfo_screenwidth
winfo_server
winfo_toplevel
winfo_viewable
winfo_visual
winfo_visualid
winfo_visualsavailable
winfo_vrootheight
winfo_vrootwidth
winfo_vrootx
winfo_vrooty
winfo_width
winfo_x
winfo_y
update
update_idletasks
bindtags
bind
unbind
bind_all
unbind_all
bind_class
unbind_class
mainloop
quit
nametowidget
register
configure
config
cget
keys
pack_propagate
propagate
pack_slaves
slaves
place_slaves
grid_anchor
anchor
grid_bbox
bbox
grid_columnconfigure
columnconfigure
grid_location
grid_propagate
grid_rowconfigure
rowconfigure
grid_size
size
grid_slaves
event_add
event_delete
event_generate
event_info
image_names
image_types
tkinter.Wm
wm_aspect
aspect
wm_attributes
attributes
wm_client
client
wm_colormapwindows
colormapwindows
wm_command
command
wm_deiconify
deiconify
wm_focusmodel
focusmodel
wm_forget
forget
wm_frame
frame
wm_geometry
geometry
wm_grid
grid
wm_group
group
wm_iconbitmap
iconbitmap
wm_iconify
iconify
wm_iconmask
iconmask
wm_iconname
iconname
wm_iconphoto
iconphoto
wm_iconposition
iconposition
wm_iconwindow
iconwindow
wm_manage
manage
wm_maxsize
maxsize
wm_minsize
minsize
wm_overrideredirect
overrideredirect
wm_positionfrom
positionfrom
wm_protocol
protocol
wm_resizable
resizable
wm_sizefrom
sizefrom
wm_state
state
wm_title
title
wm_transient
transient
wm_withdraw
withdraw
class TempDetailsDialog(sysmon_pytk.modals.ModalDialog):
 27class TempDetailsDialog(ModalDialog):
 28    """
 29    Display detailed temperature readings in a modal dialog.
 30    """
 31
 32    def on_save(self) -> None:
 33        """
 34        Save what was entered in the modal dialog.
 35
 36        This dialog does not need a save feature.
 37        """
 38
 39    def create_widgets(self) -> None:
 40        """
 41        Create the widgets to be displayed in the modal dialog.
 42        """
 43        self.internal_frame.columnconfigure(0, weight=1)
 44        self._readings: list[list[tk.StringVar]] = []
 45        ttk.Label(
 46            self.internal_frame, text=_("Temperature Sensors"), font=self.large_font,
 47            anchor=tk.CENTER
 48        ).grid(columnspan=2, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0))
 49        temps = psutil.sensors_temperatures()
 50        stretchy_rows = self._create_detail_widgets(temps, 1)
 51        for i in stretchy_rows:
 52            self.internal_frame.rowconfigure(i, weight=1)
 53        self.add_close_button()
 54        self.add_sizegrip()
 55
 56    def _create_detail_widgets(
 57        self, temps: dict[str, list[shwtemp]], start_row: int
 58    ) -> list[int]:
 59        row = start_row
 60        stretchy_rows: list[int] = []
 61        for name, entries in temps.items():
 62            ttk.Label(
 63                self.internal_frame, text=name.upper(), anchor=tk.SW, font=self.bold_font
 64            ).grid(
 65                column=0, row=row, sticky=tk.NSEW, padx=_common.INTERNAL_PAD,
 66                columnspan=2
 67            )
 68            stretchy_rows.append(row)
 69            row += 1
 70            entryreadings: list[tk.StringVar] = []
 71            for count, entry in enumerate(entries):
 72                entryreadings.append(tk.StringVar())
 73                entryreadings[count].set(self._format_entry(entry))
 74                ttk.Label(
 75                    self.internal_frame, text=entry.label or name, anchor=tk.W,
 76                    font=self.base_font
 77                ).grid(column=0, row=row, padx=_common.INTERNAL_PAD*2, sticky=tk.NSEW)
 78                ttk.Label(
 79                    self.internal_frame, textvariable=entryreadings[count], anchor=tk.W,
 80                    font=self.base_font
 81                ).grid(column=1, row=row, padx=_common.INTERNAL_PAD, sticky=tk.NSEW)
 82                stretchy_rows.append(row)
 83                row += 1
 84            self._readings.append(entryreadings)
 85            ttk.Separator(self.internal_frame, orient=tk.HORIZONTAL).grid(
 86                column=0, columnspan=2, row=row, sticky=tk.NSEW,
 87                padx=_common.INTERNAL_PAD, pady=_common.INTERNAL_PAD
 88            )
 89            row += 1
 90        return stretchy_rows
 91
 92    def update_screen(self) -> None:
 93        """
 94        Update the modal dialog window.
 95        """
 96        temps = psutil.sensors_temperatures()
 97        for row, entries in enumerate(temps.values()):
 98            for count, entry in enumerate(entries):
 99                self._readings[row][count].set(self._format_entry(entry))
100        self.after(_common.REFRESH_INTERVAL, self.update_screen)
101
102    @classmethod
103    def _format_entry(cls, entry: shwtemp) -> str:
104        return _("{current}°C (high = {high}°C, critical = {critical}°C)").format(
105            current=entry.current, high=entry.high, critical=entry.critical
106        )

Display detailed temperature readings in a modal dialog.

def on_save(self) -> None:
32    def on_save(self) -> None:
33        """
34        Save what was entered in the modal dialog.
35
36        This dialog does not need a save feature.
37        """

Save what was entered in the modal dialog.

This dialog does not need a save feature.

def create_widgets(self) -> None:
39    def create_widgets(self) -> None:
40        """
41        Create the widgets to be displayed in the modal dialog.
42        """
43        self.internal_frame.columnconfigure(0, weight=1)
44        self._readings: list[list[tk.StringVar]] = []
45        ttk.Label(
46            self.internal_frame, text=_("Temperature Sensors"), font=self.large_font,
47            anchor=tk.CENTER
48        ).grid(columnspan=2, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0))
49        temps = psutil.sensors_temperatures()
50        stretchy_rows = self._create_detail_widgets(temps, 1)
51        for i in stretchy_rows:
52            self.internal_frame.rowconfigure(i, weight=1)
53        self.add_close_button()
54        self.add_sizegrip()

Create the widgets to be displayed in the modal dialog.

def update_screen(self) -> None:
 92    def update_screen(self) -> None:
 93        """
 94        Update the modal dialog window.
 95        """
 96        temps = psutil.sensors_temperatures()
 97        for row, entries in enumerate(temps.values()):
 98            for count, entry in enumerate(entries):
 99                self._readings[row][count].set(self._format_entry(entry))
100        self.after(_common.REFRESH_INTERVAL, self.update_screen)

Update the modal dialog window.

Inherited Members
ModalDialog
ModalDialog
load_fonts
bind_events
make_modal
dismiss
save_and_dismiss
save_dismiss_event
add_close_button
add_ok_cancel_buttons
add_sizegrip
sysmon_pytk.widgets.buttons.ButtonMixin
add_buttons
init_standard_buttons
tkinter.BaseWidget
destroy
tkinter.Misc
deletecommand
tk_strictMotif
tk_bisque
tk_setPalette
wait_variable
waitvar
wait_window
wait_visibility
setvar
getvar
getboolean
focus_set
focus
focus_force
focus_get
focus_displayof
focus_lastfor
tk_focusFollowsMouse
tk_focusNext
tk_focusPrev
after
after_idle
after_cancel
bell
clipboard_get
clipboard_clear
clipboard_append
grab_current
grab_release
grab_set
grab_set_global
grab_status
option_add
option_clear
option_get
option_readfile
selection_clear
selection_get
selection_handle
selection_own
selection_own_get
send
lower
tkraise
lift
winfo_atom
winfo_atomname
winfo_cells
winfo_children
winfo_class
winfo_colormapfull
winfo_containing
winfo_depth
winfo_exists
winfo_fpixels
winfo_geometry
winfo_height
winfo_id
winfo_interps
winfo_ismapped
winfo_manager
winfo_name
winfo_parent
winfo_pathname
winfo_pixels
winfo_pointerx
winfo_pointerxy
winfo_pointery
winfo_reqheight
winfo_reqwidth
winfo_rgb
winfo_rootx
winfo_rooty
winfo_screen
winfo_screencells
winfo_screendepth
winfo_screenheight
winfo_screenmmheight
winfo_screenmmwidth
winfo_screenvisual
winfo_screenwidth
winfo_server
winfo_toplevel
winfo_viewable
winfo_visual
winfo_visualid
winfo_visualsavailable
winfo_vrootheight
winfo_vrootwidth
winfo_vrootx
winfo_vrooty
winfo_width
winfo_x
winfo_y
update
update_idletasks
bindtags
bind
unbind
bind_all
unbind_all
bind_class
unbind_class
mainloop
quit
nametowidget
register
configure
config
cget
keys
pack_propagate
propagate
pack_slaves
slaves
place_slaves
grid_anchor
anchor
grid_bbox
bbox
grid_columnconfigure
columnconfigure
grid_location
grid_propagate
grid_rowconfigure
rowconfigure
grid_size
size
grid_slaves
event_add
event_delete
event_generate
event_info
image_names
image_types
tkinter.Wm
wm_aspect
aspect
wm_attributes
attributes
wm_client
client
wm_colormapwindows
colormapwindows
wm_command
command
wm_deiconify
deiconify
wm_focusmodel
focusmodel
wm_forget
forget
wm_frame
frame
wm_geometry
geometry
wm_grid
grid
wm_group
group
wm_iconbitmap
iconbitmap
wm_iconify
iconify
wm_iconmask
iconmask
wm_iconname
iconname
wm_iconphoto
iconphoto
wm_iconposition
iconposition
wm_iconwindow
iconwindow
wm_manage
manage
wm_maxsize
maxsize
wm_minsize
minsize
wm_overrideredirect
overrideredirect
wm_positionfrom
positionfrom
wm_protocol
protocol
wm_resizable
resizable
wm_sizefrom
sizefrom
wm_state
state
wm_title
title
wm_transient
transient
wm_withdraw
withdraw