1import unittest 2import re 3import tkinter 4from tkinter import TclError 5from test.support import requires 6 7from tkinter.test.support import pixels_conv, tcl_version, requires_tcl 8from tkinter.test.widget_tests import AbstractWidgetTest 9 10requires('gui') 11 12 13class PackTest(AbstractWidgetTest, unittest.TestCase): 14 15 test_keys = None 16 17 def create2(self): 18 pack = tkinter.Toplevel(self.root, name='pack') 19 pack.wm_geometry('300x200+0+0') 20 pack.wm_minsize(1, 1) 21 a = tkinter.Frame(pack, name='a', width=20, height=40, bg='red') 22 b = tkinter.Frame(pack, name='b', width=50, height=30, bg='blue') 23 c = tkinter.Frame(pack, name='c', width=80, height=80, bg='green') 24 d = tkinter.Frame(pack, name='d', width=40, height=30, bg='yellow') 25 return pack, a, b, c, d 26 27 def test_pack_configure_after(self): 28 pack, a, b, c, d = self.create2() 29 with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b): 30 a.pack_configure(after=b) 31 with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): 32 a.pack_configure(after='.foo') 33 a.pack_configure(side='top') 34 b.pack_configure(side='top') 35 c.pack_configure(side='top') 36 d.pack_configure(side='top') 37 self.assertEqual(pack.pack_slaves(), [a, b, c, d]) 38 a.pack_configure(after=b) 39 self.assertEqual(pack.pack_slaves(), [b, a, c, d]) 40 a.pack_configure(after=a) 41 self.assertEqual(pack.pack_slaves(), [b, a, c, d]) 42 43 def test_pack_configure_anchor(self): 44 pack, a, b, c, d = self.create2() 45 def check(anchor, geom): 46 a.pack_configure(side='top', ipadx=5, padx=10, ipady=15, pady=20, 47 expand=True, anchor=anchor) 48 self.root.update() 49 self.assertEqual(a.winfo_geometry(), geom) 50 check('n', '30x70+135+20') 51 check('ne', '30x70+260+20') 52 check('e', '30x70+260+65') 53 check('se', '30x70+260+110') 54 check('s', '30x70+135+110') 55 check('sw', '30x70+10+110') 56 check('w', '30x70+10+65') 57 check('nw', '30x70+10+20') 58 check('center', '30x70+135+65') 59 60 def test_pack_configure_before(self): 61 pack, a, b, c, d = self.create2() 62 with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b): 63 a.pack_configure(before=b) 64 with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): 65 a.pack_configure(before='.foo') 66 a.pack_configure(side='top') 67 b.pack_configure(side='top') 68 c.pack_configure(side='top') 69 d.pack_configure(side='top') 70 self.assertEqual(pack.pack_slaves(), [a, b, c, d]) 71 a.pack_configure(before=d) 72 self.assertEqual(pack.pack_slaves(), [b, c, a, d]) 73 a.pack_configure(before=a) 74 self.assertEqual(pack.pack_slaves(), [b, c, a, d]) 75 76 def test_pack_configure_expand(self): 77 pack, a, b, c, d = self.create2() 78 def check(*geoms): 79 self.root.update() 80 self.assertEqual(a.winfo_geometry(), geoms[0]) 81 self.assertEqual(b.winfo_geometry(), geoms[1]) 82 self.assertEqual(c.winfo_geometry(), geoms[2]) 83 self.assertEqual(d.winfo_geometry(), geoms[3]) 84 a.pack_configure(side='left') 85 b.pack_configure(side='top') 86 c.pack_configure(side='right') 87 d.pack_configure(side='bottom') 88 check('20x40+0+80', '50x30+135+0', '80x80+220+75', '40x30+100+170') 89 a.pack_configure(side='left', expand='yes') 90 b.pack_configure(side='top', expand='on') 91 c.pack_configure(side='right', expand=True) 92 d.pack_configure(side='bottom', expand=1) 93 check('20x40+40+80', '50x30+175+35', '80x80+180+110', '40x30+100+135') 94 a.pack_configure(side='left', expand='yes', fill='both') 95 b.pack_configure(side='top', expand='on', fill='both') 96 c.pack_configure(side='right', expand=True, fill='both') 97 d.pack_configure(side='bottom', expand=1, fill='both') 98 check('100x200+0+0', '200x100+100+0', '160x100+140+100', '40x100+100+100') 99 100 def test_pack_configure_in(self): 101 pack, a, b, c, d = self.create2() 102 a.pack_configure(side='top') 103 b.pack_configure(side='top') 104 c.pack_configure(side='top') 105 d.pack_configure(side='top') 106 a.pack_configure(in_=pack) 107 self.assertEqual(pack.pack_slaves(), [b, c, d, a]) 108 a.pack_configure(in_=c) 109 self.assertEqual(pack.pack_slaves(), [b, c, d]) 110 self.assertEqual(c.pack_slaves(), [a]) 111 with self.assertRaisesRegex(TclError, 112 'can\'t pack %s inside itself' % (a,)): 113 a.pack_configure(in_=a) 114 with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): 115 a.pack_configure(in_='.foo') 116 117 def test_pack_configure_padx_ipadx_fill(self): 118 pack, a, b, c, d = self.create2() 119 def check(geom1, geom2, **kwargs): 120 a.pack_forget() 121 b.pack_forget() 122 a.pack_configure(**kwargs) 123 b.pack_configure(expand=True, fill='both') 124 self.root.update() 125 self.assertEqual(a.winfo_geometry(), geom1) 126 self.assertEqual(b.winfo_geometry(), geom2) 127 check('20x40+260+80', '240x200+0+0', side='right', padx=20) 128 check('20x40+250+80', '240x200+0+0', side='right', padx=(10, 30)) 129 check('60x40+240+80', '240x200+0+0', side='right', ipadx=20) 130 check('30x40+260+80', '250x200+0+0', side='right', ipadx=5, padx=10) 131 check('20x40+260+80', '240x200+0+0', side='right', padx=20, fill='x') 132 check('20x40+249+80', '240x200+0+0', 133 side='right', padx=(9, 31), fill='x') 134 check('60x40+240+80', '240x200+0+0', side='right', ipadx=20, fill='x') 135 check('30x40+260+80', '250x200+0+0', 136 side='right', ipadx=5, padx=10, fill='x') 137 check('30x40+255+80', '250x200+0+0', 138 side='right', ipadx=5, padx=(5, 15), fill='x') 139 check('20x40+140+0', '300x160+0+40', side='top', padx=20) 140 check('20x40+120+0', '300x160+0+40', side='top', padx=(0, 40)) 141 check('60x40+120+0', '300x160+0+40', side='top', ipadx=20) 142 check('30x40+135+0', '300x160+0+40', side='top', ipadx=5, padx=10) 143 check('30x40+130+0', '300x160+0+40', side='top', ipadx=5, padx=(5, 15)) 144 check('260x40+20+0', '300x160+0+40', side='top', padx=20, fill='x') 145 check('260x40+25+0', '300x160+0+40', 146 side='top', padx=(25, 15), fill='x') 147 check('300x40+0+0', '300x160+0+40', side='top', ipadx=20, fill='x') 148 check('280x40+10+0', '300x160+0+40', 149 side='top', ipadx=5, padx=10, fill='x') 150 check('280x40+5+0', '300x160+0+40', 151 side='top', ipadx=5, padx=(5, 15), fill='x') 152 a.pack_configure(padx='1c') 153 self.assertEqual(a.pack_info()['padx'], 154 self._str(pack.winfo_pixels('1c'))) 155 a.pack_configure(ipadx='1c') 156 self.assertEqual(a.pack_info()['ipadx'], 157 self._str(pack.winfo_pixels('1c'))) 158 159 def test_pack_configure_pady_ipady_fill(self): 160 pack, a, b, c, d = self.create2() 161 def check(geom1, geom2, **kwargs): 162 a.pack_forget() 163 b.pack_forget() 164 a.pack_configure(**kwargs) 165 b.pack_configure(expand=True, fill='both') 166 self.root.update() 167 self.assertEqual(a.winfo_geometry(), geom1) 168 self.assertEqual(b.winfo_geometry(), geom2) 169 check('20x40+280+80', '280x200+0+0', side='right', pady=20) 170 check('20x40+280+70', '280x200+0+0', side='right', pady=(10, 30)) 171 check('20x80+280+60', '280x200+0+0', side='right', ipady=20) 172 check('20x50+280+75', '280x200+0+0', side='right', ipady=5, pady=10) 173 check('20x40+280+80', '280x200+0+0', side='right', pady=20, fill='x') 174 check('20x40+280+69', '280x200+0+0', 175 side='right', pady=(9, 31), fill='x') 176 check('20x80+280+60', '280x200+0+0', side='right', ipady=20, fill='x') 177 check('20x50+280+75', '280x200+0+0', 178 side='right', ipady=5, pady=10, fill='x') 179 check('20x50+280+70', '280x200+0+0', 180 side='right', ipady=5, pady=(5, 15), fill='x') 181 check('20x40+140+20', '300x120+0+80', side='top', pady=20) 182 check('20x40+140+0', '300x120+0+80', side='top', pady=(0, 40)) 183 check('20x80+140+0', '300x120+0+80', side='top', ipady=20) 184 check('20x50+140+10', '300x130+0+70', side='top', ipady=5, pady=10) 185 check('20x50+140+5', '300x130+0+70', side='top', ipady=5, pady=(5, 15)) 186 check('300x40+0+20', '300x120+0+80', side='top', pady=20, fill='x') 187 check('300x40+0+25', '300x120+0+80', 188 side='top', pady=(25, 15), fill='x') 189 check('300x80+0+0', '300x120+0+80', side='top', ipady=20, fill='x') 190 check('300x50+0+10', '300x130+0+70', 191 side='top', ipady=5, pady=10, fill='x') 192 check('300x50+0+5', '300x130+0+70', 193 side='top', ipady=5, pady=(5, 15), fill='x') 194 a.pack_configure(pady='1c') 195 self.assertEqual(a.pack_info()['pady'], 196 self._str(pack.winfo_pixels('1c'))) 197 a.pack_configure(ipady='1c') 198 self.assertEqual(a.pack_info()['ipady'], 199 self._str(pack.winfo_pixels('1c'))) 200 201 def test_pack_configure_side(self): 202 pack, a, b, c, d = self.create2() 203 def check(side, geom1, geom2): 204 a.pack_configure(side=side) 205 self.assertEqual(a.pack_info()['side'], side) 206 b.pack_configure(expand=True, fill='both') 207 self.root.update() 208 self.assertEqual(a.winfo_geometry(), geom1) 209 self.assertEqual(b.winfo_geometry(), geom2) 210 check('top', '20x40+140+0', '300x160+0+40') 211 check('bottom', '20x40+140+160', '300x160+0+0') 212 check('left', '20x40+0+80', '280x200+20+0') 213 check('right', '20x40+280+80', '280x200+0+0') 214 215 def test_pack_forget(self): 216 pack, a, b, c, d = self.create2() 217 a.pack_configure() 218 b.pack_configure() 219 c.pack_configure() 220 self.assertEqual(pack.pack_slaves(), [a, b, c]) 221 b.pack_forget() 222 self.assertEqual(pack.pack_slaves(), [a, c]) 223 b.pack_forget() 224 self.assertEqual(pack.pack_slaves(), [a, c]) 225 d.pack_forget() 226 227 def test_pack_info(self): 228 pack, a, b, c, d = self.create2() 229 with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % a): 230 a.pack_info() 231 a.pack_configure() 232 b.pack_configure(side='right', in_=a, anchor='s', expand=True, fill='x', 233 ipadx=5, padx=10, ipady=2, pady=(5, 15)) 234 info = a.pack_info() 235 self.assertIsInstance(info, dict) 236 self.assertEqual(info['anchor'], 'center') 237 self.assertEqual(info['expand'], self._str(0)) 238 self.assertEqual(info['fill'], 'none') 239 self.assertEqual(info['in'], pack) 240 self.assertEqual(info['ipadx'], self._str(0)) 241 self.assertEqual(info['ipady'], self._str(0)) 242 self.assertEqual(info['padx'], self._str(0)) 243 self.assertEqual(info['pady'], self._str(0)) 244 self.assertEqual(info['side'], 'top') 245 info = b.pack_info() 246 self.assertIsInstance(info, dict) 247 self.assertEqual(info['anchor'], 's') 248 self.assertEqual(info['expand'], self._str(1)) 249 self.assertEqual(info['fill'], 'x') 250 self.assertEqual(info['in'], a) 251 self.assertEqual(info['ipadx'], self._str(5)) 252 self.assertEqual(info['ipady'], self._str(2)) 253 self.assertEqual(info['padx'], self._str(10)) 254 self.assertEqual(info['pady'], self._str((5, 15))) 255 self.assertEqual(info['side'], 'right') 256 257 def test_pack_propagate(self): 258 pack, a, b, c, d = self.create2() 259 pack.configure(width=300, height=200) 260 a.pack_configure() 261 pack.pack_propagate(False) 262 self.root.update() 263 self.assertEqual(pack.winfo_reqwidth(), 300) 264 self.assertEqual(pack.winfo_reqheight(), 200) 265 pack.pack_propagate(True) 266 self.root.update() 267 self.assertEqual(pack.winfo_reqwidth(), 20) 268 self.assertEqual(pack.winfo_reqheight(), 40) 269 270 def test_pack_slaves(self): 271 pack, a, b, c, d = self.create2() 272 self.assertEqual(pack.pack_slaves(), []) 273 a.pack_configure() 274 self.assertEqual(pack.pack_slaves(), [a]) 275 b.pack_configure() 276 self.assertEqual(pack.pack_slaves(), [a, b]) 277 278 279class PlaceTest(AbstractWidgetTest, unittest.TestCase): 280 281 test_keys = None 282 283 def create2(self): 284 t = tkinter.Toplevel(self.root, width=300, height=200, bd=0) 285 t.wm_geometry('300x200+0+0') 286 f = tkinter.Frame(t, width=154, height=84, bd=2, relief='raised') 287 f.place_configure(x=48, y=38) 288 f2 = tkinter.Frame(t, width=30, height=60, bd=2, relief='raised') 289 self.root.update() 290 return t, f, f2 291 292 def test_place_configure_in(self): 293 t, f, f2 = self.create2() 294 self.assertEqual(f2.winfo_manager(), '') 295 with self.assertRaisesRegex(TclError, "can't place %s relative to " 296 "itself" % re.escape(str(f2))): 297 f2.place_configure(in_=f2) 298 if tcl_version >= (8, 5): 299 self.assertEqual(f2.winfo_manager(), '') 300 with self.assertRaisesRegex(TclError, 'bad window path name'): 301 f2.place_configure(in_='spam') 302 f2.place_configure(in_=f) 303 self.assertEqual(f2.winfo_manager(), 'place') 304 305 def test_place_configure_x(self): 306 t, f, f2 = self.create2() 307 f2.place_configure(in_=f) 308 self.assertEqual(f2.place_info()['x'], '0') 309 self.root.update() 310 self.assertEqual(f2.winfo_x(), 50) 311 f2.place_configure(x=100) 312 self.assertEqual(f2.place_info()['x'], '100') 313 self.root.update() 314 self.assertEqual(f2.winfo_x(), 150) 315 f2.place_configure(x=-10, relx=1) 316 self.assertEqual(f2.place_info()['x'], '-10') 317 self.root.update() 318 self.assertEqual(f2.winfo_x(), 190) 319 with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'): 320 f2.place_configure(in_=f, x='spam') 321 322 def test_place_configure_y(self): 323 t, f, f2 = self.create2() 324 f2.place_configure(in_=f) 325 self.assertEqual(f2.place_info()['y'], '0') 326 self.root.update() 327 self.assertEqual(f2.winfo_y(), 40) 328 f2.place_configure(y=50) 329 self.assertEqual(f2.place_info()['y'], '50') 330 self.root.update() 331 self.assertEqual(f2.winfo_y(), 90) 332 f2.place_configure(y=-10, rely=1) 333 self.assertEqual(f2.place_info()['y'], '-10') 334 self.root.update() 335 self.assertEqual(f2.winfo_y(), 110) 336 with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'): 337 f2.place_configure(in_=f, y='spam') 338 339 def test_place_configure_relx(self): 340 t, f, f2 = self.create2() 341 f2.place_configure(in_=f) 342 self.assertEqual(f2.place_info()['relx'], '0') 343 self.root.update() 344 self.assertEqual(f2.winfo_x(), 50) 345 f2.place_configure(relx=0.5) 346 self.assertEqual(f2.place_info()['relx'], '0.5') 347 self.root.update() 348 self.assertEqual(f2.winfo_x(), 125) 349 f2.place_configure(relx=1) 350 self.assertEqual(f2.place_info()['relx'], '1') 351 self.root.update() 352 self.assertEqual(f2.winfo_x(), 200) 353 with self.assertRaisesRegex(TclError, 'expected floating-point number ' 354 'but got "spam"'): 355 f2.place_configure(in_=f, relx='spam') 356 357 def test_place_configure_rely(self): 358 t, f, f2 = self.create2() 359 f2.place_configure(in_=f) 360 self.assertEqual(f2.place_info()['rely'], '0') 361 self.root.update() 362 self.assertEqual(f2.winfo_y(), 40) 363 f2.place_configure(rely=0.5) 364 self.assertEqual(f2.place_info()['rely'], '0.5') 365 self.root.update() 366 self.assertEqual(f2.winfo_y(), 80) 367 f2.place_configure(rely=1) 368 self.assertEqual(f2.place_info()['rely'], '1') 369 self.root.update() 370 self.assertEqual(f2.winfo_y(), 120) 371 with self.assertRaisesRegex(TclError, 'expected floating-point number ' 372 'but got "spam"'): 373 f2.place_configure(in_=f, rely='spam') 374 375 def test_place_configure_anchor(self): 376 f = tkinter.Frame(self.root) 377 with self.assertRaisesRegex(TclError, 'bad anchor "j"'): 378 f.place_configure(anchor='j') 379 with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'): 380 f.place_configure(anchor='') 381 for value in 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center': 382 f.place_configure(anchor=value) 383 self.assertEqual(f.place_info()['anchor'], value) 384 385 def test_place_configure_width(self): 386 t, f, f2 = self.create2() 387 f2.place_configure(in_=f, width=120) 388 self.root.update() 389 self.assertEqual(f2.winfo_width(), 120) 390 f2.place_configure(width='') 391 self.root.update() 392 self.assertEqual(f2.winfo_width(), 30) 393 with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'): 394 f2.place_configure(width='abcd') 395 396 def test_place_configure_height(self): 397 t, f, f2 = self.create2() 398 f2.place_configure(in_=f, height=120) 399 self.root.update() 400 self.assertEqual(f2.winfo_height(), 120) 401 f2.place_configure(height='') 402 self.root.update() 403 self.assertEqual(f2.winfo_height(), 60) 404 with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'): 405 f2.place_configure(height='abcd') 406 407 def test_place_configure_relwidth(self): 408 t, f, f2 = self.create2() 409 f2.place_configure(in_=f, relwidth=0.5) 410 self.root.update() 411 self.assertEqual(f2.winfo_width(), 75) 412 f2.place_configure(relwidth='') 413 self.root.update() 414 self.assertEqual(f2.winfo_width(), 30) 415 with self.assertRaisesRegex(TclError, 'expected floating-point number ' 416 'but got "abcd"'): 417 f2.place_configure(relwidth='abcd') 418 419 def test_place_configure_relheight(self): 420 t, f, f2 = self.create2() 421 f2.place_configure(in_=f, relheight=0.5) 422 self.root.update() 423 self.assertEqual(f2.winfo_height(), 40) 424 f2.place_configure(relheight='') 425 self.root.update() 426 self.assertEqual(f2.winfo_height(), 60) 427 with self.assertRaisesRegex(TclError, 'expected floating-point number ' 428 'but got "abcd"'): 429 f2.place_configure(relheight='abcd') 430 431 def test_place_configure_bordermode(self): 432 f = tkinter.Frame(self.root) 433 with self.assertRaisesRegex(TclError, 'bad bordermode "j"'): 434 f.place_configure(bordermode='j') 435 with self.assertRaisesRegex(TclError, 'ambiguous bordermode ""'): 436 f.place_configure(bordermode='') 437 for value in 'inside', 'outside', 'ignore': 438 f.place_configure(bordermode=value) 439 self.assertEqual(f.place_info()['bordermode'], value) 440 441 def test_place_forget(self): 442 foo = tkinter.Frame(self.root) 443 foo.place_configure(width=50, height=50) 444 self.root.update() 445 foo.place_forget() 446 self.root.update() 447 self.assertFalse(foo.winfo_ismapped()) 448 with self.assertRaises(TypeError): 449 foo.place_forget(0) 450 451 def test_place_info(self): 452 t, f, f2 = self.create2() 453 f2.place_configure(in_=f, x=1, y=2, width=3, height=4, 454 relx=0.1, rely=0.2, relwidth=0.3, relheight=0.4, 455 anchor='se', bordermode='outside') 456 info = f2.place_info() 457 self.assertIsInstance(info, dict) 458 self.assertEqual(info['x'], '1') 459 self.assertEqual(info['y'], '2') 460 self.assertEqual(info['width'], '3') 461 self.assertEqual(info['height'], '4') 462 self.assertEqual(info['relx'], '0.1') 463 self.assertEqual(info['rely'], '0.2') 464 self.assertEqual(info['relwidth'], '0.3') 465 self.assertEqual(info['relheight'], '0.4') 466 self.assertEqual(info['anchor'], 'se') 467 self.assertEqual(info['bordermode'], 'outside') 468 self.assertEqual(info['x'], '1') 469 self.assertEqual(info['x'], '1') 470 with self.assertRaises(TypeError): 471 f2.place_info(0) 472 473 def test_place_slaves(self): 474 foo = tkinter.Frame(self.root) 475 bar = tkinter.Frame(self.root) 476 self.assertEqual(foo.place_slaves(), []) 477 bar.place_configure(in_=foo) 478 self.assertEqual(foo.place_slaves(), [bar]) 479 with self.assertRaises(TypeError): 480 foo.place_slaves(0) 481 482 483class GridTest(AbstractWidgetTest, unittest.TestCase): 484 485 test_keys = None 486 487 def tearDown(self): 488 cols, rows = self.root.grid_size() 489 for i in range(cols + 1): 490 self.root.grid_columnconfigure(i, weight=0, minsize=0, pad=0, uniform='') 491 for i in range(rows + 1): 492 self.root.grid_rowconfigure(i, weight=0, minsize=0, pad=0, uniform='') 493 self.root.grid_propagate(1) 494 if tcl_version >= (8, 5): 495 self.root.grid_anchor('nw') 496 super().tearDown() 497 498 def test_grid_configure(self): 499 b = tkinter.Button(self.root) 500 self.assertEqual(b.grid_info(), {}) 501 b.grid_configure() 502 self.assertEqual(b.grid_info()['in'], self.root) 503 self.assertEqual(b.grid_info()['column'], self._str(0)) 504 self.assertEqual(b.grid_info()['row'], self._str(0)) 505 b.grid_configure({'column': 1}, row=2) 506 self.assertEqual(b.grid_info()['column'], self._str(1)) 507 self.assertEqual(b.grid_info()['row'], self._str(2)) 508 509 def test_grid_configure_column(self): 510 b = tkinter.Button(self.root) 511 with self.assertRaisesRegex(TclError, 'bad column value "-1": ' 512 'must be a non-negative integer'): 513 b.grid_configure(column=-1) 514 b.grid_configure(column=2) 515 self.assertEqual(b.grid_info()['column'], self._str(2)) 516 517 def test_grid_configure_columnspan(self): 518 b = tkinter.Button(self.root) 519 with self.assertRaisesRegex(TclError, 'bad columnspan value "0": ' 520 'must be a positive integer'): 521 b.grid_configure(columnspan=0) 522 b.grid_configure(columnspan=2) 523 self.assertEqual(b.grid_info()['columnspan'], self._str(2)) 524 525 def test_grid_configure_in(self): 526 f = tkinter.Frame(self.root) 527 b = tkinter.Button(self.root) 528 self.assertEqual(b.grid_info(), {}) 529 b.grid_configure() 530 self.assertEqual(b.grid_info()['in'], self.root) 531 b.grid_configure(in_=f) 532 self.assertEqual(b.grid_info()['in'], f) 533 b.grid_configure({'in': self.root}) 534 self.assertEqual(b.grid_info()['in'], self.root) 535 536 def test_grid_configure_ipadx(self): 537 b = tkinter.Button(self.root) 538 with self.assertRaisesRegex(TclError, 'bad ipadx value "-1": ' 539 'must be positive screen distance'): 540 b.grid_configure(ipadx=-1) 541 b.grid_configure(ipadx=1) 542 self.assertEqual(b.grid_info()['ipadx'], self._str(1)) 543 b.grid_configure(ipadx='.5c') 544 self.assertEqual(b.grid_info()['ipadx'], 545 self._str(round(pixels_conv('.5c') * self.scaling))) 546 547 def test_grid_configure_ipady(self): 548 b = tkinter.Button(self.root) 549 with self.assertRaisesRegex(TclError, 'bad ipady value "-1": ' 550 'must be positive screen distance'): 551 b.grid_configure(ipady=-1) 552 b.grid_configure(ipady=1) 553 self.assertEqual(b.grid_info()['ipady'], self._str(1)) 554 b.grid_configure(ipady='.5c') 555 self.assertEqual(b.grid_info()['ipady'], 556 self._str(round(pixels_conv('.5c') * self.scaling))) 557 558 def test_grid_configure_padx(self): 559 b = tkinter.Button(self.root) 560 with self.assertRaisesRegex(TclError, 'bad pad value "-1": ' 561 'must be positive screen distance'): 562 b.grid_configure(padx=-1) 563 b.grid_configure(padx=1) 564 self.assertEqual(b.grid_info()['padx'], self._str(1)) 565 b.grid_configure(padx=(10, 5)) 566 self.assertEqual(b.grid_info()['padx'], self._str((10, 5))) 567 b.grid_configure(padx='.5c') 568 self.assertEqual(b.grid_info()['padx'], 569 self._str(round(pixels_conv('.5c') * self.scaling))) 570 571 def test_grid_configure_pady(self): 572 b = tkinter.Button(self.root) 573 with self.assertRaisesRegex(TclError, 'bad pad value "-1": ' 574 'must be positive screen distance'): 575 b.grid_configure(pady=-1) 576 b.grid_configure(pady=1) 577 self.assertEqual(b.grid_info()['pady'], self._str(1)) 578 b.grid_configure(pady=(10, 5)) 579 self.assertEqual(b.grid_info()['pady'], self._str((10, 5))) 580 b.grid_configure(pady='.5c') 581 self.assertEqual(b.grid_info()['pady'], 582 self._str(round(pixels_conv('.5c') * self.scaling))) 583 584 def test_grid_configure_row(self): 585 b = tkinter.Button(self.root) 586 with self.assertRaisesRegex(TclError, 'bad (row|grid) value "-1": ' 587 'must be a non-negative integer'): 588 b.grid_configure(row=-1) 589 b.grid_configure(row=2) 590 self.assertEqual(b.grid_info()['row'], self._str(2)) 591 592 def test_grid_configure_rownspan(self): 593 b = tkinter.Button(self.root) 594 with self.assertRaisesRegex(TclError, 'bad rowspan value "0": ' 595 'must be a positive integer'): 596 b.grid_configure(rowspan=0) 597 b.grid_configure(rowspan=2) 598 self.assertEqual(b.grid_info()['rowspan'], self._str(2)) 599 600 def test_grid_configure_sticky(self): 601 f = tkinter.Frame(self.root, bg='red') 602 with self.assertRaisesRegex(TclError, 'bad stickyness value "glue"'): 603 f.grid_configure(sticky='glue') 604 f.grid_configure(sticky='ne') 605 self.assertEqual(f.grid_info()['sticky'], 'ne') 606 f.grid_configure(sticky='n,s,e,w') 607 self.assertEqual(f.grid_info()['sticky'], 'nesw') 608 609 def test_grid_columnconfigure(self): 610 with self.assertRaises(TypeError): 611 self.root.grid_columnconfigure() 612 self.assertEqual(self.root.grid_columnconfigure(0), 613 {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0}) 614 with self.assertRaisesRegex(TclError, 'bad option "-foo"'): 615 self.root.grid_columnconfigure(0, 'foo') 616 self.root.grid_columnconfigure((0, 3), weight=2) 617 with self.assertRaisesRegex(TclError, 618 'must specify a single element on retrieval'): 619 self.root.grid_columnconfigure((0, 3)) 620 b = tkinter.Button(self.root) 621 b.grid_configure(column=0, row=0) 622 if tcl_version >= (8, 5): 623 self.root.grid_columnconfigure('all', weight=3) 624 with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): 625 self.root.grid_columnconfigure('all') 626 self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) 627 self.assertEqual(self.root.grid_columnconfigure(3, 'weight'), 2) 628 self.assertEqual(self.root.grid_columnconfigure(265, 'weight'), 0) 629 if tcl_version >= (8, 5): 630 self.root.grid_columnconfigure(b, weight=4) 631 self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4) 632 633 def test_grid_columnconfigure_minsize(self): 634 with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): 635 self.root.grid_columnconfigure(0, minsize='foo') 636 self.root.grid_columnconfigure(0, minsize=10) 637 self.assertEqual(self.root.grid_columnconfigure(0, 'minsize'), 10) 638 self.assertEqual(self.root.grid_columnconfigure(0)['minsize'], 10) 639 640 def test_grid_columnconfigure_weight(self): 641 with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'): 642 self.root.grid_columnconfigure(0, weight='bad') 643 with self.assertRaisesRegex(TclError, 'invalid arg "-weight": ' 644 'should be non-negative'): 645 self.root.grid_columnconfigure(0, weight=-3) 646 self.root.grid_columnconfigure(0, weight=3) 647 self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) 648 self.assertEqual(self.root.grid_columnconfigure(0)['weight'], 3) 649 650 def test_grid_columnconfigure_pad(self): 651 with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): 652 self.root.grid_columnconfigure(0, pad='foo') 653 with self.assertRaisesRegex(TclError, 'invalid arg "-pad": ' 654 'should be non-negative'): 655 self.root.grid_columnconfigure(0, pad=-3) 656 self.root.grid_columnconfigure(0, pad=3) 657 self.assertEqual(self.root.grid_columnconfigure(0, 'pad'), 3) 658 self.assertEqual(self.root.grid_columnconfigure(0)['pad'], 3) 659 660 def test_grid_columnconfigure_uniform(self): 661 self.root.grid_columnconfigure(0, uniform='foo') 662 self.assertEqual(self.root.grid_columnconfigure(0, 'uniform'), 'foo') 663 self.assertEqual(self.root.grid_columnconfigure(0)['uniform'], 'foo') 664 665 def test_grid_rowconfigure(self): 666 with self.assertRaises(TypeError): 667 self.root.grid_rowconfigure() 668 self.assertEqual(self.root.grid_rowconfigure(0), 669 {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0}) 670 with self.assertRaisesRegex(TclError, 'bad option "-foo"'): 671 self.root.grid_rowconfigure(0, 'foo') 672 self.root.grid_rowconfigure((0, 3), weight=2) 673 with self.assertRaisesRegex(TclError, 674 'must specify a single element on retrieval'): 675 self.root.grid_rowconfigure((0, 3)) 676 b = tkinter.Button(self.root) 677 b.grid_configure(column=0, row=0) 678 if tcl_version >= (8, 5): 679 self.root.grid_rowconfigure('all', weight=3) 680 with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): 681 self.root.grid_rowconfigure('all') 682 self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) 683 self.assertEqual(self.root.grid_rowconfigure(3, 'weight'), 2) 684 self.assertEqual(self.root.grid_rowconfigure(265, 'weight'), 0) 685 if tcl_version >= (8, 5): 686 self.root.grid_rowconfigure(b, weight=4) 687 self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4) 688 689 def test_grid_rowconfigure_minsize(self): 690 with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): 691 self.root.grid_rowconfigure(0, minsize='foo') 692 self.root.grid_rowconfigure(0, minsize=10) 693 self.assertEqual(self.root.grid_rowconfigure(0, 'minsize'), 10) 694 self.assertEqual(self.root.grid_rowconfigure(0)['minsize'], 10) 695 696 def test_grid_rowconfigure_weight(self): 697 with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'): 698 self.root.grid_rowconfigure(0, weight='bad') 699 with self.assertRaisesRegex(TclError, 'invalid arg "-weight": ' 700 'should be non-negative'): 701 self.root.grid_rowconfigure(0, weight=-3) 702 self.root.grid_rowconfigure(0, weight=3) 703 self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) 704 self.assertEqual(self.root.grid_rowconfigure(0)['weight'], 3) 705 706 def test_grid_rowconfigure_pad(self): 707 with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): 708 self.root.grid_rowconfigure(0, pad='foo') 709 with self.assertRaisesRegex(TclError, 'invalid arg "-pad": ' 710 'should be non-negative'): 711 self.root.grid_rowconfigure(0, pad=-3) 712 self.root.grid_rowconfigure(0, pad=3) 713 self.assertEqual(self.root.grid_rowconfigure(0, 'pad'), 3) 714 self.assertEqual(self.root.grid_rowconfigure(0)['pad'], 3) 715 716 def test_grid_rowconfigure_uniform(self): 717 self.root.grid_rowconfigure(0, uniform='foo') 718 self.assertEqual(self.root.grid_rowconfigure(0, 'uniform'), 'foo') 719 self.assertEqual(self.root.grid_rowconfigure(0)['uniform'], 'foo') 720 721 def test_grid_forget(self): 722 b = tkinter.Button(self.root) 723 c = tkinter.Button(self.root) 724 b.grid_configure(row=2, column=2, rowspan=2, columnspan=2, 725 padx=3, pady=4, sticky='ns') 726 self.assertEqual(self.root.grid_slaves(), [b]) 727 b.grid_forget() 728 c.grid_forget() 729 self.assertEqual(self.root.grid_slaves(), []) 730 self.assertEqual(b.grid_info(), {}) 731 b.grid_configure(row=0, column=0) 732 info = b.grid_info() 733 self.assertEqual(info['row'], self._str(0)) 734 self.assertEqual(info['column'], self._str(0)) 735 self.assertEqual(info['rowspan'], self._str(1)) 736 self.assertEqual(info['columnspan'], self._str(1)) 737 self.assertEqual(info['padx'], self._str(0)) 738 self.assertEqual(info['pady'], self._str(0)) 739 self.assertEqual(info['sticky'], '') 740 741 def test_grid_remove(self): 742 b = tkinter.Button(self.root) 743 c = tkinter.Button(self.root) 744 b.grid_configure(row=2, column=2, rowspan=2, columnspan=2, 745 padx=3, pady=4, sticky='ns') 746 self.assertEqual(self.root.grid_slaves(), [b]) 747 b.grid_remove() 748 c.grid_remove() 749 self.assertEqual(self.root.grid_slaves(), []) 750 self.assertEqual(b.grid_info(), {}) 751 b.grid_configure(row=0, column=0) 752 info = b.grid_info() 753 self.assertEqual(info['row'], self._str(0)) 754 self.assertEqual(info['column'], self._str(0)) 755 self.assertEqual(info['rowspan'], self._str(2)) 756 self.assertEqual(info['columnspan'], self._str(2)) 757 self.assertEqual(info['padx'], self._str(3)) 758 self.assertEqual(info['pady'], self._str(4)) 759 self.assertEqual(info['sticky'], 'ns') 760 761 def test_grid_info(self): 762 b = tkinter.Button(self.root) 763 self.assertEqual(b.grid_info(), {}) 764 b.grid_configure(row=2, column=2, rowspan=2, columnspan=2, 765 padx=3, pady=4, sticky='ns') 766 info = b.grid_info() 767 self.assertIsInstance(info, dict) 768 self.assertEqual(info['in'], self.root) 769 self.assertEqual(info['row'], self._str(2)) 770 self.assertEqual(info['column'], self._str(2)) 771 self.assertEqual(info['rowspan'], self._str(2)) 772 self.assertEqual(info['columnspan'], self._str(2)) 773 self.assertEqual(info['padx'], self._str(3)) 774 self.assertEqual(info['pady'], self._str(4)) 775 self.assertEqual(info['sticky'], 'ns') 776 777 @requires_tcl(8, 5) 778 def test_grid_anchor(self): 779 with self.assertRaisesRegex(TclError, 'bad anchor "x"'): 780 self.root.grid_anchor('x') 781 with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'): 782 self.root.grid_anchor('') 783 with self.assertRaises(TypeError): 784 self.root.grid_anchor('se', 'nw') 785 self.root.grid_anchor('se') 786 self.assertEqual(self.root.tk.call('grid', 'anchor', self.root), 'se') 787 788 def test_grid_bbox(self): 789 self.assertEqual(self.root.grid_bbox(), (0, 0, 0, 0)) 790 self.assertEqual(self.root.grid_bbox(0, 0), (0, 0, 0, 0)) 791 self.assertEqual(self.root.grid_bbox(0, 0, 1, 1), (0, 0, 0, 0)) 792 with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): 793 self.root.grid_bbox('x', 0) 794 with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): 795 self.root.grid_bbox(0, 'x') 796 with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): 797 self.root.grid_bbox(0, 0, 'x', 0) 798 with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): 799 self.root.grid_bbox(0, 0, 0, 'x') 800 with self.assertRaises(TypeError): 801 self.root.grid_bbox(0, 0, 0, 0, 0) 802 t = self.root 803 # de-maximize 804 t.wm_geometry('1x1+0+0') 805 t.wm_geometry('') 806 f1 = tkinter.Frame(t, width=75, height=75, bg='red') 807 f2 = tkinter.Frame(t, width=90, height=90, bg='blue') 808 f1.grid_configure(row=0, column=0) 809 f2.grid_configure(row=1, column=1) 810 self.root.update() 811 self.assertEqual(t.grid_bbox(), (0, 0, 165, 165)) 812 self.assertEqual(t.grid_bbox(0, 0), (0, 0, 75, 75)) 813 self.assertEqual(t.grid_bbox(0, 0, 1, 1), (0, 0, 165, 165)) 814 self.assertEqual(t.grid_bbox(1, 1), (75, 75, 90, 90)) 815 self.assertEqual(t.grid_bbox(10, 10, 0, 0), (0, 0, 165, 165)) 816 self.assertEqual(t.grid_bbox(-2, -2, -1, -1), (0, 0, 0, 0)) 817 self.assertEqual(t.grid_bbox(10, 10, 12, 12), (165, 165, 0, 0)) 818 819 def test_grid_location(self): 820 with self.assertRaises(TypeError): 821 self.root.grid_location() 822 with self.assertRaises(TypeError): 823 self.root.grid_location(0) 824 with self.assertRaises(TypeError): 825 self.root.grid_location(0, 0, 0) 826 with self.assertRaisesRegex(TclError, 'bad screen distance "x"'): 827 self.root.grid_location('x', 'y') 828 with self.assertRaisesRegex(TclError, 'bad screen distance "y"'): 829 self.root.grid_location('1c', 'y') 830 t = self.root 831 # de-maximize 832 t.wm_geometry('1x1+0+0') 833 t.wm_geometry('') 834 f = tkinter.Frame(t, width=200, height=100, 835 highlightthickness=0, bg='red') 836 self.assertEqual(f.grid_location(10, 10), (-1, -1)) 837 f.grid_configure() 838 self.root.update() 839 self.assertEqual(t.grid_location(-10, -10), (-1, -1)) 840 self.assertEqual(t.grid_location(-10, 0), (-1, 0)) 841 self.assertEqual(t.grid_location(-1, 0), (-1, 0)) 842 self.assertEqual(t.grid_location(0, -10), (0, -1)) 843 self.assertEqual(t.grid_location(0, -1), (0, -1)) 844 self.assertEqual(t.grid_location(0, 0), (0, 0)) 845 self.assertEqual(t.grid_location(200, 0), (0, 0)) 846 self.assertEqual(t.grid_location(201, 0), (1, 0)) 847 self.assertEqual(t.grid_location(0, 100), (0, 0)) 848 self.assertEqual(t.grid_location(0, 101), (0, 1)) 849 self.assertEqual(t.grid_location(201, 101), (1, 1)) 850 851 def test_grid_propagate(self): 852 self.assertEqual(self.root.grid_propagate(), True) 853 with self.assertRaises(TypeError): 854 self.root.grid_propagate(False, False) 855 self.root.grid_propagate(False) 856 self.assertFalse(self.root.grid_propagate()) 857 f = tkinter.Frame(self.root, width=100, height=100, bg='red') 858 f.grid_configure(row=0, column=0) 859 self.root.update() 860 self.assertEqual(f.winfo_width(), 100) 861 self.assertEqual(f.winfo_height(), 100) 862 f.grid_propagate(False) 863 g = tkinter.Frame(self.root, width=75, height=85, bg='green') 864 g.grid_configure(in_=f, row=0, column=0) 865 self.root.update() 866 self.assertEqual(f.winfo_width(), 100) 867 self.assertEqual(f.winfo_height(), 100) 868 f.grid_propagate(True) 869 self.root.update() 870 self.assertEqual(f.winfo_width(), 75) 871 self.assertEqual(f.winfo_height(), 85) 872 873 def test_grid_size(self): 874 with self.assertRaises(TypeError): 875 self.root.grid_size(0) 876 self.assertEqual(self.root.grid_size(), (0, 0)) 877 f = tkinter.Scale(self.root) 878 f.grid_configure(row=0, column=0) 879 self.assertEqual(self.root.grid_size(), (1, 1)) 880 f.grid_configure(row=4, column=5) 881 self.assertEqual(self.root.grid_size(), (6, 5)) 882 883 def test_grid_slaves(self): 884 self.assertEqual(self.root.grid_slaves(), []) 885 a = tkinter.Label(self.root) 886 a.grid_configure(row=0, column=1) 887 b = tkinter.Label(self.root) 888 b.grid_configure(row=1, column=0) 889 c = tkinter.Label(self.root) 890 c.grid_configure(row=1, column=1) 891 d = tkinter.Label(self.root) 892 d.grid_configure(row=1, column=1) 893 self.assertEqual(self.root.grid_slaves(), [d, c, b, a]) 894 self.assertEqual(self.root.grid_slaves(row=0), [a]) 895 self.assertEqual(self.root.grid_slaves(row=1), [d, c, b]) 896 self.assertEqual(self.root.grid_slaves(column=0), [b]) 897 self.assertEqual(self.root.grid_slaves(column=1), [d, c, a]) 898 self.assertEqual(self.root.grid_slaves(row=1, column=1), [d, c]) 899 900 901tests_gui = ( 902 PackTest, PlaceTest, GridTest, 903) 904 905if __name__ == '__main__': 906 unittest.main() 907