sysmon_pytk.application
System monitor application.
1# SPDX-FileCopyrightText: © 2024 Stacey Adams <stacey.belle.rose@gmail.com> 2# SPDX-License-Identifier: MIT 3 4""" 5System monitor application. 6""" 7 8from __future__ import annotations 9 10import sys 11import tkinter as tk 12from socket import gethostname 13from tkinter import font, ttk 14from typing import TYPE_CHECKING 15 16import psutil 17 18from . import _common, about 19from .app_locale import get_translator, reload_translated_modules 20from .file_utils import get_full_path, settings_path 21from .modals import AboutDialog, AboutMetadata, LicenseMetadata, SettingsDialog 22from .settings import Settings 23from .style_manager import StyleManager 24from .widgets import TempToolTip, ToolTip 25from .widgets.meters import CpuMeter, DiskMeter, RamMeter, TempMeter 26 27if TYPE_CHECKING: 28 from tkinter import Event, Variable 29 30_ = get_translator() 31 32APP_TITLE = _("System Monitor") 33"""Application title, which appears in window title bars.""" 34 35 36class Application(tk.Tk): 37 """ 38 System monitor application. 39 40 Toplevel widget of Tk which represents the main window of the application. 41 42 Attributes 43 ---------- 44 _name : StringVar 45 The hostname of the system. 46 _ip_addr : StringVar 47 The IP Address of the system. 48 _uptime : StringVar 49 The current uptime of the system. 50 _processes : StringVar 51 The current process count of the system. 52 _update_job : str 53 The ID of the scheduled job to update the screen. 54 _menu_icons : dict[str, PhotoImage] 55 The icons used in the menu. 56 """ 57 58 def __init__(self) -> None: 59 """Return a new Toplevel Tk widget.""" 60 super().__init__() 61 self.title(APP_TITLE) 62 self.iconphoto(False, tk.PhotoImage(file=get_full_path("images/icon.png"))) 63 self.read_settings() 64 self._name = tk.StringVar() 65 self._ip_addr = tk.StringVar() 66 self._uptime = tk.StringVar() 67 self._processes = tk.StringVar() 68 self._update_job: str | None = None 69 StyleManager.init_theme(self, self.settings) 70 self.create_widgets() 71 self._load_menu_images() 72 self.build_menu() 73 self.bind_events() 74 self.update() 75 self.minsize(self.winfo_width(), self.winfo_height()) 76 self.update_screen() 77 78 def read_settings(self, *_args) -> None: 79 """ 80 Read and process application settings from configuration file. 81 82 This method is triggered on a `<<SettingsChanged>>` event, and is part 83 of the application startup program flow. 84 """ 85 self.settings = Settings(settings_path()) 86 self.call("wm", "attributes", ".", "-topmost", f"{self.settings.always_on_top}") 87 88 def create_widgets(self) -> None: 89 """ 90 Create the widgets to be displayed in the main application window. 91 """ 92 frame = ttk.Frame(self) 93 frame.grid(sticky=tk.NSEW) 94 for row in [1, 2]: 95 frame.rowconfigure(row, weight=1) 96 for column in [1, 2, 3, 4]: 97 frame.columnconfigure(column, weight=1) 98 self._add_variable_label(frame, self._name, 1, 1) 99 ip_label = self._add_variable_label(frame, self._ip_addr, 1, 2) 100 ToolTip(ip_label, _("Click to copy IP Address to clipboard")) 101 ip_label.bind("<Button-1>", self.on_click_ip_address) 102 self._add_variable_label(frame, self._processes, 1, 3) 103 self._add_variable_label(frame, self._uptime, 1, 4) 104 self._add_meters(frame) 105 self._add_sizegrip(frame) 106 107 @classmethod 108 def _add_variable_label( 109 cls, frame: ttk.Frame, textvariable: Variable, row: int, column: int 110 ) -> ttk.Label: 111 base_font = StyleManager.get_base_font() 112 label = ttk.Label( 113 frame, textvariable=textvariable, font=base_font, anchor=tk.CENTER 114 ) 115 label.grid( 116 row=row, column=column, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 117 ) 118 return label 119 120 def _add_meters(self, frame: ttk.Frame) -> None: 121 CpuMeter(frame, width=220, height=165).grid( 122 row=2, column=1, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 123 ) 124 TempMeter(frame, width=220, height=165).grid( 125 row=2, column=2, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 126 ) 127 RamMeter(frame, width=220, height=165).grid( 128 row=2, column=3, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 129 ) 130 DiskMeter(frame, width=220, height=165).grid( 131 row=2, column=4, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 132 ) 133 134 @classmethod 135 def _add_sizegrip(cls, frame: ttk.Frame) -> None: 136 ttk.Sizegrip(frame).grid( 137 row=3, column=4, sticky=tk.SE, padx=_common.INTERNAL_PAD/2, 138 pady=(0, _common.INTERNAL_PAD/2) 139 ) 140 141 def _load_menu_images(self) -> None: 142 self._menu_icons = { 143 "about": tk.PhotoImage(file=get_full_path("images/internet-group-chat.png")), 144 "preferences": tk.PhotoImage(file=get_full_path("images/preferences-system.png")), 145 "restart": tk.PhotoImage(file=get_full_path("images/view-refresh.png")), 146 "quit": tk.PhotoImage(file=get_full_path("images/blank.png")) 147 } 148 149 def build_menu(self) -> None: 150 """ 151 Build the application menu and bind associated keypress events to functions. 152 """ 153 top = self.winfo_toplevel() 154 top.rowconfigure(0, weight=1) 155 top.columnconfigure(0, weight=1) 156 menu_bar = tk.Menu( 157 top, relief=tk.FLAT, activeborderwidth=0, 158 font=font.nametofont("TkMenuFont"), 159 background=StyleManager.get_menu_background(), 160 foreground=StyleManager.get_menu_foreground() 161 ) 162 file_menu = tk.Menu( 163 menu_bar, relief=tk.FLAT, activeborderwidth=0, 164 font=font.nametofont("TkMenuFont"), 165 background=StyleManager.get_menu_background(), 166 foreground=StyleManager.get_menu_foreground() 167 ) 168 169 menu_bar.add_cascade( 170 label=_("File"), menu=file_menu, 171 ) 172 file_menu.add_command( 173 label=_("About"), accelerator=_("Ctrl+A"), command=self.on_about, 174 compound=tk.LEFT, image=self._menu_icons["about"] 175 ) 176 file_menu.add_command( 177 label=_("Preferences"), accelerator=_("Ctrl+Shift+P"), command=self.on_settings, 178 compound=tk.LEFT, image=self._menu_icons["preferences"] 179 ) 180 file_menu.add_command( 181 label=_("Restart"), accelerator=_("Ctrl+R"), command=self.on_restart, 182 compound=tk.LEFT, image=self._menu_icons["restart"] 183 ) 184 file_menu.add_separator() 185 file_menu.add_command( 186 label=_("Quit"), accelerator=_("Ctrl+Q"), command=lambda: sys.exit(0), 187 compound=tk.LEFT, image=self._menu_icons["quit"] 188 ) 189 top["menu"] = menu_bar 190 # bind keypress events for menu here 191 self.bind("<Control-KeyPress-a>", self.on_about) 192 self.bind("<Control-Shift-KeyPress-P>", self.on_settings) 193 self.bind("<Control-KeyPress-r>", self.on_restart) 194 self.bind("<Control-KeyPress-q>", lambda _x: sys.exit(0)) 195 196 def bind_events(self) -> None: 197 """ 198 Set up bindings for custom application events. 199 """ 200 self.bind("<<SettingsChanged>>", self.read_settings) 201 self.bind("<<LanguageChanged>>", self.on_language) 202 self.bind("<<FontChanged>>", self.on_restart) 203 204 def on_click_ip_address(self, event: Event) -> None: 205 """ 206 Copy the IP address to the clipboard. 207 """ 208 self.clipboard_clear() 209 self.clipboard_append(_common.net_addr()) 210 TempToolTip(self, _("Copied!"), (event.x_root, event.y_root), 5000) 211 212 def on_language(self, *_args) -> None: 213 """ 214 Update the selected translation after the user selects a new language. 215 216 This method is triggered on a `<<LanguageChanged>>` event. 217 """ 218 reload_translated_modules() 219 self.on_restart() 220 221 def on_about(self, *_args) -> None: 222 """ 223 Open the About modal dialog box. 224 """ 225 metadata = AboutMetadata( 226 about.__app_name__, about.__version__, about.__author_name__, 227 about.__copyright_year__, about.__summary__, about.__url__, 228 LicenseMetadata( 229 about.__full_license__, about.__license__, about.__license_url__ 230 ) 231 ) 232 AboutDialog(self, metadata, iconpath=get_full_path("images/icon.png")) 233 234 def on_restart(self, *_args) -> None: 235 """ 236 Restart the application. 237 238 This method is triggered on a `<<FontChanged>>` event, and is part of 239 the program flow for `<<LanguageChanged>>` event processing. 240 """ 241 if self._update_job is not None: 242 self.after_cancel(self._update_job) 243 self._update_job = None 244 self.destroy() 245 self.__init__() # type: ignore[misc] # pylint: disable=unnecessary-dunder-call 246 247 def on_settings(self, *_args) -> None: 248 """ 249 Open the Settings modal dialog and process any changes afterward. 250 """ 251 SettingsDialog( 252 self.settings, self, _("{} Preferences").format(APP_TITLE), 253 iconpath=get_full_path("images/icon.png") 254 ) 255 StyleManager.update_by_dark_mode(self, self.settings) 256 257 def update_screen(self) -> None: 258 """ 259 Periodically update the screen to refresh the displayed data. 260 261 This method reschedules itself after `sysmon_pytk._common.REFRESH_INTERVAL` 262 milliseconds. 263 """ 264 self._name.set(_("Hostname: {}").format(gethostname())) 265 self._ip_addr.set(_("IP Address: {}").format(_common.net_addr())) 266 self._processes.set(_("Processes: {}").format(len(psutil.pids()))) 267 self._uptime.set(_("Uptime: {}").format(_common.system_uptime())) 268 self._update_job = self.after( 269 _common.REFRESH_INTERVAL, self.update_screen 270 )
Application title, which appears in window title bars.
37class Application(tk.Tk): 38 """ 39 System monitor application. 40 41 Toplevel widget of Tk which represents the main window of the application. 42 43 Attributes 44 ---------- 45 _name : StringVar 46 The hostname of the system. 47 _ip_addr : StringVar 48 The IP Address of the system. 49 _uptime : StringVar 50 The current uptime of the system. 51 _processes : StringVar 52 The current process count of the system. 53 _update_job : str 54 The ID of the scheduled job to update the screen. 55 _menu_icons : dict[str, PhotoImage] 56 The icons used in the menu. 57 """ 58 59 def __init__(self) -> None: 60 """Return a new Toplevel Tk widget.""" 61 super().__init__() 62 self.title(APP_TITLE) 63 self.iconphoto(False, tk.PhotoImage(file=get_full_path("images/icon.png"))) 64 self.read_settings() 65 self._name = tk.StringVar() 66 self._ip_addr = tk.StringVar() 67 self._uptime = tk.StringVar() 68 self._processes = tk.StringVar() 69 self._update_job: str | None = None 70 StyleManager.init_theme(self, self.settings) 71 self.create_widgets() 72 self._load_menu_images() 73 self.build_menu() 74 self.bind_events() 75 self.update() 76 self.minsize(self.winfo_width(), self.winfo_height()) 77 self.update_screen() 78 79 def read_settings(self, *_args) -> None: 80 """ 81 Read and process application settings from configuration file. 82 83 This method is triggered on a `<<SettingsChanged>>` event, and is part 84 of the application startup program flow. 85 """ 86 self.settings = Settings(settings_path()) 87 self.call("wm", "attributes", ".", "-topmost", f"{self.settings.always_on_top}") 88 89 def create_widgets(self) -> None: 90 """ 91 Create the widgets to be displayed in the main application window. 92 """ 93 frame = ttk.Frame(self) 94 frame.grid(sticky=tk.NSEW) 95 for row in [1, 2]: 96 frame.rowconfigure(row, weight=1) 97 for column in [1, 2, 3, 4]: 98 frame.columnconfigure(column, weight=1) 99 self._add_variable_label(frame, self._name, 1, 1) 100 ip_label = self._add_variable_label(frame, self._ip_addr, 1, 2) 101 ToolTip(ip_label, _("Click to copy IP Address to clipboard")) 102 ip_label.bind("<Button-1>", self.on_click_ip_address) 103 self._add_variable_label(frame, self._processes, 1, 3) 104 self._add_variable_label(frame, self._uptime, 1, 4) 105 self._add_meters(frame) 106 self._add_sizegrip(frame) 107 108 @classmethod 109 def _add_variable_label( 110 cls, frame: ttk.Frame, textvariable: Variable, row: int, column: int 111 ) -> ttk.Label: 112 base_font = StyleManager.get_base_font() 113 label = ttk.Label( 114 frame, textvariable=textvariable, font=base_font, anchor=tk.CENTER 115 ) 116 label.grid( 117 row=row, column=column, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 118 ) 119 return label 120 121 def _add_meters(self, frame: ttk.Frame) -> None: 122 CpuMeter(frame, width=220, height=165).grid( 123 row=2, column=1, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 124 ) 125 TempMeter(frame, width=220, height=165).grid( 126 row=2, column=2, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 127 ) 128 RamMeter(frame, width=220, height=165).grid( 129 row=2, column=3, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 130 ) 131 DiskMeter(frame, width=220, height=165).grid( 132 row=2, column=4, sticky=tk.NSEW, pady=(_common.INTERNAL_PAD, 0) 133 ) 134 135 @classmethod 136 def _add_sizegrip(cls, frame: ttk.Frame) -> None: 137 ttk.Sizegrip(frame).grid( 138 row=3, column=4, sticky=tk.SE, padx=_common.INTERNAL_PAD/2, 139 pady=(0, _common.INTERNAL_PAD/2) 140 ) 141 142 def _load_menu_images(self) -> None: 143 self._menu_icons = { 144 "about": tk.PhotoImage(file=get_full_path("images/internet-group-chat.png")), 145 "preferences": tk.PhotoImage(file=get_full_path("images/preferences-system.png")), 146 "restart": tk.PhotoImage(file=get_full_path("images/view-refresh.png")), 147 "quit": tk.PhotoImage(file=get_full_path("images/blank.png")) 148 } 149 150 def build_menu(self) -> None: 151 """ 152 Build the application menu and bind associated keypress events to functions. 153 """ 154 top = self.winfo_toplevel() 155 top.rowconfigure(0, weight=1) 156 top.columnconfigure(0, weight=1) 157 menu_bar = tk.Menu( 158 top, relief=tk.FLAT, activeborderwidth=0, 159 font=font.nametofont("TkMenuFont"), 160 background=StyleManager.get_menu_background(), 161 foreground=StyleManager.get_menu_foreground() 162 ) 163 file_menu = tk.Menu( 164 menu_bar, relief=tk.FLAT, activeborderwidth=0, 165 font=font.nametofont("TkMenuFont"), 166 background=StyleManager.get_menu_background(), 167 foreground=StyleManager.get_menu_foreground() 168 ) 169 170 menu_bar.add_cascade( 171 label=_("File"), menu=file_menu, 172 ) 173 file_menu.add_command( 174 label=_("About"), accelerator=_("Ctrl+A"), command=self.on_about, 175 compound=tk.LEFT, image=self._menu_icons["about"] 176 ) 177 file_menu.add_command( 178 label=_("Preferences"), accelerator=_("Ctrl+Shift+P"), command=self.on_settings, 179 compound=tk.LEFT, image=self._menu_icons["preferences"] 180 ) 181 file_menu.add_command( 182 label=_("Restart"), accelerator=_("Ctrl+R"), command=self.on_restart, 183 compound=tk.LEFT, image=self._menu_icons["restart"] 184 ) 185 file_menu.add_separator() 186 file_menu.add_command( 187 label=_("Quit"), accelerator=_("Ctrl+Q"), command=lambda: sys.exit(0), 188 compound=tk.LEFT, image=self._menu_icons["quit"] 189 ) 190 top["menu"] = menu_bar 191 # bind keypress events for menu here 192 self.bind("<Control-KeyPress-a>", self.on_about) 193 self.bind("<Control-Shift-KeyPress-P>", self.on_settings) 194 self.bind("<Control-KeyPress-r>", self.on_restart) 195 self.bind("<Control-KeyPress-q>", lambda _x: sys.exit(0)) 196 197 def bind_events(self) -> None: 198 """ 199 Set up bindings for custom application events. 200 """ 201 self.bind("<<SettingsChanged>>", self.read_settings) 202 self.bind("<<LanguageChanged>>", self.on_language) 203 self.bind("<<FontChanged>>", self.on_restart) 204 205 def on_click_ip_address(self, event: Event) -> None: 206 """ 207 Copy the IP address to the clipboard. 208 """ 209 self.clipboard_clear() 210 self.clipboard_append(_common.net_addr()) 211 TempToolTip(self, _("Copied!"), (event.x_root, event.y_root), 5000) 212 213 def on_language(self, *_args) -> None: 214 """ 215 Update the selected translation after the user selects a new language. 216 217 This method is triggered on a `<<LanguageChanged>>` event. 218 """ 219 reload_translated_modules() 220 self.on_restart() 221 222 def on_about(self, *_args) -> None: 223 """ 224 Open the About modal dialog box. 225 """ 226 metadata = AboutMetadata( 227 about.__app_name__, about.__version__, about.__author_name__, 228 about.__copyright_year__, about.__summary__, about.__url__, 229 LicenseMetadata( 230 about.__full_license__, about.__license__, about.__license_url__ 231 ) 232 ) 233 AboutDialog(self, metadata, iconpath=get_full_path("images/icon.png")) 234 235 def on_restart(self, *_args) -> None: 236 """ 237 Restart the application. 238 239 This method is triggered on a `<<FontChanged>>` event, and is part of 240 the program flow for `<<LanguageChanged>>` event processing. 241 """ 242 if self._update_job is not None: 243 self.after_cancel(self._update_job) 244 self._update_job = None 245 self.destroy() 246 self.__init__() # type: ignore[misc] # pylint: disable=unnecessary-dunder-call 247 248 def on_settings(self, *_args) -> None: 249 """ 250 Open the Settings modal dialog and process any changes afterward. 251 """ 252 SettingsDialog( 253 self.settings, self, _("{} Preferences").format(APP_TITLE), 254 iconpath=get_full_path("images/icon.png") 255 ) 256 StyleManager.update_by_dark_mode(self, self.settings) 257 258 def update_screen(self) -> None: 259 """ 260 Periodically update the screen to refresh the displayed data. 261 262 This method reschedules itself after `sysmon_pytk._common.REFRESH_INTERVAL` 263 milliseconds. 264 """ 265 self._name.set(_("Hostname: {}").format(gethostname())) 266 self._ip_addr.set(_("IP Address: {}").format(_common.net_addr())) 267 self._processes.set(_("Processes: {}").format(len(psutil.pids()))) 268 self._uptime.set(_("Uptime: {}").format(_common.system_uptime())) 269 self._update_job = self.after( 270 _common.REFRESH_INTERVAL, self.update_screen 271 )
System monitor application.
Toplevel widget of Tk which represents the main window of the application.
Attributes
- _name (StringVar): The hostname of the system.
- _ip_addr (StringVar): The IP Address of the system.
- _uptime (StringVar): The current uptime of the system.
- _processes (StringVar): The current process count of the system.
- _update_job (str): The ID of the scheduled job to update the screen.
- _menu_icons (dict[str, PhotoImage]): The icons used in the menu.
59 def __init__(self) -> None: 60 """Return a new Toplevel Tk widget.""" 61 super().__init__() 62 self.title(APP_TITLE) 63 self.iconphoto(False, tk.PhotoImage(file=get_full_path("images/icon.png"))) 64 self.read_settings() 65 self._name = tk.StringVar() 66 self._ip_addr = tk.StringVar() 67 self._uptime = tk.StringVar() 68 self._processes = tk.StringVar() 69 self._update_job: str | None = None 70 StyleManager.init_theme(self, self.settings) 71 self.create_widgets() 72 self._load_menu_images() 73 self.build_menu() 74 self.bind_events() 75 self.update() 76 self.minsize(self.winfo_width(), self.winfo_height()) 77 self.update_screen()
Return a new Toplevel Tk widget.
79 def read_settings(self, *_args) -> None: 80 """ 81 Read and process application settings from configuration file. 82 83 This method is triggered on a `<<SettingsChanged>>` event, and is part 84 of the application startup program flow. 85 """ 86 self.settings = Settings(settings_path()) 87 self.call("wm", "attributes", ".", "-topmost", f"{self.settings.always_on_top}")
Read and process application settings from configuration file.
This method is triggered on a <<SettingsChanged>> event, and is part
of the application startup program flow.
89 def create_widgets(self) -> None: 90 """ 91 Create the widgets to be displayed in the main application window. 92 """ 93 frame = ttk.Frame(self) 94 frame.grid(sticky=tk.NSEW) 95 for row in [1, 2]: 96 frame.rowconfigure(row, weight=1) 97 for column in [1, 2, 3, 4]: 98 frame.columnconfigure(column, weight=1) 99 self._add_variable_label(frame, self._name, 1, 1) 100 ip_label = self._add_variable_label(frame, self._ip_addr, 1, 2) 101 ToolTip(ip_label, _("Click to copy IP Address to clipboard")) 102 ip_label.bind("<Button-1>", self.on_click_ip_address) 103 self._add_variable_label(frame, self._processes, 1, 3) 104 self._add_variable_label(frame, self._uptime, 1, 4) 105 self._add_meters(frame) 106 self._add_sizegrip(frame)
Create the widgets to be displayed in the main application window.
197 def bind_events(self) -> None: 198 """ 199 Set up bindings for custom application events. 200 """ 201 self.bind("<<SettingsChanged>>", self.read_settings) 202 self.bind("<<LanguageChanged>>", self.on_language) 203 self.bind("<<FontChanged>>", self.on_restart)
Set up bindings for custom application events.
205 def on_click_ip_address(self, event: Event) -> None: 206 """ 207 Copy the IP address to the clipboard. 208 """ 209 self.clipboard_clear() 210 self.clipboard_append(_common.net_addr()) 211 TempToolTip(self, _("Copied!"), (event.x_root, event.y_root), 5000)
Copy the IP address to the clipboard.
213 def on_language(self, *_args) -> None: 214 """ 215 Update the selected translation after the user selects a new language. 216 217 This method is triggered on a `<<LanguageChanged>>` event. 218 """ 219 reload_translated_modules() 220 self.on_restart()
Update the selected translation after the user selects a new language.
This method is triggered on a <<LanguageChanged>> event.
222 def on_about(self, *_args) -> None: 223 """ 224 Open the About modal dialog box. 225 """ 226 metadata = AboutMetadata( 227 about.__app_name__, about.__version__, about.__author_name__, 228 about.__copyright_year__, about.__summary__, about.__url__, 229 LicenseMetadata( 230 about.__full_license__, about.__license__, about.__license_url__ 231 ) 232 ) 233 AboutDialog(self, metadata, iconpath=get_full_path("images/icon.png"))
Open the About modal dialog box.
235 def on_restart(self, *_args) -> None: 236 """ 237 Restart the application. 238 239 This method is triggered on a `<<FontChanged>>` event, and is part of 240 the program flow for `<<LanguageChanged>>` event processing. 241 """ 242 if self._update_job is not None: 243 self.after_cancel(self._update_job) 244 self._update_job = None 245 self.destroy() 246 self.__init__() # type: ignore[misc] # pylint: disable=unnecessary-dunder-call
Restart the application.
This method is triggered on a <<FontChanged>> event, and is part of
the program flow for <<LanguageChanged>> event processing.
248 def on_settings(self, *_args) -> None: 249 """ 250 Open the Settings modal dialog and process any changes afterward. 251 """ 252 SettingsDialog( 253 self.settings, self, _("{} Preferences").format(APP_TITLE), 254 iconpath=get_full_path("images/icon.png") 255 ) 256 StyleManager.update_by_dark_mode(self, self.settings)
Open the Settings modal dialog and process any changes afterward.
258 def update_screen(self) -> None: 259 """ 260 Periodically update the screen to refresh the displayed data. 261 262 This method reschedules itself after `sysmon_pytk._common.REFRESH_INTERVAL` 263 milliseconds. 264 """ 265 self._name.set(_("Hostname: {}").format(gethostname())) 266 self._ip_addr.set(_("IP Address: {}").format(_common.net_addr())) 267 self._processes.set(_("Processes: {}").format(len(psutil.pids()))) 268 self._uptime.set(_("Uptime: {}").format(_common.system_uptime())) 269 self._update_job = self.after( 270 _common.REFRESH_INTERVAL, self.update_screen 271 )
Periodically update the screen to refresh the displayed data.
This method reschedules itself after sysmon_pytk._common.REFRESH_INTERVAL
milliseconds.
Inherited Members
- tkinter.Tk
- destroy
- readprofile
- report_callback_exception
- 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