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]
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
Frameto 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
197 @abstractmethod 198 def update_screen(self) -> None: 199 """ 200 Update the modal dialog window. 201 """
Update the modal dialog window.
Inherited Members
- 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
- 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
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.
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.
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.
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.
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.
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.
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.
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_sizegrip
- 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
- 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
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.
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 ""
Build the copyright text based on year and author.
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.
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.
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.
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.
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.
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_sizegrip
- 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
- 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
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.
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.
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.
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.
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.
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.
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_sizegrip
- 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
- 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
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.
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.
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.
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.
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.
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_sizegrip
- 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
- 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
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.
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.
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.
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_sizegrip
- 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
- 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
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
FontChooserto manage the regular application font. - fixed_font_button (Button):
A button to open a
FontChooserto manage the monospace application font.
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.
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.
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.
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.
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.
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.
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.
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_sizegrip
- 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
- 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
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.
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.
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.
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_sizegrip
- 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
- 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