Issue #27939: Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused

by representing the scale as float value internally in Tk.  tkinter.IntVar
now works if float value is set to underlying Tk variable.
This commit is contained in:
Serhiy Storchaka 2016-10-30 18:49:52 +02:00
parent 0438683939
commit 32c0d3ada5
4 changed files with 25 additions and 9 deletions

View file

@ -357,7 +357,11 @@ def __init__(self, master=None, value=None, name=None):
def get(self):
"""Return the value of the variable as an integer."""
return self._tk.getint(self._tk.globalgetvar(self._name))
value = self._tk.globalgetvar(self._name)
try:
return self._tk.getint(value)
except (TypeError, TclError):
return int(self._tk.getdouble(value))
class DoubleVar(Variable):
"""Value holder for float variables."""
@ -2864,7 +2868,7 @@ def get(self):
value = self.tk.call(self._w, 'get')
try:
return self.tk.getint(value)
except (ValueError, TclError):
except (ValueError, TypeError, TclError):
return self.tk.getdouble(value)
def set(self, value):
"""Set the value to VALUE."""

View file

@ -167,15 +167,14 @@ def test_get(self):
self.assertEqual(123, v.get())
self.root.globalsetvar("name", "345")
self.assertEqual(345, v.get())
self.root.globalsetvar("name", "876.5")
self.assertEqual(876, v.get())
def test_invalid_value(self):
v = IntVar(self.root, name="name")
self.root.globalsetvar("name", "value")
with self.assertRaises((ValueError, TclError)):
v.get()
self.root.globalsetvar("name", "345.0")
with self.assertRaises((ValueError, TclError)):
v.get()
class TestDoubleVar(TestBase):

View file

@ -69,14 +69,12 @@ def test_initialization(self):
# variable initialization/passing
passed_expected = (('0', 0), (0, 0), (10, 10),
(-1, -1), (sys.maxsize + 1, sys.maxsize + 1))
(-1, -1), (sys.maxsize + 1, sys.maxsize + 1),
(2.5, 2), ('2.5', 2))
for pair in passed_expected:
x = ttk.LabeledScale(self.root, from_=pair[0])
self.assertEqual(x.value, pair[1])
x.destroy()
x = ttk.LabeledScale(self.root, from_='2.5')
self.assertRaises((ValueError, tkinter.TclError), x._variable.get)
x.destroy()
x = ttk.LabeledScale(self.root, from_=None)
self.assertRaises((ValueError, tkinter.TclError), x._variable.get)
x.destroy()
@ -155,8 +153,10 @@ def test_variable_change(self):
# The following update is needed since the test doesn't use mainloop,
# at the same time this shouldn't affect test outcome
x.update()
self.assertEqual(x.value, newval)
self.assertEqual(x.label['text'],
newval if self.wantobjects else str(newval))
self.assertEqual(float(x.scale.get()), newval)
self.assertGreater(x.scale.coords()[0], curr_xcoord)
self.assertEqual(x.scale.coords()[0],
int(x.label.place_info()['x']))
@ -168,10 +168,19 @@ def test_variable_change(self):
conv = int
x.value = conv(x.scale['to']) + 1 # no changes shouldn't happen
x.update()
self.assertEqual(x.value, newval)
self.assertEqual(conv(x.label['text']), newval)
self.assertEqual(float(x.scale.get()), newval)
self.assertEqual(x.scale.coords()[0],
int(x.label.place_info()['x']))
# non-integer value
x.value = newval = newval + 1.5
x.update()
self.assertEqual(x.value, int(newval))
self.assertEqual(conv(x.label['text']), int(newval))
self.assertEqual(float(x.scale.get()), newval)
x.destroy()

View file

@ -113,6 +113,10 @@ Core and Builtins
Library
-------
- Issue #27939: Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused
by representing the scale as float value internally in Tk. tkinter.IntVar
now works if float value is set to underlying Tk variable.
- Issue #28255: calendar.TextCalendar().prmonth() no longer prints a space
at the start of new line after printing a month's calendar. Patch by
Xiang Zhang.