Edit on GitHub

sysmon_pytk.modals.messagebox

Message boxes.

 1# SPDX-FileCopyrightText: © 2024 Stacey Adams <stacey.belle.rose@gmail.com>
 2# SPDX-License-Identifier: MIT
 3
 4"""
 5Message boxes.
 6"""
 7
 8from .base import MessageBox, MessageBoxButtonSet, MessageBoxIcon
 9from .mb_functions import (
10    ask_ok_cancel,
11    ask_retry_cancel,
12    ask_yes_no,
13    ask_yes_no_cancel,
14    show_error,
15    show_message,
16    show_warning,
17)
18
19__all__ = [
20    "MessageBox",
21    "MessageBoxButtonSet",
22    "MessageBoxIcon",
23    "ask_ok_cancel",
24    "ask_retry_cancel",
25    "ask_yes_no",
26    "ask_yes_no_cancel",
27    "show_message",
28    "show_warning",
29    "show_error"
30]
class MessageBox(sysmon_pytk.widgets.buttons.ButtonMixin, tkinter.Toplevel):
 70class MessageBox(ButtonMixin, tk.Toplevel):
 71    """
 72    Message box modal dialog.
 73
 74    Attributes
 75    ----------
 76    message : str
 77        The message text of the message box.
 78    icon : MessageBoxIcon
 79        The standard icon to display with the message.
 80    custom_icon : PhotoImage
 81        The custom icon to display with the message.
 82    button_set : MessageBoxButtonSet
 83        The set of buttons to display in the message box.
 84    button_list : list[ButtonName]
 85        A list of buttons to display in the message box, overrides button_set.
 86    default : int
 87        The default button number.
 88    internal_frame : ttk.Frame
 89        A frame to hold the message box contents.
 90    """
 91
 92    def __init__(
 93        self, parent: tk.Misc | None = None, *,
 94        title: str | None = None,
 95        message: str | None = None,
 96        icon: MessageBoxIcon | None = None,
 97        custom_icon: tk.PhotoImage | None = None,
 98        button_set: MessageBoxButtonSet = MessageBoxButtonSet.OK,
 99        button_list: list[ButtonName] | None = None,
100        default: int = -1
101    ) -> None:
102        """
103        Construct a messagebox.
104
105        Parameters
106        ----------
107        parent : Misc, optional
108            The parent widget.
109        title : str, optional
110            The title to display in the window title bar.
111        message : str, optional
112            The message text of the messagebox.
113        icon : MessageBoxIcon, optional
114            The standard icon to display with the message.
115        custom_icon : PhotoImage, optional
116            The custom icon to display with the message.
117        button_set : MessageBoxButtonSet
118            The set of buttons to display in the message box.
119        button_list : list[ButtonName]
120            A list of buttons to display in the message box, overrides button_set.
121        default : int
122            The default button number.
123        """
124        super().__init__(parent, class_="MessageBox")
125        self.message = message
126        self.icon = icon
127        self.custom_icon = custom_icon
128        self.button_set = button_set
129        self.button_list = button_list
130        self.default = default
131        self._set_standard_icon()
132        self.internal_frame = ttk.Frame(self)
133        self.internal_frame.grid(sticky=tk.NSEW)
134        self.title(title)
135        self.bind("<KeyPress-Escape>", self.dismiss)
136        self.create_widgets()
137        top = self.winfo_toplevel()
138        top.rowconfigure(0, weight=1)
139        top.columnconfigure(0, weight=1)
140        self.transient(parent)  # type: ignore[arg-type]
141        self.wm_withdraw()
142
143    def show(self) -> ButtonName:
144        """
145        Show the constructed message box as a modal dialog.
146
147        Returns
148        -------
149        ButtonName - the ButtonName of the button pressed.
150        """
151        self.wm_deiconify()
152        self.wait_visibility()
153        self.grab_set()
154        self.wait_window()
155        return self.result
156
157    def create_widgets(self) -> None:
158        """
159        Create the widgets to be displayed in the message box.
160        """
161        message = self.message if self.message else ""
162        label = ttk.Label(
163            self.internal_frame, text=message, compound=tk.LEFT, wraplength=320
164        )
165        if self.custom_icon is not None:
166            label.configure(image=self.custom_icon)
167        label.grid(row=0, column=0, sticky=tk.NSEW, padx=INTERNAL_PAD, pady=INTERNAL_PAD)
168        if self.button_list is not None:
169            with suppress(KeyError):
170                buttons = [self.button_definitions[button] for button in self.button_list]
171                self.add_buttons(self.internal_frame, buttons=buttons, default=self.default)
172        else:
173            self.add_buttons_from_button_set()()
174
175    def _set_standard_icon(self) -> None:
176        if self.custom_icon is not None:
177            return
178        file: str | None = None
179        if self.icon is not None:
180            with suppress(KeyError):
181                file = MESSAGE_BOX_ICON_PATHS[self.icon]
182        if file is not None:
183            self.custom_icon = tk.PhotoImage(file=get_full_path(file))
184
185    def add_buttons_from_button_set(self) -> Callable:
186        """
187        Add buttons based on the button set.
188
189        Returns
190        -------
191        Callable - a method which adds one or more buttons to the message box.
192        """
193        button_set_command = {
194            MessageBoxButtonSet.OK: self.add_ok_button,
195            MessageBoxButtonSet.OKCANCEL: self.add_ok_cancel_buttons,
196            MessageBoxButtonSet.CLOSE: self.add_close_button,
197            MessageBoxButtonSet.YESNO: self.add_yes_no_buttons,
198            MessageBoxButtonSet.YESNOCANCEL: self.add_yes_no_cancel_buttons,
199            MessageBoxButtonSet.RETRYCANCEL: self.add_retry_cancel_buttons
200        }
201        with suppress(KeyError):
202            return button_set_command[self.button_set]
203        return lambda: None
204
205    def add_ok_button(self) -> None:
206        """
207        Add an OK button to the bottom row of the modal dialog.
208        """
209        buttons = [
210            self.button_definitions[ButtonName.OK]
211        ]
212        self.add_buttons(self.internal_frame, buttons=buttons, default=0)
213
214    def add_ok_cancel_buttons(self) -> None:
215        """
216        Add OK and Cancel buttons to the bottom row of the modal dialog.
217        """
218        buttons = [
219            self.button_definitions[ButtonName.CANCEL],
220            self.button_definitions[ButtonName.OK]
221        ]
222        self.add_buttons(self.internal_frame, buttons=buttons, default=1)
223
224    def add_close_button(self) -> None:
225        """
226        Add a Close button to the bottom row of the modal dialog.
227        """
228        buttons = [
229            self.button_definitions[ButtonName.CLOSE]
230        ]
231        self.add_buttons(self.internal_frame, buttons=buttons, default=0)
232
233    def add_yes_no_buttons(self) -> None:
234        """
235        Add Yes and No buttons to the bottom row of the modal dialog.
236        """
237        buttons = [
238            self.button_definitions[ButtonName.NO],
239            self.button_definitions[ButtonName.YES]
240        ]
241        self.add_buttons(self.internal_frame, buttons=buttons, default=1)
242
243    def add_yes_no_cancel_buttons(self) -> None:
244        """
245        Add OK and Cancel buttons to the bottom row of the modal dialog.
246        """
247        buttons = [
248            self.button_definitions[ButtonName.CANCEL],
249            self.button_definitions[ButtonName.NO],
250            self.button_definitions[ButtonName.YES]
251        ]
252        self.add_buttons(self.internal_frame, buttons=buttons, default=2)
253
254    def add_retry_cancel_buttons(self) -> None:
255        """
256        Add Retry and Cancel buttons to the bottom row of the modal dialog.
257        """
258        buttons = [
259            self.button_definitions[ButtonName.CANCEL],
260            self.button_definitions[ButtonName.RETRY]
261        ]
262        self.add_buttons(self.internal_frame, buttons=buttons, default=1)

Message box modal dialog.

Attributes
  • message (str): The message text of the message box.
  • icon (MessageBoxIcon): The standard icon to display with the message.
  • custom_icon (PhotoImage): The custom icon to display with the message.
  • button_set (MessageBoxButtonSet): The set of buttons to display in the message box.
  • button_list (list[ButtonName]): A list of buttons to display in the message box, overrides button_set.
  • default (int): The default button number.
  • internal_frame (ttk.Frame): A frame to hold the message box contents.
MessageBox( parent: tkinter.Misc | None = None, *, title: str | None = None, message: str | None = None, icon: MessageBoxIcon | None = None, custom_icon: tkinter.PhotoImage | None = None, button_set: MessageBoxButtonSet = <MessageBoxButtonSet.OK: 1>, button_list: list[sysmon_pytk.widgets.buttons.ButtonName] | None = None, default: int = -1)
 92    def __init__(
 93        self, parent: tk.Misc | None = None, *,
 94        title: str | None = None,
 95        message: str | None = None,
 96        icon: MessageBoxIcon | None = None,
 97        custom_icon: tk.PhotoImage | None = None,
 98        button_set: MessageBoxButtonSet = MessageBoxButtonSet.OK,
 99        button_list: list[ButtonName] | None = None,
100        default: int = -1
101    ) -> None:
102        """
103        Construct a messagebox.
104
105        Parameters
106        ----------
107        parent : Misc, optional
108            The parent widget.
109        title : str, optional
110            The title to display in the window title bar.
111        message : str, optional
112            The message text of the messagebox.
113        icon : MessageBoxIcon, optional
114            The standard icon to display with the message.
115        custom_icon : PhotoImage, optional
116            The custom icon to display with the message.
117        button_set : MessageBoxButtonSet
118            The set of buttons to display in the message box.
119        button_list : list[ButtonName]
120            A list of buttons to display in the message box, overrides button_set.
121        default : int
122            The default button number.
123        """
124        super().__init__(parent, class_="MessageBox")
125        self.message = message
126        self.icon = icon
127        self.custom_icon = custom_icon
128        self.button_set = button_set
129        self.button_list = button_list
130        self.default = default
131        self._set_standard_icon()
132        self.internal_frame = ttk.Frame(self)
133        self.internal_frame.grid(sticky=tk.NSEW)
134        self.title(title)
135        self.bind("<KeyPress-Escape>", self.dismiss)
136        self.create_widgets()
137        top = self.winfo_toplevel()
138        top.rowconfigure(0, weight=1)
139        top.columnconfigure(0, weight=1)
140        self.transient(parent)  # type: ignore[arg-type]
141        self.wm_withdraw()

Construct a messagebox.

Parameters
  • parent (Misc, optional): The parent widget.
  • title (str, optional): The title to display in the window title bar.
  • message (str, optional): The message text of the messagebox.
  • icon (MessageBoxIcon, optional): The standard icon to display with the message.
  • custom_icon (PhotoImage, optional): The custom icon to display with the message.
  • button_set (MessageBoxButtonSet): The set of buttons to display in the message box.
  • button_list (list[ButtonName]): A list of buttons to display in the message box, overrides button_set.
  • default (int): The default button number.
def show(self) -> sysmon_pytk.widgets.buttons.ButtonName:
143    def show(self) -> ButtonName:
144        """
145        Show the constructed message box as a modal dialog.
146
147        Returns
148        -------
149        ButtonName - the ButtonName of the button pressed.
150        """
151        self.wm_deiconify()
152        self.wait_visibility()
153        self.grab_set()
154        self.wait_window()
155        return self.result

Show the constructed message box as a modal dialog.

Returns
  • ButtonName - the ButtonName of the button pressed.
def create_widgets(self) -> None:
157    def create_widgets(self) -> None:
158        """
159        Create the widgets to be displayed in the message box.
160        """
161        message = self.message if self.message else ""
162        label = ttk.Label(
163            self.internal_frame, text=message, compound=tk.LEFT, wraplength=320
164        )
165        if self.custom_icon is not None:
166            label.configure(image=self.custom_icon)
167        label.grid(row=0, column=0, sticky=tk.NSEW, padx=INTERNAL_PAD, pady=INTERNAL_PAD)
168        if self.button_list is not None:
169            with suppress(KeyError):
170                buttons = [self.button_definitions[button] for button in self.button_list]
171                self.add_buttons(self.internal_frame, buttons=buttons, default=self.default)
172        else:
173            self.add_buttons_from_button_set()()

Create the widgets to be displayed in the message box.

def add_buttons_from_button_set(self) -> Callable:
185    def add_buttons_from_button_set(self) -> Callable:
186        """
187        Add buttons based on the button set.
188
189        Returns
190        -------
191        Callable - a method which adds one or more buttons to the message box.
192        """
193        button_set_command = {
194            MessageBoxButtonSet.OK: self.add_ok_button,
195            MessageBoxButtonSet.OKCANCEL: self.add_ok_cancel_buttons,
196            MessageBoxButtonSet.CLOSE: self.add_close_button,
197            MessageBoxButtonSet.YESNO: self.add_yes_no_buttons,
198            MessageBoxButtonSet.YESNOCANCEL: self.add_yes_no_cancel_buttons,
199            MessageBoxButtonSet.RETRYCANCEL: self.add_retry_cancel_buttons
200        }
201        with suppress(KeyError):
202            return button_set_command[self.button_set]
203        return lambda: None

Add buttons based on the button set.

Returns
  • Callable - a method which adds one or more buttons to the message box.
def add_ok_button(self) -> None:
205    def add_ok_button(self) -> None:
206        """
207        Add an OK button to the bottom row of the modal dialog.
208        """
209        buttons = [
210            self.button_definitions[ButtonName.OK]
211        ]
212        self.add_buttons(self.internal_frame, buttons=buttons, default=0)

Add an OK button to the bottom row of the modal dialog.

def add_ok_cancel_buttons(self) -> None:
214    def add_ok_cancel_buttons(self) -> None:
215        """
216        Add OK and Cancel buttons to the bottom row of the modal dialog.
217        """
218        buttons = [
219            self.button_definitions[ButtonName.CANCEL],
220            self.button_definitions[ButtonName.OK]
221        ]
222        self.add_buttons(self.internal_frame, buttons=buttons, default=1)

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

def add_close_button(self) -> None:
224    def add_close_button(self) -> None:
225        """
226        Add a Close button to the bottom row of the modal dialog.
227        """
228        buttons = [
229            self.button_definitions[ButtonName.CLOSE]
230        ]
231        self.add_buttons(self.internal_frame, buttons=buttons, default=0)

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

def add_yes_no_buttons(self) -> None:
233    def add_yes_no_buttons(self) -> None:
234        """
235        Add Yes and No buttons to the bottom row of the modal dialog.
236        """
237        buttons = [
238            self.button_definitions[ButtonName.NO],
239            self.button_definitions[ButtonName.YES]
240        ]
241        self.add_buttons(self.internal_frame, buttons=buttons, default=1)

Add Yes and No buttons to the bottom row of the modal dialog.

def add_yes_no_cancel_buttons(self) -> None:
243    def add_yes_no_cancel_buttons(self) -> None:
244        """
245        Add OK and Cancel buttons to the bottom row of the modal dialog.
246        """
247        buttons = [
248            self.button_definitions[ButtonName.CANCEL],
249            self.button_definitions[ButtonName.NO],
250            self.button_definitions[ButtonName.YES]
251        ]
252        self.add_buttons(self.internal_frame, buttons=buttons, default=2)

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

def add_retry_cancel_buttons(self) -> None:
254    def add_retry_cancel_buttons(self) -> None:
255        """
256        Add Retry and Cancel buttons to the bottom row of the modal dialog.
257        """
258        buttons = [
259            self.button_definitions[ButtonName.CANCEL],
260            self.button_definitions[ButtonName.RETRY]
261        ]
262        self.add_buttons(self.internal_frame, buttons=buttons, default=1)

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

Inherited Members
sysmon_pytk.widgets.buttons.ButtonMixin
add_buttons
init_standard_buttons
dismiss
tkinter.BaseWidget
destroy
tkinter.Misc
deletecommand
tk_strictMotif
tk_bisque
tk_setPalette
wait_variable
waitvar
wait_window
wait_visibility
setvar
getvar
getboolean
focus_set
focus
focus_force
focus_get
focus_displayof
focus_lastfor
tk_focusFollowsMouse
tk_focusNext
tk_focusPrev
after
after_idle
after_cancel
bell
clipboard_get
clipboard_clear
clipboard_append
grab_current
grab_release
grab_set
grab_set_global
grab_status
option_add
option_clear
option_get
option_readfile
selection_clear
selection_get
selection_handle
selection_own
selection_own_get
send
lower
tkraise
lift
winfo_atom
winfo_atomname
winfo_cells
winfo_children
winfo_class
winfo_colormapfull
winfo_containing
winfo_depth
winfo_exists
winfo_fpixels
winfo_geometry
winfo_height
winfo_id
winfo_interps
winfo_ismapped
winfo_manager
winfo_name
winfo_parent
winfo_pathname
winfo_pixels
winfo_pointerx
winfo_pointerxy
winfo_pointery
winfo_reqheight
winfo_reqwidth
winfo_rgb
winfo_rootx
winfo_rooty
winfo_screen
winfo_screencells
winfo_screendepth
winfo_screenheight
winfo_screenmmheight
winfo_screenmmwidth
winfo_screenvisual
winfo_screenwidth
winfo_server
winfo_toplevel
winfo_viewable
winfo_visual
winfo_visualid
winfo_visualsavailable
winfo_vrootheight
winfo_vrootwidth
winfo_vrootx
winfo_vrooty
winfo_width
winfo_x
winfo_y
update
update_idletasks
bindtags
bind
unbind
bind_all
unbind_all
bind_class
unbind_class
mainloop
quit
nametowidget
register
configure
config
cget
keys
pack_propagate
propagate
pack_slaves
slaves
place_slaves
grid_anchor
anchor
grid_bbox
bbox
grid_columnconfigure
columnconfigure
grid_location
grid_propagate
grid_rowconfigure
rowconfigure
grid_size
size
grid_slaves
event_add
event_delete
event_generate
event_info
image_names
image_types
tkinter.Wm
wm_aspect
aspect
wm_attributes
attributes
wm_client
client
wm_colormapwindows
colormapwindows
wm_command
command
wm_deiconify
deiconify
wm_focusmodel
focusmodel
wm_forget
forget
wm_frame
frame
wm_geometry
geometry
wm_grid
grid
wm_group
group
wm_iconbitmap
iconbitmap
wm_iconify
iconify
wm_iconmask
iconmask
wm_iconname
iconname
wm_iconphoto
iconphoto
wm_iconposition
iconposition
wm_iconwindow
iconwindow
wm_manage
manage
wm_maxsize
maxsize
wm_minsize
minsize
wm_overrideredirect
overrideredirect
wm_positionfrom
positionfrom
wm_protocol
protocol
wm_resizable
resizable
wm_sizefrom
sizefrom
wm_state
state
wm_title
title
wm_transient
transient
wm_withdraw
withdraw
enum MessageBoxButtonSet(enum.IntEnum):
43class MessageBoxButtonSet(IntEnum):
44    """
45    Standard sets of buttons to use in a message box.
46    """
47
48    OK = 1
49    """Message box contains OK button."""
50    OKCANCEL = 2
51    """Message box contains OK and Cancel buttons."""
52    CLOSE = 3
53    """Message box contains Close button."""
54    YESNO = 4
55    """Message box contains Yes and No buttons."""
56    YESNOCANCEL = 5
57    """Message box contains Yes, No, and Cancel buttons."""
58    RETRYCANCEL = 6
59    """Message box contains Retry and Cancel buttons."""

Standard sets of buttons to use in a message box.

Message box contains OK button.

Message box contains OK and Cancel buttons.

Message box contains Close button.

Message box contains Yes and No buttons.

YESNOCANCEL = <MessageBoxButtonSet.YESNOCANCEL: 5>

Message box contains Yes, No, and Cancel buttons.

RETRYCANCEL = <MessageBoxButtonSet.RETRYCANCEL: 6>

Message box contains Retry and Cancel buttons.

Inherited Members
enum.Enum
name
value
builtins.int
conjugate
bit_length
bit_count
to_bytes
from_bytes
as_integer_ratio
real
imag
numerator
denominator
enum MessageBoxIcon(enum.IntEnum):
28class MessageBoxIcon(IntEnum):
29    """
30    Standard message box icons.
31    """
32
33    INFO = 1
34    """Message box displays the INFO icon."""
35    QUESTION = 2
36    """Message box displays the QUESTION icon."""
37    WARNING = 3
38    """Message box displays the WARNING icon."""
39    ERROR = 4
40    """Message box displays the ERROR icon."""

Standard message box icons.

INFO = <MessageBoxIcon.INFO: 1>

Message box displays the INFO icon.

QUESTION = <MessageBoxIcon.QUESTION: 2>

Message box displays the QUESTION icon.

WARNING = <MessageBoxIcon.WARNING: 3>

Message box displays the WARNING icon.

ERROR = <MessageBoxIcon.ERROR: 4>

Message box displays the ERROR icon.

Inherited Members
enum.Enum
name
value
builtins.int
conjugate
bit_length
bit_count
to_bytes
from_bytes
as_integer_ratio
real
imag
numerator
denominator
def ask_ok_cancel( parent: tkinter.Misc | None, title: str, message: str) -> sysmon_pytk.widgets.buttons.ButtonName:
51def ask_ok_cancel(parent: Misc | None, title: str, message: str) -> ButtonName:
52    """
53    Display a message box to ask a question with OK/Cancel buttons.
54    """
55    return MessageBox(
56        parent, title=title, message=message, icon=MessageBoxIcon.QUESTION,
57        button_set=MessageBoxButtonSet.OKCANCEL
58    ).show()

Display a message box to ask a question with OK/Cancel buttons.

def ask_retry_cancel( parent: tkinter.Misc | None, title: str, message: str) -> sysmon_pytk.widgets.buttons.ButtonName:
81def ask_retry_cancel(parent: Misc | None, title: str, message: str) -> ButtonName:
82    """
83    Display a message box to ask a question with Retry/Cancel buttons.
84    """
85    return MessageBox(
86        parent, title=title, message=message, icon=MessageBoxIcon.QUESTION,
87        button_set=MessageBoxButtonSet.RETRYCANCEL
88    ).show()

Display a message box to ask a question with Retry/Cancel buttons.

def ask_yes_no( parent: tkinter.Misc | None, title: str, message: str) -> sysmon_pytk.widgets.buttons.ButtonName:
61def ask_yes_no(parent: Misc | None, title: str, message: str) -> ButtonName:
62    """
63    Display a message box to ask a question with Yes/No buttons.
64    """
65    return MessageBox(
66        parent, title=title, message=message, icon=MessageBoxIcon.QUESTION,
67        button_set=MessageBoxButtonSet.YESNO
68    ).show()

Display a message box to ask a question with Yes/No buttons.

def ask_yes_no_cancel( parent: tkinter.Misc | None, title: str, message: str) -> sysmon_pytk.widgets.buttons.ButtonName:
71def ask_yes_no_cancel(parent: Misc | None, title: str, message: str) -> ButtonName:
72    """
73    Display a message box to ask a question with Yes/No/Cancel buttons.
74    """
75    return MessageBox(
76        parent, title=title, message=message, icon=MessageBoxIcon.QUESTION,
77        button_set=MessageBoxButtonSet.YESNOCANCEL
78    ).show()

Display a message box to ask a question with Yes/No/Cancel buttons.

def show_message( parent: tkinter.Misc | None, title: str, message: str) -> sysmon_pytk.widgets.buttons.ButtonName:
21def show_message(parent: Misc | None, title: str, message: str) -> ButtonName:
22    """
23    Display a message box to show a message.
24    """
25    return MessageBox(
26        parent, title=title, message=message, icon=MessageBoxIcon.QUESTION,
27        button_set=MessageBoxButtonSet.OK
28    ).show()

Display a message box to show a message.

def show_warning( parent: tkinter.Misc | None, title: str, message: str) -> sysmon_pytk.widgets.buttons.ButtonName:
31def show_warning(parent: Misc | None, title: str, message: str) -> ButtonName:
32    """
33    Display a message box to show a warning.
34    """
35    return MessageBox(
36        parent, title=title, message=message, icon=MessageBoxIcon.WARNING,
37        button_set=MessageBoxButtonSet.OK
38    ).show()

Display a message box to show a warning.

def show_error( parent: tkinter.Misc | None, title: str, message: str) -> sysmon_pytk.widgets.buttons.ButtonName:
41def show_error(parent: Misc | None, title: str, message: str) -> ButtonName:
42    """
43    Display a message box to show an error.
44    """
45    return MessageBox(
46        parent, title=title, message=message, icon=MessageBoxIcon.ERROR,
47        button_set=MessageBoxButtonSet.OK
48    ).show()

Display a message box to show an error.