跳转至

Dialog

Bases: BaseWidget

A simple dialog base class.

Source code in src/ttkbootstrap/dialogs/base.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
class Dialog(BaseWidget):
    """A simple dialog base class."""

    def __init__(self, parent: Optional[tkinter.Misc] = None, title: str = "", alert: bool = False) -> None:
        """
        Parameters:

            parent (Widget):
                Makes the window the logical parent of the message box.
                The messagebox is displayed on top of its parent window.

            title (str):
                The string displayed as the title of the message box.
                This option is ignored on Mac OS X, where platform
                guidelines forbid the use of a title on this kind of
                dialog.

            alert (bool):
                Ring the display's bell when the dialog is shown.
        """
        BaseWidget._setup(self, parent, {})
        self._winsys = self.master.tk.call("tk", "windowingsystem")
        self._parent = parent
        self._toplevel = None
        self._title = title or " "
        self._result = None
        self._alert = alert
        self._initial_focus = None

    def _locate(self) -> None:
        toplevel = self._toplevel
        center_on_parent(toplevel, self._parent)

    def show(self, position: Optional[Tuple[int, int]] = None, wait_for_result: bool = True) -> None:
        """Show the popup dialog
        Parameters:

            wait_for_result:
            position: tuple[int, int]
                The x and y coordinates used to position the dialog. If no parent
                then the dialog will anchor to the center of the parent window.
        """
        self.update_idletasks()
        self._result = None
        self.build()

        if position is None:
            self._locate()
        else:
            try:
                x, y = position
                self._toplevel.geometry(f'+{x}+{y}')
            except Exception:
                self._locate()

        self._toplevel.deiconify()
        if self._alert:
            self._toplevel.bell()

        if self._initial_focus:
            self._initial_focus.focus_force()

        if wait_for_result:
            self._toplevel.grab_set()
            self._toplevel.wait_window()

    def create_body(self, master: tkinter.Misc) -> None:
        """Create the dialog body.

        This method should be overridden and is called by the `build`
        method. Set the `self._initial_focus` for the widget that
        should receive the initial focus.

        Parameters:

            master (Widget):
                The parent widget.
        """
        raise NotImplementedError

    def create_buttonbox(self, master: tkinter.Misc) -> None:
        """Create the dialog button box.

        This method should be overridden and is called by the `build`
        method. Set the `self._initial_focus` for the button that
        should receive the intial focus.

        Parameters:

            master (Widget):
                The parent widget.
        """
        raise NotImplementedError

    def build(self) -> None:
        """Build the dialog from settings"""

        # setup toplevel based on widowing system
        if self._winsys == "win32":
            self._toplevel = ttk.Toplevel(
                transient=self.master,
                title=self._title,
                resizable=(False, False),
                minsize=(250, 15),
                iconify=True,
            )
        else:
            self._toplevel = ttk.Toplevel(
                transient=self.master,
                title=self._title,
                resizable=(False, False),
                minsize=(250, 15),
                windowtype="dialog",
                iconify=True,
            )

        self._toplevel.withdraw()  # reset the iconify state

        # bind <Escape> event to window close
        self._toplevel.bind("<Escape>", lambda _: self._toplevel.destroy())

        # create widgets
        self.create_body(self._toplevel)
        self.create_buttonbox(self._toplevel)

        # update the window before showing
        self._toplevel.update_idletasks()

        # Explicitly set geometry to ensure proper sizing on all platforms
        width = self._toplevel.winfo_reqwidth()
        height = self._toplevel.winfo_reqheight()
        if width > 0 and height > 0:
            self._toplevel.geometry(f"{width}x{height}")        

    @property
    def result(self) -> Any:
        """Returns the result of the dialog."""
        self._toplevel.grab_release()
        return self._result

result property

Returns the result of the dialog.

__init__(parent=None, title='', alert=False)

Parameters:

parent (Widget):
    Makes the window the logical parent of the message box.
    The messagebox is displayed on top of its parent window.

title (str):
    The string displayed as the title of the message box.
    This option is ignored on Mac OS X, where platform
    guidelines forbid the use of a title on this kind of
    dialog.

alert (bool):
    Ring the display's bell when the dialog is shown.
Source code in src/ttkbootstrap/dialogs/base.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def __init__(self, parent: Optional[tkinter.Misc] = None, title: str = "", alert: bool = False) -> None:
    """
    Parameters:

        parent (Widget):
            Makes the window the logical parent of the message box.
            The messagebox is displayed on top of its parent window.

        title (str):
            The string displayed as the title of the message box.
            This option is ignored on Mac OS X, where platform
            guidelines forbid the use of a title on this kind of
            dialog.

        alert (bool):
            Ring the display's bell when the dialog is shown.
    """
    BaseWidget._setup(self, parent, {})
    self._winsys = self.master.tk.call("tk", "windowingsystem")
    self._parent = parent
    self._toplevel = None
    self._title = title or " "
    self._result = None
    self._alert = alert
    self._initial_focus = None

build()

Build the dialog from settings

Source code in src/ttkbootstrap/dialogs/base.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def build(self) -> None:
    """Build the dialog from settings"""

    # setup toplevel based on widowing system
    if self._winsys == "win32":
        self._toplevel = ttk.Toplevel(
            transient=self.master,
            title=self._title,
            resizable=(False, False),
            minsize=(250, 15),
            iconify=True,
        )
    else:
        self._toplevel = ttk.Toplevel(
            transient=self.master,
            title=self._title,
            resizable=(False, False),
            minsize=(250, 15),
            windowtype="dialog",
            iconify=True,
        )

    self._toplevel.withdraw()  # reset the iconify state

    # bind <Escape> event to window close
    self._toplevel.bind("<Escape>", lambda _: self._toplevel.destroy())

    # create widgets
    self.create_body(self._toplevel)
    self.create_buttonbox(self._toplevel)

    # update the window before showing
    self._toplevel.update_idletasks()

    # Explicitly set geometry to ensure proper sizing on all platforms
    width = self._toplevel.winfo_reqwidth()
    height = self._toplevel.winfo_reqheight()
    if width > 0 and height > 0:
        self._toplevel.geometry(f"{width}x{height}")        

create_body(master)

Create the dialog body.

This method should be overridden and is called by the build method. Set the self._initial_focus for the widget that should receive the initial focus.

Parameters:

master (Widget):
    The parent widget.
Source code in src/ttkbootstrap/dialogs/base.py
81
82
83
84
85
86
87
88
89
90
91
92
93
def create_body(self, master: tkinter.Misc) -> None:
    """Create the dialog body.

    This method should be overridden and is called by the `build`
    method. Set the `self._initial_focus` for the widget that
    should receive the initial focus.

    Parameters:

        master (Widget):
            The parent widget.
    """
    raise NotImplementedError

create_buttonbox(master)

Create the dialog button box.

This method should be overridden and is called by the build method. Set the self._initial_focus for the button that should receive the intial focus.

Parameters:

master (Widget):
    The parent widget.
Source code in src/ttkbootstrap/dialogs/base.py
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def create_buttonbox(self, master: tkinter.Misc) -> None:
    """Create the dialog button box.

    This method should be overridden and is called by the `build`
    method. Set the `self._initial_focus` for the button that
    should receive the intial focus.

    Parameters:

        master (Widget):
            The parent widget.
    """
    raise NotImplementedError

show(position=None, wait_for_result=True)

Show the popup dialog Parameters:

wait_for_result:
position: tuple[int, int]
    The x and y coordinates used to position the dialog. If no parent
    then the dialog will anchor to the center of the parent window.
Source code in src/ttkbootstrap/dialogs/base.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def show(self, position: Optional[Tuple[int, int]] = None, wait_for_result: bool = True) -> None:
    """Show the popup dialog
    Parameters:

        wait_for_result:
        position: tuple[int, int]
            The x and y coordinates used to position the dialog. If no parent
            then the dialog will anchor to the center of the parent window.
    """
    self.update_idletasks()
    self._result = None
    self.build()

    if position is None:
        self._locate()
    else:
        try:
            x, y = position
            self._toplevel.geometry(f'+{x}+{y}')
        except Exception:
            self._locate()

    self._toplevel.deiconify()
    if self._alert:
        self._toplevel.bell()

    if self._initial_focus:
        self._initial_focus.focus_force()

    if wait_for_result:
        self._toplevel.grab_set()
        self._toplevel.wait_window()