summaryrefslogtreecommitdiffstats
path: root/Lib/tkinter
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/tkinter')
-rw-r--r--Lib/tkinter/__init__.py256
-rw-r--r--Lib/tkinter/_fix.py78
-rw-r--r--Lib/tkinter/font.py8
-rw-r--r--Lib/tkinter/simpledialog.py4
-rw-r--r--Lib/tkinter/test/runtktests.py2
-rw-r--r--Lib/tkinter/test/test_tkinter/test_geometry_managers.py6
-rw-r--r--Lib/tkinter/test/test_tkinter/test_misc.py5
-rw-r--r--Lib/tkinter/test/test_tkinter/test_variables.py6
-rw-r--r--Lib/tkinter/test/test_tkinter/test_widgets.py20
-rw-r--r--Lib/tkinter/test/test_ttk/test_extensions.py6
-rw-r--r--Lib/tkinter/test/test_ttk/test_widgets.py268
-rw-r--r--Lib/tkinter/test/widget_tests.py27
12 files changed, 303 insertions, 383 deletions
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index 75c40e56..da430df 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -31,9 +31,6 @@ tk.mainloop()
"""
import sys
-if sys.platform == "win32":
- # Attempt to configure Tcl/Tk without requiring PATH
- from tkinter import _fix
import _tkinter # If this fails your Python may not be configured for Tk
TclError = _tkinter.TclError
@@ -355,7 +352,7 @@ class IntVar(Variable):
def get(self):
"""Return the value of the variable as an integer."""
- return getint(self._tk.globalgetvar(self._name))
+ return self._tk.getint(self._tk.globalgetvar(self._name))
class DoubleVar(Variable):
"""Value holder for float variables."""
@@ -374,7 +371,7 @@ class DoubleVar(Variable):
def get(self):
"""Return the value of the variable as a float."""
- return getdouble(self._tk.globalgetvar(self._name))
+ return self._tk.getdouble(self._tk.globalgetvar(self._name))
class BooleanVar(Variable):
"""Value holder for boolean variables."""
@@ -505,14 +502,26 @@ class Misc:
def getvar(self, name='PY_VAR'):
"""Return value of Tcl variable NAME."""
return self.tk.getvar(name)
- getint = int
- getdouble = float
+
+ def getint(self, s):
+ try:
+ return self.tk.getint(s)
+ except TclError as exc:
+ raise ValueError(str(exc))
+
+ def getdouble(self, s):
+ try:
+ return self.tk.getdouble(s)
+ except TclError as exc:
+ raise ValueError(str(exc))
+
def getboolean(self, s):
"""Return a boolean value for Tcl boolean values true and false given as parameter."""
try:
return self.tk.getboolean(s)
except TclError:
raise ValueError("invalid literal for getboolean()")
+
def focus_set(self):
"""Direct input focus to this widget.
@@ -775,13 +784,10 @@ class Misc:
"""Raise this widget in the stacking order."""
self.tk.call('raise', self._w, aboveThis)
lift = tkraise
- def colormodel(self, value=None):
- """Useless. Not implemented in Tk."""
- return self.tk.call('tk', 'colormodel', self._w, value)
def winfo_atom(self, name, displayof=0):
"""Return integer which represents atom NAME."""
args = ('winfo', 'atom') + self._displayof(displayof) + (name,)
- return getint(self.tk.call(args))
+ return self.tk.getint(self.tk.call(args))
def winfo_atomname(self, id, displayof=0):
"""Return name of atom with identifier ID."""
args = ('winfo', 'atomname') \
@@ -789,7 +795,7 @@ class Misc:
return self.tk.call(args)
def winfo_cells(self):
"""Return number of cells in the colormap for this widget."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'cells', self._w))
def winfo_children(self):
"""Return a list of all widgets which are children of this widget."""
@@ -820,22 +826,22 @@ class Misc:
return self._nametowidget(name)
def winfo_depth(self):
"""Return the number of bits per pixel."""
- return getint(self.tk.call('winfo', 'depth', self._w))
+ return self.tk.getint(self.tk.call('winfo', 'depth', self._w))
def winfo_exists(self):
"""Return true if this widget exists."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'exists', self._w))
def winfo_fpixels(self, number):
"""Return the number of pixels for the given distance NUMBER
(e.g. "3c") as float."""
- return getdouble(self.tk.call(
+ return self.tk.getdouble(self.tk.call(
'winfo', 'fpixels', self._w, number))
def winfo_geometry(self):
"""Return geometry string for this widget in the form "widthxheight+X+Y"."""
return self.tk.call('winfo', 'geometry', self._w)
def winfo_height(self):
"""Return height of this widget."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'height', self._w))
def winfo_id(self):
"""Return identifier ID for this widget."""
@@ -847,7 +853,7 @@ class Misc:
return self.tk.splitlist(self.tk.call(args))
def winfo_ismapped(self):
"""Return true if this widget is mapped."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'ismapped', self._w))
def winfo_manager(self):
"""Return the window mananger name for this widget."""
@@ -865,11 +871,11 @@ class Misc:
return self.tk.call(args)
def winfo_pixels(self, number):
"""Rounded integer value of winfo_fpixels."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'pixels', self._w, number))
def winfo_pointerx(self):
"""Return the x coordinate of the pointer on the root window."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'pointerx', self._w))
def winfo_pointerxy(self):
"""Return a tuple of x and y coordinates of the pointer on the root window."""
@@ -877,15 +883,15 @@ class Misc:
self.tk.call('winfo', 'pointerxy', self._w))
def winfo_pointery(self):
"""Return the y coordinate of the pointer on the root window."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'pointery', self._w))
def winfo_reqheight(self):
"""Return requested height of this widget."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'reqheight', self._w))
def winfo_reqwidth(self):
"""Return requested width of this widget."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'reqwidth', self._w))
def winfo_rgb(self, color):
"""Return tuple of decimal values for red, green, blue for
@@ -895,12 +901,12 @@ class Misc:
def winfo_rootx(self):
"""Return x coordinate of upper left corner of this widget on the
root window."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'rootx', self._w))
def winfo_rooty(self):
"""Return y coordinate of upper left corner of this widget on the
root window."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'rooty', self._w))
def winfo_screen(self):
"""Return the screen name of this widget."""
@@ -908,27 +914,27 @@ class Misc:
def winfo_screencells(self):
"""Return the number of the cells in the colormap of the screen
of this widget."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'screencells', self._w))
def winfo_screendepth(self):
"""Return the number of bits per pixel of the root window of the
screen of this widget."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'screendepth', self._w))
def winfo_screenheight(self):
"""Return the number of pixels of the height of the screen of this widget
in pixel."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'screenheight', self._w))
def winfo_screenmmheight(self):
"""Return the number of pixels of the height of the screen of
this widget in mm."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'screenmmheight', self._w))
def winfo_screenmmwidth(self):
"""Return the number of pixels of the width of the screen of
this widget in mm."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'screenmmwidth', self._w))
def winfo_screenvisual(self):
"""Return one of the strings directcolor, grayscale, pseudocolor,
@@ -938,7 +944,7 @@ class Misc:
def winfo_screenwidth(self):
"""Return the number of pixels of the width of the screen of
this widget in pixel."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'screenwidth', self._w))
def winfo_server(self):
"""Return information of the X-Server of the screen of this widget in
@@ -950,7 +956,7 @@ class Misc:
'winfo', 'toplevel', self._w))
def winfo_viewable(self):
"""Return true if the widget and all its higher ancestors are mapped."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'viewable', self._w))
def winfo_visual(self):
"""Return one of the strings directcolor, grayscale, pseudocolor,
@@ -982,37 +988,37 @@ class Misc:
"""Return the height of the virtual root window associated with this
widget in pixels. If there is no virtual root window return the
height of the screen."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'vrootheight', self._w))
def winfo_vrootwidth(self):
"""Return the width of the virtual root window associated with this
widget in pixel. If there is no virtual root window return the
width of the screen."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'vrootwidth', self._w))
def winfo_vrootx(self):
"""Return the x offset of the virtual root relative to the root
window of the screen of this widget."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'vrootx', self._w))
def winfo_vrooty(self):
"""Return the y offset of the virtual root relative to the root
window of the screen of this widget."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'vrooty', self._w))
def winfo_width(self):
"""Return the width of this widget."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'width', self._w))
def winfo_x(self):
"""Return the x coordinate of the upper left corner of this widget
in the parent."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'x', self._w))
def winfo_y(self):
"""Return the y coordinate of the upper left corner of this widget
in the parent."""
- return getint(
+ return self.tk.getint(
self.tk.call('winfo', 'y', self._w))
def update(self):
"""Enter event loop until all pending events have been processed by Tcl."""
@@ -1129,11 +1135,11 @@ class Misc:
def _getints(self, string):
"""Internal function."""
if string:
- return tuple(map(getint, self.tk.splitlist(string)))
+ return tuple(map(self.tk.getint, self.tk.splitlist(string)))
def _getdoubles(self, string):
"""Internal function."""
if string:
- return tuple(map(getdouble, self.tk.splitlist(string)))
+ return tuple(map(self.tk.getdouble, self.tk.splitlist(string)))
def _getboolean(self, string):
"""Internal function."""
if string:
@@ -1232,12 +1238,12 @@ class Misc:
if len(args) != len(self._subst_format): return args
getboolean = self.tk.getboolean
- getint = int
+ getint = self.tk.getint
def getint_event(s):
"""Tk changed behavior in 8.4.2, returning "??" rather more often."""
try:
- return int(s)
- except ValueError:
+ return getint(s)
+ except (ValueError, TclError):
return s
nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args
@@ -1281,7 +1287,7 @@ class Misc:
e.y_root = getint_event(Y)
try:
e.delta = getint(D)
- except ValueError:
+ except (ValueError, TclError):
e.delta = 0
return (e,)
def _report_exception(self):
@@ -1331,11 +1337,17 @@ class Misc:
self.configure({key: value})
def keys(self):
"""Return a list of all resource names of this widget."""
- return [x[0][1:] for x in
- self.tk.splitlist(self.tk.call(self._w, 'configure'))]
+ splitlist = self.tk.splitlist
+ return [splitlist(x)[0][1:] for x in
+ splitlist(self.tk.call(self._w, 'configure'))]
def __str__(self):
"""Return the window path name of this widget."""
return self._w
+
+ def __repr__(self):
+ return '<%s.%s object %s>' % (
+ self.__class__.__module__, self.__class__.__qualname__, self._w)
+
# Pack methods that apply to the master
_noarg_ = ['_noarg_']
def pack_propagate(self, flag=_noarg_):
@@ -1401,10 +1413,10 @@ class Misc:
if not svalue:
return None
elif '.' in svalue:
- return getdouble(svalue)
+ return self.tk.getdouble(svalue)
else:
- return getint(svalue)
- except ValueError:
+ return self.tk.getint(svalue)
+ except (ValueError, TclError):
pass
return value
@@ -1850,7 +1862,7 @@ class Tk(Misc, Wm):
import os
baseName = os.path.basename(sys.argv[0])
baseName, ext = os.path.splitext(baseName)
- if ext not in ('.py', '.pyc', '.pyo'):
+ if ext not in ('.py', '.pyc'):
baseName = baseName + ext
interactive = 0
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
@@ -2196,21 +2208,6 @@ class Button(Widget):
"""
Widget.__init__(self, master, 'button', cnf, kw)
- def tkButtonEnter(self, *dummy):
- self.tk.call('tkButtonEnter', self._w)
-
- def tkButtonLeave(self, *dummy):
- self.tk.call('tkButtonLeave', self._w)
-
- def tkButtonDown(self, *dummy):
- self.tk.call('tkButtonDown', self._w)
-
- def tkButtonUp(self, *dummy):
- self.tk.call('tkButtonUp', self._w)
-
- def tkButtonInvoke(self, *dummy):
- self.tk.call('tkButtonInvoke', self._w)
-
def flash(self):
"""Flash the button.
@@ -2297,17 +2294,17 @@ class Canvas(Widget, XView, YView):
def canvasx(self, screenx, gridspacing=None):
"""Return the canvas x coordinate of pixel position SCREENX rounded
to nearest multiple of GRIDSPACING units."""
- return getdouble(self.tk.call(
+ return self.tk.getdouble(self.tk.call(
self._w, 'canvasx', screenx, gridspacing))
def canvasy(self, screeny, gridspacing=None):
"""Return the canvas y coordinate of pixel position SCREENY rounded
to nearest multiple of GRIDSPACING units."""
- return getdouble(self.tk.call(
+ return self.tk.getdouble(self.tk.call(
self._w, 'canvasy', screeny, gridspacing))
def coords(self, *args):
"""Return a list of coordinates for the item given in ARGS."""
# XXX Should use _flatten on args
- return [getdouble(x) for x in
+ return [self.tk.getdouble(x) for x in
self.tk.splitlist(
self.tk.call((self._w, 'coords') + args))]
def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={})
@@ -2318,7 +2315,7 @@ class Canvas(Widget, XView, YView):
args = args[:-1]
else:
cnf = {}
- return getint(self.tk.call(
+ return self.tk.getint(self.tk.call(
self._w, 'create', itemType,
*(args + self._options(cnf, kw))))
def create_arc(self, *args, **kw):
@@ -2402,7 +2399,7 @@ class Canvas(Widget, XView, YView):
self.tk.call((self._w, 'icursor') + args)
def index(self, *args):
"""Return position of cursor as integer in item specified in ARGS."""
- return getint(self.tk.call((self._w, 'index') + args))
+ return self.tk.getint(self.tk.call((self._w, 'index') + args))
def insert(self, *args):
"""Insert TEXT in item TAGORID at position POS. ARGS must
be TAGORID POS TEXT."""
@@ -2504,7 +2501,7 @@ class Checkbutton(Widget):
self.tk.call(self._w, 'toggle')
class Entry(Widget, XView):
- """Entry widget which allows to display simple text."""
+ """Entry widget which allows displaying simple text."""
def __init__(self, master=None, cnf={}, **kw):
"""Construct an entry widget with the parent MASTER.
@@ -2528,7 +2525,7 @@ class Entry(Widget, XView):
self.tk.call(self._w, 'icursor', index)
def index(self, index):
"""Return position of cursor."""
- return getint(self.tk.call(
+ return self.tk.getint(self.tk.call(
self._w, 'index', index))
def insert(self, index, string):
"""Insert STRING at INDEX."""
@@ -2643,13 +2640,13 @@ class Listbox(Widget, XView, YView):
"""Return index of item identified with INDEX."""
i = self.tk.call(self._w, 'index', index)
if i == 'none': return None
- return getint(i)
+ return self.tk.getint(i)
def insert(self, index, *elements):
"""Insert ELEMENTS at INDEX."""
self.tk.call((self._w, 'insert', index) + elements)
def nearest(self, y):
"""Get index of item which is nearest to y coordinate Y."""
- return getint(self.tk.call(
+ return self.tk.getint(self.tk.call(
self._w, 'nearest', y))
def scan_mark(self, x, y):
"""Remember the current X, Y coordinates."""
@@ -2683,7 +2680,7 @@ class Listbox(Widget, XView, YView):
select_set = selection_set
def size(self):
"""Return the number of elements in the listbox."""
- return getint(self.tk.call(self._w, 'size'))
+ return self.tk.getint(self.tk.call(self._w, 'size'))
def itemcget(self, index, option):
"""Return the resource value for an ITEM and an OPTION."""
return self.tk.call(
@@ -2700,7 +2697,7 @@ class Listbox(Widget, XView, YView):
itemconfig = itemconfigure
class Menu(Widget):
- """Menu widget which allows to display menu bars, pull-down menus and pop-up menus."""
+ """Menu widget which allows displaying menu bars, pull-down menus and pop-up menus."""
def __init__(self, master=None, cnf={}, **kw):
"""Construct menu widget with the parent MASTER.
@@ -2709,35 +2706,15 @@ class Menu(Widget):
disabledforeground, fg, font, foreground, postcommand, relief,
selectcolor, takefocus, tearoff, tearoffcommand, title, type."""
Widget.__init__(self, master, 'menu', cnf, kw)
+ def tk_popup(self, x, y, entry=""):
+ """Post the menu at position X,Y with entry ENTRY."""
+ self.tk.call('tk_popup', self._w, x, y, entry)
def tk_bindForTraversal(self):
# obsolete since Tk 4.0
import warnings
warnings.warn('tk_bindForTraversal() does nothing and '
'will be removed in 3.6',
DeprecationWarning, stacklevel=2)
- def tk_mbPost(self):
- self.tk.call('tk_mbPost', self._w)
- def tk_mbUnpost(self):
- self.tk.call('tk_mbUnpost')
- def tk_traverseToMenu(self, char):
- self.tk.call('tk_traverseToMenu', self._w, char)
- def tk_traverseWithinMenu(self, char):
- self.tk.call('tk_traverseWithinMenu', self._w, char)
- def tk_getMenuButtons(self):
- return self.tk.call('tk_getMenuButtons', self._w)
- def tk_nextMenu(self, count):
- self.tk.call('tk_nextMenu', count)
- def tk_nextMenuEntry(self, count):
- self.tk.call('tk_nextMenuEntry', count)
- def tk_invokeMenu(self):
- self.tk.call('tk_invokeMenu', self._w)
- def tk_firstMenu(self):
- self.tk.call('tk_firstMenu', self._w)
- def tk_mbButtonDown(self):
- self.tk.call('tk_mbButtonDown', self._w)
- def tk_popup(self, x, y, entry=""):
- """Post the menu at position X,Y with entry ENTRY."""
- self.tk.call('tk_popup', self._w, x, y, entry)
def activate(self, index):
"""Activate entry at INDEX."""
self.tk.call(self._w, 'activate', index)
@@ -2805,7 +2782,7 @@ class Menu(Widget):
"""Return the index of a menu item identified by INDEX."""
i = self.tk.call(self._w, 'index', index)
if i == 'none': return None
- return getint(i)
+ return self.tk.getint(i)
def invoke(self, index):
"""Invoke a menu item identified by INDEX and execute
the associated command."""
@@ -2822,10 +2799,10 @@ class Menu(Widget):
def xposition(self, index): # new in Tk 8.5
"""Return the x-position of the leftmost pixel of the menu item
at INDEX."""
- return getint(self.tk.call(self._w, 'xposition', index))
+ return self.tk.getint(self.tk.call(self._w, 'xposition', index))
def yposition(self, index):
"""Return the y-position of the topmost pixel of the menu item at INDEX."""
- return getint(self.tk.call(
+ return self.tk.getint(self.tk.call(
self._w, 'yposition', index))
class Menubutton(Widget):
@@ -2881,9 +2858,9 @@ class Scale(Widget):
"""Get the current value as integer or float."""
value = self.tk.call(self._w, 'get')
try:
- return getint(value)
- except ValueError:
- return getdouble(value)
+ return self.tk.getint(value)
+ except (ValueError, TclError):
+ return self.tk.getdouble(value)
def set(self, value):
"""Set the value to VALUE."""
self.tk.call(self._w, 'set', value)
@@ -2910,19 +2887,23 @@ class Scrollbar(Widget):
relief, repeatdelay, repeatinterval, takefocus,
troughcolor, width."""
Widget.__init__(self, master, 'scrollbar', cnf, kw)
- def activate(self, index):
- """Display the element at INDEX with activebackground and activerelief.
- INDEX can be "arrow1","slider" or "arrow2"."""
- self.tk.call(self._w, 'activate', index)
+ def activate(self, index=None):
+ """Marks the element indicated by index as active.
+ The only index values understood by this method are "arrow1",
+ "slider", or "arrow2". If any other value is specified then no
+ element of the scrollbar will be active. If index is not specified,
+ the method returns the name of the element that is currently active,
+ or None if no element is active."""
+ return self.tk.call(self._w, 'activate', index) or None
def delta(self, deltax, deltay):
"""Return the fractional change of the scrollbar setting if it
would be moved by DELTAX or DELTAY pixels."""
- return getdouble(
+ return self.tk.getdouble(
self.tk.call(self._w, 'delta', deltax, deltay))
def fraction(self, x, y):
"""Return the fractional value which corresponds to a slider
position of X,Y."""
- return getdouble(self.tk.call(self._w, 'fraction', x, y))
+ return self.tk.getdouble(self.tk.call(self._w, 'fraction', x, y))
def identify(self, x, y):
"""Return the element under position X,Y as one of
"arrow1","slider","arrow2" or ""."""
@@ -2931,10 +2912,10 @@ class Scrollbar(Widget):
"""Return the current fractional values (upper and lower end)
of the slider position."""
return self._getdoubles(self.tk.call(self._w, 'get'))
- def set(self, *args):
+ def set(self, first, last):
"""Set the fractional values of the slider position (upper and
lower ends as value between 0 and 1)."""
- self.tk.call((self._w, 'set') + args)
+ self.tk.call(self._w, 'set', first, last)
@@ -2969,14 +2950,6 @@ class Text(Widget, XView, YView):
box of the visible part of the character at the given index."""
return self._getints(
self.tk.call(self._w, 'bbox', index)) or None
- def tk_textSelectTo(self, index):
- self.tk.call('tk_textSelectTo', self._w, index)
- def tk_textBackspace(self):
- self.tk.call('tk_textBackspace', self._w)
- def tk_textIndexCloser(self, a, b, c):
- self.tk.call('tk_textIndexCloser', self._w, a, b, c)
- def tk_textResetAnchor(self, index):
- self.tk.call('tk_textResetAnchor', self._w, index)
def compare(self, index1, op, index2):
"""Return whether between index INDEX1 and index INDEX2 the
relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""
@@ -3401,14 +3374,14 @@ class Image:
config = configure
def height(self):
"""Return the height of the image."""
- return getint(
+ return self.tk.getint(
self.tk.call('image', 'height', self.name))
def type(self):
"""Return the type of the imgage, e.g. "photo" or "bitmap"."""
return self.tk.call('image', 'type', self.name)
def width(self):
"""Return the width of the image."""
- return getint(
+ return self.tk.getint(
self.tk.call('image', 'width', self.name))
class PhotoImage(Image):
@@ -3434,16 +3407,20 @@ class PhotoImage(Image):
destImage = PhotoImage(master=self.tk)
self.tk.call(destImage, 'copy', self.name)
return destImage
- def zoom(self,x,y=''):
+ def zoom(self, x, y=''):
"""Return a new PhotoImage with the same image as this widget
- but zoom it with X and Y."""
+ but zoom it with a factor of x in the X direction and y in the Y
+ direction. If y is not given, the default value is the same as x.
+ """
destImage = PhotoImage(master=self.tk)
if y=='': y=x
self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
return destImage
- def subsample(self,x,y=''):
+ def subsample(self, x, y=''):
"""Return a new PhotoImage based on the same image as this widget
- but use only every Xth or Yth pixel."""
+ but use only every Xth or Yth pixel. If y is not given, the
+ default value is the same as x.
+ """
destImage = PhotoImage(master=self.tk)
if y=='': y=x
self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
@@ -3854,35 +3831,12 @@ class PanedWindow(Widget):
"""Returns an ordered list of the child panes."""
return self.tk.splitlist(self.tk.call(self._w, 'panes'))
-######################################################################
-# Extensions:
-
-class Studbutton(Button):
- def __init__(self, master=None, cnf={}, **kw):
- Widget.__init__(self, master, 'studbutton', cnf, kw)
- self.bind('<Any-Enter>', self.tkButtonEnter)
- self.bind('<Any-Leave>', self.tkButtonLeave)
- self.bind('<1>', self.tkButtonDown)
- self.bind('<ButtonRelease-1>', self.tkButtonUp)
-
-class Tributton(Button):
- def __init__(self, master=None, cnf={}, **kw):
- Widget.__init__(self, master, 'tributton', cnf, kw)
- self.bind('<Any-Enter>', self.tkButtonEnter)
- self.bind('<Any-Leave>', self.tkButtonLeave)
- self.bind('<1>', self.tkButtonDown)
- self.bind('<ButtonRelease-1>', self.tkButtonUp)
- self['fg'] = self['bg']
- self['activebackground'] = self['bg']
-
-######################################################################
# Test:
def _test():
root = Tk()
text = "This is Tcl/Tk version %s" % TclVersion
- if TclVersion >= 8.1:
- text += "\nThis should be a cedilla: \xe7"
+ text += "\nThis should be a cedilla: \xe7"
label = Label(root, text=text)
label.pack()
test = Button(root, text="Click me!",
diff --git a/Lib/tkinter/_fix.py b/Lib/tkinter/_fix.py
deleted file mode 100644
index fa88734..0000000
--- a/Lib/tkinter/_fix.py
+++ /dev/null
@@ -1,78 +0,0 @@
-import sys, os
-
-# Delay import _tkinter until we have set TCL_LIBRARY,
-# so that Tcl_FindExecutable has a chance to locate its
-# encoding directory.
-
-# Unfortunately, we cannot know the TCL_LIBRARY directory
-# if we don't know the tcl version, which we cannot find out
-# without import Tcl. Fortunately, Tcl will itself look in
-# <TCL_LIBRARY>\..\tcl<TCL_VERSION>, so anything close to
-# the real Tcl library will do.
-
-# Expand symbolic links on Vista
-try:
- import ctypes
- ctypes.windll.kernel32.GetFinalPathNameByHandleW
-except (ImportError, AttributeError):
- def convert_path(s):
- return s
-else:
- def convert_path(s):
- if isinstance(s, bytes):
- s = s.decode("mbcs")
- hdir = ctypes.windll.kernel32.\
- CreateFileW(s, 0x80, # FILE_READ_ATTRIBUTES
- 1, # FILE_SHARE_READ
- None, 3, # OPEN_EXISTING
- 0x02000000, # FILE_FLAG_BACKUP_SEMANTICS
- None)
- if hdir == -1:
- # Cannot open directory, give up
- return s
- buf = ctypes.create_unicode_buffer("", 32768)
- res = ctypes.windll.kernel32.\
- GetFinalPathNameByHandleW(hdir, buf, len(buf),
- 0) # VOLUME_NAME_DOS
- ctypes.windll.kernel32.CloseHandle(hdir)
- if res == 0:
- # Conversion failed (e.g. network location)
- return s
- s = buf[:res]
- # Ignore leading \\?\
- if s.startswith("\\\\?\\"):
- s = s[4:]
- if s.startswith("UNC"):
- s = "\\" + s[3:]
- return s
-
-prefix = os.path.join(sys.base_prefix,"tcl")
-if not os.path.exists(prefix):
- # devdir/externals/tcltk/lib
- prefix = os.path.join(sys.base_prefix, "externals", "tcltk", "lib")
- prefix = os.path.abspath(prefix)
-# if this does not exist, no further search is needed
-if os.path.exists(prefix):
- prefix = convert_path(prefix)
- if "TCL_LIBRARY" not in os.environ:
- for name in os.listdir(prefix):
- if name.startswith("tcl"):
- tcldir = os.path.join(prefix,name)
- if os.path.isdir(tcldir):
- os.environ["TCL_LIBRARY"] = tcldir
- # Compute TK_LIBRARY, knowing that it has the same version
- # as Tcl
- import _tkinter
- ver = str(_tkinter.TCL_VERSION)
- if "TK_LIBRARY" not in os.environ:
- v = os.path.join(prefix, 'tk'+ver)
- if os.path.exists(os.path.join(v, "tclIndex")):
- os.environ['TK_LIBRARY'] = v
- # We don't know the Tix version, so we must search the entire
- # directory
- if "TIX_LIBRARY" not in os.environ:
- for name in os.listdir(prefix):
- if name.startswith("tix"):
- tixdir = os.path.join(prefix,name)
- if os.path.isdir(tixdir):
- os.environ["TIX_LIBRARY"] = tixdir
diff --git a/Lib/tkinter/font.py b/Lib/tkinter/font.py
index b966732..1364257 100644
--- a/Lib/tkinter/font.py
+++ b/Lib/tkinter/font.py
@@ -112,8 +112,6 @@ class Font:
try:
if self.delete_font:
self._call("font", "delete", self.name)
- except (KeyboardInterrupt, SystemExit):
- raise
except Exception:
pass
@@ -153,7 +151,7 @@ class Font:
args = (text,)
if displayof:
args = ('-displayof', displayof, text)
- return int(self._call("font", "measure", self.name, *args))
+ return self._tk.getint(self._call("font", "measure", self.name, *args))
def metrics(self, *options, **kw):
"""Return font metrics.
@@ -166,13 +164,13 @@ class Font:
args = ('-displayof', displayof)
if options:
args = args + self._get(options)
- return int(
+ return self._tk.getint(
self._call("font", "metrics", self.name, *args))
else:
res = self._split(self._call("font", "metrics", self.name, *args))
options = {}
for i in range(0, len(res), 2):
- options[res[i][1:]] = int(res[i+1])
+ options[res[i][1:]] = self._tk.getint(res[i+1])
return options
diff --git a/Lib/tkinter/simpledialog.py b/Lib/tkinter/simpledialog.py
index 45302b4..a95f551 100644
--- a/Lib/tkinter/simpledialog.py
+++ b/Lib/tkinter/simpledialog.py
@@ -325,7 +325,7 @@ class _QueryDialog(Dialog):
class _QueryInteger(_QueryDialog):
errormessage = "Not an integer."
def getresult(self):
- return int(self.entry.get())
+ return self.getint(self.entry.get())
def askinteger(title, prompt, **kw):
'''get an integer from the user
@@ -344,7 +344,7 @@ def askinteger(title, prompt, **kw):
class _QueryFloat(_QueryDialog):
errormessage = "Not a floating point value."
def getresult(self):
- return float(self.entry.get())
+ return self.getdouble(self.entry.get())
def askfloat(title, prompt, **kw):
'''get a float from the user
diff --git a/Lib/tkinter/test/runtktests.py b/Lib/tkinter/test/runtktests.py
index ccb3755..dbe5e88 100644
--- a/Lib/tkinter/test/runtktests.py
+++ b/Lib/tkinter/test/runtktests.py
@@ -16,7 +16,7 @@ this_dir_path = os.path.abspath(os.path.dirname(__file__))
def is_package(path):
for name in os.listdir(path):
- if name in ('__init__.py', '__init__.pyc', '__init.pyo'):
+ if name in ('__init__.py', '__init__.pyc'):
return True
return False
diff --git a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py
index e42b1be..c645d43 100644
--- a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py
+++ b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py
@@ -12,6 +12,8 @@ requires('gui')
class PackTest(AbstractWidgetTest, unittest.TestCase):
+ test_keys = None
+
def create2(self):
pack = tkinter.Toplevel(self.root, name='pack')
pack.wm_geometry('300x200+0+0')
@@ -276,6 +278,8 @@ class PackTest(AbstractWidgetTest, unittest.TestCase):
class PlaceTest(AbstractWidgetTest, unittest.TestCase):
+ test_keys = None
+
def create2(self):
t = tkinter.Toplevel(self.root, width=300, height=200, bd=0)
t.wm_geometry('300x200+0+0')
@@ -478,6 +482,8 @@ class PlaceTest(AbstractWidgetTest, unittest.TestCase):
class GridTest(AbstractWidgetTest, unittest.TestCase):
+ test_keys = None
+
def tearDown(self):
cols, rows = self.root.grid_size()
for i in range(cols + 1):
diff --git a/Lib/tkinter/test/test_tkinter/test_misc.py b/Lib/tkinter/test/test_tkinter/test_misc.py
index d8de949..85ee2c7 100644
--- a/Lib/tkinter/test/test_tkinter/test_misc.py
+++ b/Lib/tkinter/test/test_tkinter/test_misc.py
@@ -7,6 +7,11 @@ support.requires('gui')
class MiscTest(AbstractTkTest, unittest.TestCase):
+ def test_repr(self):
+ t = tkinter.Toplevel(self.root, name='top')
+ f = tkinter.Frame(t, name='child')
+ self.assertEqual(repr(f), '<tkinter.Frame object .top.child>')
+
def test_tk_setPalette(self):
root = self.root
root.tk_setPalette('black')
diff --git a/Lib/tkinter/test/test_tkinter/test_variables.py b/Lib/tkinter/test/test_tkinter/test_variables.py
index 4b72943..abdce96 100644
--- a/Lib/tkinter/test/test_tkinter/test_variables.py
+++ b/Lib/tkinter/test/test_tkinter/test_variables.py
@@ -122,10 +122,10 @@ class TestIntVar(TestBase):
def test_invalid_value(self):
v = IntVar(self.root, name="name")
self.root.globalsetvar("name", "value")
- with self.assertRaises(ValueError):
+ with self.assertRaises((ValueError, TclError)):
v.get()
self.root.globalsetvar("name", "345.0")
- with self.assertRaises(ValueError):
+ with self.assertRaises((ValueError, TclError)):
v.get()
@@ -152,7 +152,7 @@ class TestDoubleVar(TestBase):
def test_invalid_value(self):
v = DoubleVar(self.root, name="name")
self.root.globalsetvar("name", "value")
- with self.assertRaises(ValueError):
+ with self.assertRaises((ValueError, TclError)):
v.get()
diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py
index 8be0371..c924d55 100644
--- a/Lib/tkinter/test/test_tkinter/test_widgets.py
+++ b/Lib/tkinter/test/test_tkinter/test_widgets.py
@@ -102,7 +102,7 @@ class FrameTest(AbstractToplevelTest, unittest.TestCase):
'background', 'borderwidth',
'class', 'colormap', 'container', 'cursor', 'height',
'highlightbackground', 'highlightcolor', 'highlightthickness',
- 'relief', 'takefocus', 'visual', 'width',
+ 'padx', 'pady', 'relief', 'takefocus', 'visual', 'width',
)
def create(self, **kwargs):
@@ -636,7 +636,7 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase):
'highlightbackground', 'highlightcolor', 'highlightthickness',
'insertbackground', 'insertborderwidth',
'insertofftime', 'insertontime', 'insertwidth',
- 'relief', 'scrollregion',
+ 'offset', 'relief', 'scrollregion',
'selectbackground', 'selectborderwidth', 'selectforeground',
'state', 'takefocus',
'xscrollcommand', 'xscrollincrement',
@@ -658,6 +658,15 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase):
widget = self.create()
self.checkBooleanParam(widget, 'confine')
+ def test_offset(self):
+ widget = self.create()
+ self.assertEqual(widget['offset'], '0,0')
+ self.checkParams(widget, 'offset',
+ 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
+ self.checkParam(widget, 'offset', '10,20')
+ self.checkParam(widget, 'offset', '#5,6')
+ self.checkInvalidParam(widget, 'offset', 'spam')
+
def test_scrollregion(self):
widget = self.create()
self.checkParam(widget, 'scrollregion', '0 0 200 150')
@@ -920,8 +929,9 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
sb = self.create()
for e in ('arrow1', 'slider', 'arrow2'):
sb.activate(e)
+ self.assertEqual(sb.activate(), e)
sb.activate('')
- self.assertRaises(TypeError, sb.activate)
+ self.assertIsNone(sb.activate())
self.assertRaises(TypeError, sb.activate, 'arrow1', 'arrow2')
def test_set(self):
@@ -931,8 +941,8 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
self.assertRaises(TclError, sb.set, 'abc', 'def')
self.assertRaises(TclError, sb.set, 0.6, 'def')
self.assertRaises(TclError, sb.set, 0.6, None)
- self.assertRaises(TclError, sb.set, 0.6)
- self.assertRaises(TclError, sb.set, 0.6, 0.7, 0.8)
+ self.assertRaises(TypeError, sb.set, 0.6)
+ self.assertRaises(TypeError, sb.set, 0.6, 0.7, 0.8)
@add_standard_options(StandardOptionsTests)
diff --git a/Lib/tkinter/test/test_ttk/test_extensions.py b/Lib/tkinter/test/test_ttk/test_extensions.py
index c3af06c..f33945c 100644
--- a/Lib/tkinter/test/test_ttk/test_extensions.py
+++ b/Lib/tkinter/test/test_ttk/test_extensions.py
@@ -70,17 +70,15 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
# variable initialization/passing
passed_expected = (('0', 0), (0, 0), (10, 10),
(-1, -1), (sys.maxsize + 1, sys.maxsize + 1))
- if self.wantobjects:
- passed_expected += ((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, x._variable.get)
+ self.assertRaises((ValueError, tkinter.TclError), x._variable.get)
x.destroy()
x = ttk.LabeledScale(self.root, from_=None)
- self.assertRaises(ValueError, x._variable.get)
+ self.assertRaises((ValueError, tkinter.TclError), x._variable.get)
x.destroy()
# variable should have its default value set to the from_ value
myvar = tkinter.DoubleVar(self.root, value=20)
diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py
index afd3230..c031351 100644
--- a/Lib/tkinter/test/test_ttk/test_widgets.py
+++ b/Lib/tkinter/test/test_ttk/test_widgets.py
@@ -187,7 +187,7 @@ class AbstractLabelTest(AbstractWidgetTest):
@add_standard_options(StandardTtkOptionsTests)
class LabelTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
- 'anchor', 'background',
+ 'anchor', 'background', 'borderwidth',
'class', 'compound', 'cursor', 'font', 'foreground',
'image', 'justify', 'padding', 'relief', 'state', 'style',
'takefocus', 'text', 'textvariable',
@@ -208,7 +208,8 @@ class LabelTest(AbstractLabelTest, unittest.TestCase):
class ButtonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'class', 'command', 'compound', 'cursor', 'default',
- 'image', 'state', 'style', 'takefocus', 'text', 'textvariable',
+ 'image', 'padding', 'state', 'style',
+ 'takefocus', 'text', 'textvariable',
'underline', 'width',
)
@@ -232,7 +233,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
'class', 'command', 'compound', 'cursor',
'image',
'offvalue', 'onvalue',
- 'state', 'style',
+ 'padding', 'state', 'style',
'takefocus', 'text', 'textvariable',
'underline', 'variable', 'width',
)
@@ -276,137 +277,10 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
-class ComboboxTest(AbstractWidgetTest, unittest.TestCase):
- OPTIONS = (
- 'class', 'cursor', 'exportselection', 'height',
- 'justify', 'postcommand', 'state', 'style',
- 'takefocus', 'textvariable', 'values', 'width',
- )
-
- def setUp(self):
- super().setUp()
- self.combo = self.create()
-
- def create(self, **kwargs):
- return ttk.Combobox(self.root, **kwargs)
-
- def test_height(self):
- widget = self.create()
- self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
-
- def test_state(self):
- widget = self.create()
- self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
-
- def _show_drop_down_listbox(self):
- width = self.combo.winfo_width()
- self.combo.event_generate('<ButtonPress-1>', x=width - 5, y=5)
- self.combo.event_generate('<ButtonRelease-1>', x=width - 5, y=5)
- self.combo.update_idletasks()
-
-
- def test_virtual_event(self):
- success = []
-
- self.combo['values'] = [1]
- self.combo.bind('<<ComboboxSelected>>',
- lambda evt: success.append(True))
- self.combo.pack()
- self.combo.wait_visibility()
-
- height = self.combo.winfo_height()
- self._show_drop_down_listbox()
- self.combo.update()
- self.combo.event_generate('<Return>')
- self.combo.update()
-
- self.assertTrue(success)
-
-
- def test_postcommand(self):
- success = []
-
- self.combo['postcommand'] = lambda: success.append(True)
- self.combo.pack()
- self.combo.wait_visibility()
-
- self._show_drop_down_listbox()
- self.assertTrue(success)
-
- # testing postcommand removal
- self.combo['postcommand'] = ''
- self._show_drop_down_listbox()
- self.assertEqual(len(success), 1)
-
-
- def test_values(self):
- def check_get_current(getval, currval):
- self.assertEqual(self.combo.get(), getval)
- self.assertEqual(self.combo.current(), currval)
-
- self.assertEqual(self.combo['values'],
- () if tcl_version < (8, 5) else '')
- check_get_current('', -1)
-
- self.checkParam(self.combo, 'values', 'mon tue wed thur',
- expected=('mon', 'tue', 'wed', 'thur'))
- self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur'))
- self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string'))
- self.checkParam(self.combo, 'values', '',
- expected='' if get_tk_patchlevel() < (8, 5, 10) else ())
-
- self.combo['values'] = ['a', 1, 'c']
-
- self.combo.set('c')
- check_get_current('c', 2)
-
- self.combo.current(0)
- check_get_current('a', 0)
-
- self.combo.set('d')
- check_get_current('d', -1)
-
- # testing values with empty string
- self.combo.set('')
- self.combo['values'] = (1, 2, '', 3)
- check_get_current('', 2)
-
- # testing values with empty string set through configure
- self.combo.configure(values=[1, '', 2])
- self.assertEqual(self.combo['values'],
- ('1', '', '2') if self.wantobjects else
- '1 {} 2')
-
- # testing values with spaces
- self.combo['values'] = ['a b', 'a\tb', 'a\nb']
- self.assertEqual(self.combo['values'],
- ('a b', 'a\tb', 'a\nb') if self.wantobjects else
- '{a b} {a\tb} {a\nb}')
-
- # testing values with special characters
- self.combo['values'] = [r'a\tb', '"a"', '} {']
- self.assertEqual(self.combo['values'],
- (r'a\tb', '"a"', '} {') if self.wantobjects else
- r'a\\tb {"a"} \}\ \{')
-
- # out of range
- self.assertRaises(tkinter.TclError, self.combo.current,
- len(self.combo['values']))
- # it expects an integer (or something that can be converted to int)
- self.assertRaises(tkinter.TclError, self.combo.current, '')
-
- # testing creating combobox with empty string in values
- combo2 = ttk.Combobox(self.root, values=[1, 2, ''])
- self.assertEqual(combo2['values'],
- ('1', '2', '') if self.wantobjects else '1 2 {}')
- combo2.destroy()
-
-
-@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
class EntryTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'background', 'class', 'cursor',
- 'exportselection', 'font',
+ 'exportselection', 'font', 'foreground',
'invalidcommand', 'justify',
'show', 'state', 'style', 'takefocus', 'textvariable',
'validate', 'validatecommand', 'width', 'xscrollcommand',
@@ -535,6 +409,132 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class ComboboxTest(EntryTest, unittest.TestCase):
+ OPTIONS = (
+ 'background', 'class', 'cursor', 'exportselection',
+ 'font', 'foreground', 'height', 'invalidcommand',
+ 'justify', 'postcommand', 'show', 'state', 'style',
+ 'takefocus', 'textvariable',
+ 'validate', 'validatecommand', 'values',
+ 'width', 'xscrollcommand',
+ )
+
+ def setUp(self):
+ super().setUp()
+ self.combo = self.create()
+
+ def create(self, **kwargs):
+ return ttk.Combobox(self.root, **kwargs)
+
+ def test_height(self):
+ widget = self.create()
+ self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
+
+ def _show_drop_down_listbox(self):
+ width = self.combo.winfo_width()
+ self.combo.event_generate('<ButtonPress-1>', x=width - 5, y=5)
+ self.combo.event_generate('<ButtonRelease-1>', x=width - 5, y=5)
+ self.combo.update_idletasks()
+
+
+ def test_virtual_event(self):
+ success = []
+
+ self.combo['values'] = [1]
+ self.combo.bind('<<ComboboxSelected>>',
+ lambda evt: success.append(True))
+ self.combo.pack()
+ self.combo.wait_visibility()
+
+ height = self.combo.winfo_height()
+ self._show_drop_down_listbox()
+ self.combo.update()
+ self.combo.event_generate('<Return>')
+ self.combo.update()
+
+ self.assertTrue(success)
+
+
+ def test_postcommand(self):
+ success = []
+
+ self.combo['postcommand'] = lambda: success.append(True)
+ self.combo.pack()
+ self.combo.wait_visibility()
+
+ self._show_drop_down_listbox()
+ self.assertTrue(success)
+
+ # testing postcommand removal
+ self.combo['postcommand'] = ''
+ self._show_drop_down_listbox()
+ self.assertEqual(len(success), 1)
+
+
+ def test_values(self):
+ def check_get_current(getval, currval):
+ self.assertEqual(self.combo.get(), getval)
+ self.assertEqual(self.combo.current(), currval)
+
+ self.assertEqual(self.combo['values'],
+ () if tcl_version < (8, 5) else '')
+ check_get_current('', -1)
+
+ self.checkParam(self.combo, 'values', 'mon tue wed thur',
+ expected=('mon', 'tue', 'wed', 'thur'))
+ self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur'))
+ self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string'))
+ self.checkParam(self.combo, 'values', '',
+ expected='' if get_tk_patchlevel() < (8, 5, 10) else ())
+
+ self.combo['values'] = ['a', 1, 'c']
+
+ self.combo.set('c')
+ check_get_current('c', 2)
+
+ self.combo.current(0)
+ check_get_current('a', 0)
+
+ self.combo.set('d')
+ check_get_current('d', -1)
+
+ # testing values with empty string
+ self.combo.set('')
+ self.combo['values'] = (1, 2, '', 3)
+ check_get_current('', 2)
+
+ # testing values with empty string set through configure
+ self.combo.configure(values=[1, '', 2])
+ self.assertEqual(self.combo['values'],
+ ('1', '', '2') if self.wantobjects else
+ '1 {} 2')
+
+ # testing values with spaces
+ self.combo['values'] = ['a b', 'a\tb', 'a\nb']
+ self.assertEqual(self.combo['values'],
+ ('a b', 'a\tb', 'a\nb') if self.wantobjects else
+ '{a b} {a\tb} {a\nb}')
+
+ # testing values with special characters
+ self.combo['values'] = [r'a\tb', '"a"', '} {']
+ self.assertEqual(self.combo['values'],
+ (r'a\tb', '"a"', '} {') if self.wantobjects else
+ r'a\\tb {"a"} \}\ \{')
+
+ # out of range
+ self.assertRaises(tkinter.TclError, self.combo.current,
+ len(self.combo['values']))
+ # it expects an integer (or something that can be converted to int)
+ self.assertRaises(tkinter.TclError, self.combo.current, '')
+
+ # testing creating combobox with empty string in values
+ combo2 = ttk.Combobox(self.root, values=[1, 2, ''])
+ self.assertEqual(combo2['values'],
+ ('1', '2', '') if self.wantobjects else '1 2 {}')
+ combo2.destroy()
+
+
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
'class', 'cursor', 'height',
@@ -674,7 +674,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'class', 'command', 'compound', 'cursor',
'image',
- 'state', 'style',
+ 'padding', 'state', 'style',
'takefocus', 'text', 'textvariable',
'underline', 'value', 'variable', 'width',
)
@@ -724,7 +724,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
OPTIONS = (
'class', 'compound', 'cursor', 'direction',
- 'image', 'menu', 'state', 'style',
+ 'image', 'menu', 'padding', 'state', 'style',
'takefocus', 'text', 'textvariable',
'underline', 'width',
)
@@ -902,7 +902,7 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
class NotebookTest(AbstractWidgetTest, unittest.TestCase):
OPTIONS = (
- 'class', 'cursor', 'height', 'padding', 'style', 'takefocus',
+ 'class', 'cursor', 'height', 'padding', 'style', 'takefocus', 'width',
)
def setUp(self):
diff --git a/Lib/tkinter/test/widget_tests.py b/Lib/tkinter/test/widget_tests.py
index 779538d..75a068f 100644
--- a/Lib/tkinter/test/widget_tests.py
+++ b/Lib/tkinter/test/widget_tests.py
@@ -206,6 +206,33 @@ class AbstractWidgetTest(AbstractTkTest):
break
+ def test_keys(self):
+ widget = self.create()
+ keys = widget.keys()
+ # XXX
+ if not isinstance(widget, Scale):
+ self.assertEqual(sorted(keys), sorted(widget.configure()))
+ for k in keys:
+ widget[k]
+ # Test if OPTIONS contains all keys
+ if test.support.verbose:
+ aliases = {
+ 'bd': 'borderwidth',
+ 'bg': 'background',
+ 'fg': 'foreground',
+ 'invcmd': 'invalidcommand',
+ 'vcmd': 'validatecommand',
+ }
+ keys = set(keys)
+ expected = set(self.OPTIONS)
+ for k in sorted(keys - expected):
+ if not (k in aliases and
+ aliases[k] in keys and
+ aliases[k] in expected):
+ print('%s.OPTIONS doesn\'t contain "%s"' %
+ (self.__class__.__name__, k))
+
+
class StandardOptionsTests:
STANDARD_OPTIONS = (
'activebackground', 'activeborderwidth', 'activeforeground', 'anchor',