|
1 | 1 | import os |
2 | 2 | import unittest |
| 3 | +import tkinter |
3 | 4 | from tkinter import filedialog |
| 5 | +from tkinter import ttk |
4 | 6 | from tkinter.commondialog import Dialog |
5 | 7 | from test.support import requires, swap_attr |
6 | 8 | from test.test_tkinter.support import setUpModule # noqa: F401 |
@@ -101,6 +103,104 @@ def test_subclasses(self): |
101 | 103 | self.assertIsInstance(d, filedialog.FileDialog) |
102 | 104 | self.assertEqual(d.top.title(), cls.title) |
103 | 105 |
|
| 106 | + # --- Themed widgets and keyboard (modernization) --- |
| 107 | + |
| 108 | + def open(self, **kw): |
| 109 | + d = filedialog.FileDialog(self.root, **kw) |
| 110 | + self.addCleanup(lambda: d.top.winfo_exists() and d.top.destroy()) |
| 111 | + d.top.deiconify() # __init__ leaves the dialog withdrawn until go() |
| 112 | + d.top.update() |
| 113 | + return d |
| 114 | + |
| 115 | + def test_use_ttk(self): |
| 116 | + # The dialog uses the themed (ttk) widgets by default. |
| 117 | + d = self.open() |
| 118 | + self.assertEqual(d.ok_button.winfo_class(), 'TButton') |
| 119 | + self.assertEqual(d.selection.winfo_class(), 'TEntry') |
| 120 | + |
| 121 | + def test_use_classic(self): |
| 122 | + # use_ttk=False uses the classic Tk widgets. |
| 123 | + d = self.open(use_ttk=False) |
| 124 | + self.assertEqual(d.ok_button.winfo_class(), 'Button') |
| 125 | + self.assertEqual(d.selection.winfo_class(), 'Entry') |
| 126 | + if d.top._windowingsystem == 'x11': |
| 127 | + self.assertEqual(str(d.botframe.cget('relief')), 'raised') |
| 128 | + |
| 129 | + def test_background(self): |
| 130 | + # The ttk dialog adopts the ttk background, even a customized one, while |
| 131 | + # the classic dialog keeps the default Toplevel background. |
| 132 | + style = ttk.Style(self.root) |
| 133 | + old = style.lookup('.', 'background') |
| 134 | + style.configure('.', background='#123456') |
| 135 | + self.addCleanup(style.configure, '.', background=old) |
| 136 | + d = self.open() |
| 137 | + self.assertEqual(str(d.top.cget('background')), '#123456') |
| 138 | + d = self.open(use_ttk=False) |
| 139 | + ref = tkinter.Toplevel(self.root) |
| 140 | + self.addCleanup(ref.destroy) |
| 141 | + self.assertEqual(str(d.top.cget('background')), |
| 142 | + str(ref.cget('background'))) |
| 143 | + |
| 144 | + def test_button_accelerator(self): |
| 145 | + # The buttons' "&" accelerators are parsed. |
| 146 | + d = self.open() |
| 147 | + self.assertEqual(str(d.ok_button.cget('text')), 'OK') |
| 148 | + self.assertEqual(int(d.ok_button.cget('underline')), 0) |
| 149 | + |
| 150 | + def test_default_ring(self): |
| 151 | + # The default ring follows the keyboard focus among the buttons. |
| 152 | + d = self.open() |
| 153 | + self.assertEqual(str(d.cancel_button.cget('default')), 'normal') |
| 154 | + d.cancel_button.focus_force() |
| 155 | + d.top.update() |
| 156 | + self.assertEqual(str(d.cancel_button.cget('default')), 'active') |
| 157 | + d.ok_button.focus_force() |
| 158 | + d.top.update() |
| 159 | + self.assertEqual(str(d.cancel_button.cget('default')), 'normal') |
| 160 | + |
| 161 | + def test_alt_key(self): |
| 162 | + # Alt + the underlined letter invokes the matching button. |
| 163 | + d = self.open() |
| 164 | + invoked = [] |
| 165 | + d.cancel_button.configure(command=lambda: invoked.append(True)) |
| 166 | + d.top.focus_force() |
| 167 | + d.top.update() |
| 168 | + d.top.event_generate('<Alt-c>') # "&Cancel" |
| 169 | + d.top.update() |
| 170 | + self.assertTrue(invoked) |
| 171 | + |
| 172 | + def test_escape_cancels(self): |
| 173 | + # The Escape key cancels the dialog. |
| 174 | + d = self.open() |
| 175 | + d.how = 'spam' |
| 176 | + d.top.focus_force() |
| 177 | + d.top.update() |
| 178 | + d.top.event_generate('<Escape>') |
| 179 | + d.top.update() |
| 180 | + self.assertIsNone(d.how) |
| 181 | + |
| 182 | + def test_horizontal_scrollbars(self): |
| 183 | + # Each list has a horizontal scrollbar besides the vertical one. |
| 184 | + d = self.open() |
| 185 | + self.assertEqual(str(d.dirshbar.cget('orient')), 'horizontal') |
| 186 | + self.assertEqual(str(d.fileshbar.cget('orient')), 'horizontal') |
| 187 | + self.assertTrue(d.dirs.cget('xscrollcommand')) |
| 188 | + self.assertTrue(d.files.cget('xscrollcommand')) |
| 189 | + |
| 190 | + def test_type_ahead(self): |
| 191 | + # Typing characters over a list jumps to a matching entry. |
| 192 | + d = self.open() |
| 193 | + d.directory = os.getcwd() # browsing the match fills the selection entry |
| 194 | + d.files.delete(0, 'end') |
| 195 | + for name in ('alpha', 'bravo', 'charlie'): |
| 196 | + d.files.insert('end', name) |
| 197 | + d.files.focus_force() |
| 198 | + d.top.update() |
| 199 | + d.files.event_generate('<Key>', keysym='c') |
| 200 | + d.top.update() |
| 201 | + sel = d.files.curselection() |
| 202 | + self.assertEqual([d.files.get(i) for i in sel], ['charlie']) |
| 203 | + |
104 | 204 |
|
105 | 205 | if __name__ == "__main__": |
106 | 206 | unittest.main() |
0 commit comments