sysmon_pytk.widgets.buttons
Mixin class for standard button sets in dialogs.
1# SPDX-FileCopyrightText: © 2024 Stacey Adams <stacey.belle.rose@gmail.com> 2# SPDX-License-Identifier: MIT 3 4""" 5Mixin class for standard button sets in dialogs. 6""" 7 8from __future__ import annotations 9 10import dataclasses 11import tkinter as tk 12from enum import IntEnum 13from tkinter import ttk 14from typing import Any, Callable, TypeVar, Union 15 16from ..._common import INTERNAL_PAD 17from ...app_locale import get_translator 18 19_ = get_translator() 20 21__all__ = ["ButtonName", "ButtonDefinition", "ButtonMixin"] 22 23WidgetFrame = TypeVar("WidgetFrame", bound=Union[ttk.Frame, tk.Frame]) 24 25 26class ButtonName(IntEnum): 27 """ 28 Standard button names. 29 """ 30 31 NONE = 0 32 """None.""" 33 OK = 1 34 """OK button.""" 35 CANCEL = 2 36 """Cancel button.""" 37 CLOSE = 3 38 """Close button.""" 39 YES = 4 40 """Yes button.""" 41 NO = 5 42 """No button.""" 43 RETRY = 6 44 """Retry button.""" 45 46 47@dataclasses.dataclass 48class ButtonDefinition: 49 """ 50 Necessary metadata for creating a button. 51 """ 52 53 text: str 54 """The text to appear on the button.""" 55 command: Callable[[], Any] 56 """The command to call when the button is pressed.""" 57 58 59class ButtonMixin: # pylint: disable=too-few-public-methods 60 """ 61 Mixin class for standard button sets in dialogs. 62 63 Attributes 64 ---------- 65 result : ButtonName 66 The button pressed to close the message box. 67 button_definitions : dict[ButtonName, ButtonDefinition] 68 A dictionary of standard buttons available to use. 69 """ 70 71 def __init__(self, *args, **kwargs) -> None: 72 super().__init__(*args, **kwargs) 73 self.result = ButtonName.NONE 74 self.init_standard_buttons() 75 self.toplevel: tk.Tk | tk.Toplevel | None = None 76 77 def add_buttons( 78 self, frame: WidgetFrame, *, buttons: list[ButtonDefinition], 79 default: int = -1 80 ) -> None: 81 """ 82 Add buttons to the provided frame at the bottom, justified right. 83 84 Parameters 85 ---------- 86 frame : WidgetFrame (tk.Frame or ttk.Frame) 87 The frame to which the buttons will be added 88 buttons : list[`ButtonDefinition`] 89 The list of buttons to add 90 default : int 91 The default button, displayed with style="Accent.TButton" 92 """ 93 self.toplevel = frame.winfo_toplevel() 94 max_columns, max_rows = frame.grid_size() 95 buttonframe = ttk.Frame(frame) 96 buttonframe.grid( 97 row=max_rows, column=0, sticky=tk.E, columnspan=max_columns, 98 pady=(0, INTERNAL_PAD) 99 ) 100 for num, button in enumerate(buttons): 101 btn = ttk.Button(buttonframe, text=button.text, command=button.command) 102 if num == default: 103 btn.configure(style="Accent.TButton") 104 self.toplevel.bind( 105 "<KeyPress-Return>", button.command # type: ignore[arg-type] 106 ) 107 self.toplevel.bind( 108 "<KeyPress-KP_Enter>", button.command # type: ignore[arg-type] 109 ) 110 btn.grid(row=0, column=num, padx=INTERNAL_PAD/2) 111 112 def init_standard_buttons(self) -> None: 113 """ 114 Define the button definitions. 115 """ 116 self.button_definitions = { 117 ButtonName.OK: ButtonDefinition( 118 text=_("OK"), command=lambda: self._set_result(ButtonName.OK) 119 ), 120 ButtonName.CANCEL: ButtonDefinition( 121 text=_("Cancel"), command=lambda: self._set_result(ButtonName.CANCEL) 122 ), 123 ButtonName.CLOSE: ButtonDefinition( 124 text=_("Close"), command=lambda: self._set_result(ButtonName.CLOSE) 125 ), 126 ButtonName.YES: ButtonDefinition( 127 text=_("Yes"), command=lambda: self._set_result(ButtonName.YES) 128 ), 129 ButtonName.NO: ButtonDefinition( 130 text=_("No"), command=lambda: self._set_result(ButtonName.NO) 131 ), 132 ButtonName.RETRY: ButtonDefinition( 133 text=_("Retry"), command=lambda: self._set_result(ButtonName.RETRY) 134 ), 135 } 136 137 def _set_result(self, value: ButtonName) -> None: 138 """ 139 Set the result to the ButtonName pressed. 140 141 Parameters 142 ---------- 143 value : ButtonName 144 The ButtonName of the button pressed. 145 """ 146 self.result = value 147 self.dismiss() 148 149 def dismiss(self, *_args) -> None: 150 """ 151 Dismiss the window. 152 """ 153 if self.toplevel is not None: 154 self.toplevel.grab_release() 155 self.toplevel.destroy()
enum ButtonName(enum.IntEnum):
27class ButtonName(IntEnum): 28 """ 29 Standard button names. 30 """ 31 32 NONE = 0 33 """None.""" 34 OK = 1 35 """OK button.""" 36 CANCEL = 2 37 """Cancel button.""" 38 CLOSE = 3 39 """Close button.""" 40 YES = 4 41 """Yes button.""" 42 NO = 5 43 """No button.""" 44 RETRY = 6 45 """Retry button."""
Standard button names.
Inherited Members
- enum.Enum
- name
- value
- builtins.int
- conjugate
- bit_length
- bit_count
- to_bytes
- from_bytes
- as_integer_ratio
- real
- imag
- numerator
- denominator
@dataclasses.dataclass
class ButtonDefinition:
48@dataclasses.dataclass 49class ButtonDefinition: 50 """ 51 Necessary metadata for creating a button. 52 """ 53 54 text: str 55 """The text to appear on the button.""" 56 command: Callable[[], Any] 57 """The command to call when the button is pressed."""
Necessary metadata for creating a button.
class ButtonMixin:
60class ButtonMixin: # pylint: disable=too-few-public-methods 61 """ 62 Mixin class for standard button sets in dialogs. 63 64 Attributes 65 ---------- 66 result : ButtonName 67 The button pressed to close the message box. 68 button_definitions : dict[ButtonName, ButtonDefinition] 69 A dictionary of standard buttons available to use. 70 """ 71 72 def __init__(self, *args, **kwargs) -> None: 73 super().__init__(*args, **kwargs) 74 self.result = ButtonName.NONE 75 self.init_standard_buttons() 76 self.toplevel: tk.Tk | tk.Toplevel | None = None 77 78 def add_buttons( 79 self, frame: WidgetFrame, *, buttons: list[ButtonDefinition], 80 default: int = -1 81 ) -> None: 82 """ 83 Add buttons to the provided frame at the bottom, justified right. 84 85 Parameters 86 ---------- 87 frame : WidgetFrame (tk.Frame or ttk.Frame) 88 The frame to which the buttons will be added 89 buttons : list[`ButtonDefinition`] 90 The list of buttons to add 91 default : int 92 The default button, displayed with style="Accent.TButton" 93 """ 94 self.toplevel = frame.winfo_toplevel() 95 max_columns, max_rows = frame.grid_size() 96 buttonframe = ttk.Frame(frame) 97 buttonframe.grid( 98 row=max_rows, column=0, sticky=tk.E, columnspan=max_columns, 99 pady=(0, INTERNAL_PAD) 100 ) 101 for num, button in enumerate(buttons): 102 btn = ttk.Button(buttonframe, text=button.text, command=button.command) 103 if num == default: 104 btn.configure(style="Accent.TButton") 105 self.toplevel.bind( 106 "<KeyPress-Return>", button.command # type: ignore[arg-type] 107 ) 108 self.toplevel.bind( 109 "<KeyPress-KP_Enter>", button.command # type: ignore[arg-type] 110 ) 111 btn.grid(row=0, column=num, padx=INTERNAL_PAD/2) 112 113 def init_standard_buttons(self) -> None: 114 """ 115 Define the button definitions. 116 """ 117 self.button_definitions = { 118 ButtonName.OK: ButtonDefinition( 119 text=_("OK"), command=lambda: self._set_result(ButtonName.OK) 120 ), 121 ButtonName.CANCEL: ButtonDefinition( 122 text=_("Cancel"), command=lambda: self._set_result(ButtonName.CANCEL) 123 ), 124 ButtonName.CLOSE: ButtonDefinition( 125 text=_("Close"), command=lambda: self._set_result(ButtonName.CLOSE) 126 ), 127 ButtonName.YES: ButtonDefinition( 128 text=_("Yes"), command=lambda: self._set_result(ButtonName.YES) 129 ), 130 ButtonName.NO: ButtonDefinition( 131 text=_("No"), command=lambda: self._set_result(ButtonName.NO) 132 ), 133 ButtonName.RETRY: ButtonDefinition( 134 text=_("Retry"), command=lambda: self._set_result(ButtonName.RETRY) 135 ), 136 } 137 138 def _set_result(self, value: ButtonName) -> None: 139 """ 140 Set the result to the ButtonName pressed. 141 142 Parameters 143 ---------- 144 value : ButtonName 145 The ButtonName of the button pressed. 146 """ 147 self.result = value 148 self.dismiss() 149 150 def dismiss(self, *_args) -> None: 151 """ 152 Dismiss the window. 153 """ 154 if self.toplevel is not None: 155 self.toplevel.grab_release() 156 self.toplevel.destroy()
Mixin class for standard button sets in dialogs.
Attributes
- result (ButtonName): The button pressed to close the message box.
- button_definitions (dict[ButtonName, ButtonDefinition]): A dictionary of standard buttons available to use.