PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/tkinter/test/test_ttk/test_extensions.py

https://gitlab.com/unofficial-mirrors/cpython
Python | 298 lines | 215 code | 49 blank | 34 comment | 19 complexity | f68e328ac7a7aebcf12c58400dc06ce0 MD5 | raw file
  1. import sys
  2. import unittest
  3. import tkinter
  4. from tkinter import ttk
  5. from test.support import requires, run_unittest, swap_attr
  6. from tkinter.test.support import AbstractTkTest, destroy_default_root
  7. requires('gui')
  8. class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
  9. def tearDown(self):
  10. self.root.update_idletasks()
  11. super().tearDown()
  12. def test_widget_destroy(self):
  13. # automatically created variable
  14. x = ttk.LabeledScale(self.root)
  15. var = x._variable._name
  16. x.destroy()
  17. self.assertRaises(tkinter.TclError, x.tk.globalgetvar, var)
  18. # manually created variable
  19. myvar = tkinter.DoubleVar(self.root)
  20. name = myvar._name
  21. x = ttk.LabeledScale(self.root, variable=myvar)
  22. x.destroy()
  23. if self.wantobjects:
  24. self.assertEqual(x.tk.globalgetvar(name), myvar.get())
  25. else:
  26. self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get())
  27. del myvar
  28. self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name)
  29. # checking that the tracing callback is properly removed
  30. myvar = tkinter.IntVar(self.root)
  31. # LabeledScale will start tracing myvar
  32. x = ttk.LabeledScale(self.root, variable=myvar)
  33. x.destroy()
  34. # Unless the tracing callback was removed, creating a new
  35. # LabeledScale with the same var will cause an error now. This
  36. # happens because the variable will be set to (possibly) a new
  37. # value which causes the tracing callback to be called and then
  38. # it tries calling instance attributes not yet defined.
  39. ttk.LabeledScale(self.root, variable=myvar)
  40. if hasattr(sys, 'last_type'):
  41. self.assertNotEqual(sys.last_type, tkinter.TclError)
  42. def test_initialization_no_master(self):
  43. # no master passing
  44. with swap_attr(tkinter, '_default_root', None), \
  45. swap_attr(tkinter, '_support_default_root', True):
  46. try:
  47. x = ttk.LabeledScale()
  48. self.assertIsNotNone(tkinter._default_root)
  49. self.assertEqual(x.master, tkinter._default_root)
  50. self.assertEqual(x.tk, tkinter._default_root.tk)
  51. x.destroy()
  52. finally:
  53. destroy_default_root()
  54. def test_initialization(self):
  55. # master passing
  56. master = tkinter.Frame(self.root)
  57. x = ttk.LabeledScale(master)
  58. self.assertEqual(x.master, master)
  59. x.destroy()
  60. # variable initialization/passing
  61. passed_expected = (('0', 0), (0, 0), (10, 10),
  62. (-1, -1), (sys.maxsize + 1, sys.maxsize + 1),
  63. (2.5, 2), ('2.5', 2))
  64. for pair in passed_expected:
  65. x = ttk.LabeledScale(self.root, from_=pair[0])
  66. self.assertEqual(x.value, pair[1])
  67. x.destroy()
  68. x = ttk.LabeledScale(self.root, from_=None)
  69. self.assertRaises((ValueError, tkinter.TclError), x._variable.get)
  70. x.destroy()
  71. # variable should have its default value set to the from_ value
  72. myvar = tkinter.DoubleVar(self.root, value=20)
  73. x = ttk.LabeledScale(self.root, variable=myvar)
  74. self.assertEqual(x.value, 0)
  75. x.destroy()
  76. # check that it is really using a DoubleVar
  77. x = ttk.LabeledScale(self.root, variable=myvar, from_=0.5)
  78. self.assertEqual(x.value, 0.5)
  79. self.assertEqual(x._variable._name, myvar._name)
  80. x.destroy()
  81. # widget positionment
  82. def check_positions(scale, scale_pos, label, label_pos):
  83. self.assertEqual(scale.pack_info()['side'], scale_pos)
  84. self.assertEqual(label.place_info()['anchor'], label_pos)
  85. x = ttk.LabeledScale(self.root, compound='top')
  86. check_positions(x.scale, 'bottom', x.label, 'n')
  87. x.destroy()
  88. x = ttk.LabeledScale(self.root, compound='bottom')
  89. check_positions(x.scale, 'top', x.label, 's')
  90. x.destroy()
  91. # invert default positions
  92. x = ttk.LabeledScale(self.root, compound='unknown')
  93. check_positions(x.scale, 'top', x.label, 's')
  94. x.destroy()
  95. x = ttk.LabeledScale(self.root) # take default positions
  96. check_positions(x.scale, 'bottom', x.label, 'n')
  97. x.destroy()
  98. # extra, and invalid, kwargs
  99. self.assertRaises(tkinter.TclError, ttk.LabeledScale, master, a='b')
  100. def test_horizontal_range(self):
  101. lscale = ttk.LabeledScale(self.root, from_=0, to=10)
  102. lscale.pack()
  103. lscale.wait_visibility()
  104. lscale.update()
  105. linfo_1 = lscale.label.place_info()
  106. prev_xcoord = lscale.scale.coords()[0]
  107. self.assertEqual(prev_xcoord, int(linfo_1['x']))
  108. # change range to: from -5 to 5. This should change the x coord of
  109. # the scale widget, since 0 is at the middle of the new
  110. # range.
  111. lscale.scale.configure(from_=-5, to=5)
  112. # The following update is needed since the test doesn't use mainloop,
  113. # at the same time this shouldn't affect test outcome
  114. lscale.update()
  115. curr_xcoord = lscale.scale.coords()[0]
  116. self.assertNotEqual(prev_xcoord, curr_xcoord)
  117. # the label widget should have been repositioned too
  118. linfo_2 = lscale.label.place_info()
  119. self.assertEqual(lscale.label['text'], 0 if self.wantobjects else '0')
  120. self.assertEqual(curr_xcoord, int(linfo_2['x']))
  121. # change the range back
  122. lscale.scale.configure(from_=0, to=10)
  123. self.assertNotEqual(prev_xcoord, curr_xcoord)
  124. self.assertEqual(prev_xcoord, int(linfo_1['x']))
  125. lscale.destroy()
  126. def test_variable_change(self):
  127. x = ttk.LabeledScale(self.root)
  128. x.pack()
  129. x.wait_visibility()
  130. x.update()
  131. curr_xcoord = x.scale.coords()[0]
  132. newval = x.value + 1
  133. x.value = newval
  134. # The following update is needed since the test doesn't use mainloop,
  135. # at the same time this shouldn't affect test outcome
  136. x.update()
  137. self.assertEqual(x.value, newval)
  138. self.assertEqual(x.label['text'],
  139. newval if self.wantobjects else str(newval))
  140. self.assertEqual(float(x.scale.get()), newval)
  141. self.assertGreater(x.scale.coords()[0], curr_xcoord)
  142. self.assertEqual(x.scale.coords()[0],
  143. int(x.label.place_info()['x']))
  144. # value outside range
  145. if self.wantobjects:
  146. conv = lambda x: x
  147. else:
  148. conv = int
  149. x.value = conv(x.scale['to']) + 1 # no changes shouldn't happen
  150. x.update()
  151. self.assertEqual(x.value, newval)
  152. self.assertEqual(conv(x.label['text']), newval)
  153. self.assertEqual(float(x.scale.get()), newval)
  154. self.assertEqual(x.scale.coords()[0],
  155. int(x.label.place_info()['x']))
  156. # non-integer value
  157. x.value = newval = newval + 1.5
  158. x.update()
  159. self.assertEqual(x.value, int(newval))
  160. self.assertEqual(conv(x.label['text']), int(newval))
  161. self.assertEqual(float(x.scale.get()), newval)
  162. x.destroy()
  163. def test_resize(self):
  164. x = ttk.LabeledScale(self.root)
  165. x.pack(expand=True, fill='both')
  166. x.wait_visibility()
  167. x.update()
  168. width, height = x.master.winfo_width(), x.master.winfo_height()
  169. width_new, height_new = width * 2, height * 2
  170. x.value = 3
  171. x.update()
  172. x.master.wm_geometry("%dx%d" % (width_new, height_new))
  173. self.assertEqual(int(x.label.place_info()['x']),
  174. x.scale.coords()[0])
  175. # Reset geometry
  176. x.master.wm_geometry("%dx%d" % (width, height))
  177. x.destroy()
  178. class OptionMenuTest(AbstractTkTest, unittest.TestCase):
  179. def setUp(self):
  180. super().setUp()
  181. self.textvar = tkinter.StringVar(self.root)
  182. def tearDown(self):
  183. del self.textvar
  184. super().tearDown()
  185. def test_widget_destroy(self):
  186. var = tkinter.StringVar(self.root)
  187. optmenu = ttk.OptionMenu(self.root, var)
  188. name = var._name
  189. optmenu.update_idletasks()
  190. optmenu.destroy()
  191. self.assertEqual(optmenu.tk.globalgetvar(name), var.get())
  192. del var
  193. self.assertRaises(tkinter.TclError, optmenu.tk.globalgetvar, name)
  194. def test_initialization(self):
  195. self.assertRaises(tkinter.TclError,
  196. ttk.OptionMenu, self.root, self.textvar, invalid='thing')
  197. optmenu = ttk.OptionMenu(self.root, self.textvar, 'b', 'a', 'b')
  198. self.assertEqual(optmenu._variable.get(), 'b')
  199. self.assertTrue(optmenu['menu'])
  200. self.assertTrue(optmenu['textvariable'])
  201. optmenu.destroy()
  202. def test_menu(self):
  203. items = ('a', 'b', 'c')
  204. default = 'a'
  205. optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items)
  206. found_default = False
  207. for i in range(len(items)):
  208. value = optmenu['menu'].entrycget(i, 'value')
  209. self.assertEqual(value, items[i])
  210. if value == default:
  211. found_default = True
  212. self.assertTrue(found_default)
  213. optmenu.destroy()
  214. # default shouldn't be in menu if it is not part of values
  215. default = 'd'
  216. optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items)
  217. curr = None
  218. i = 0
  219. while True:
  220. last, curr = curr, optmenu['menu'].entryconfigure(i, 'value')
  221. if last == curr:
  222. # no more menu entries
  223. break
  224. self.assertNotEqual(curr, default)
  225. i += 1
  226. self.assertEqual(i, len(items))
  227. # check that variable is updated correctly
  228. optmenu.pack()
  229. optmenu.wait_visibility()
  230. optmenu['menu'].invoke(0)
  231. self.assertEqual(optmenu._variable.get(), items[0])
  232. # changing to an invalid index shouldn't change the variable
  233. self.assertRaises(tkinter.TclError, optmenu['menu'].invoke, -1)
  234. self.assertEqual(optmenu._variable.get(), items[0])
  235. optmenu.destroy()
  236. # specifying a callback
  237. success = []
  238. def cb_test(item):
  239. self.assertEqual(item, items[1])
  240. success.append(True)
  241. optmenu = ttk.OptionMenu(self.root, self.textvar, 'a', command=cb_test,
  242. *items)
  243. optmenu['menu'].invoke(1)
  244. if not success:
  245. self.fail("Menu callback not invoked")
  246. optmenu.destroy()
  247. tests_gui = (LabeledScaleTest, OptionMenuTest)
  248. if __name__ == "__main__":
  249. run_unittest(*tests_gui)