Skip to content

Commit b84f029

Browse files
Issue #27319: Methods selection_set(), selection_add(), selection_remove()
and selection_toggle() of ttk.TreeView now allow to pass multiple items as multiple arguments instead of passing them as a tuple. Deprecated undocumented ability of calling the selection() method with arguments.
1 parent 6c85091 commit b84f029

3 files changed

Lines changed: 90 additions & 20 deletions

File tree

Lib/tkinter/test/test_ttk/test_widgets.py

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,7 @@ def test_insert_item(self):
14871487

14881488

14891489
def test_selection(self):
1490+
self.assertRaises(TypeError, self.tv.selection, 'spam')
14901491
# item 'none' doesn't exist
14911492
self.assertRaises(tkinter.TclError, self.tv.selection_set, 'none')
14921493
self.assertRaises(tkinter.TclError, self.tv.selection_add, 'none')
@@ -1500,25 +1501,31 @@ def test_selection(self):
15001501
c3 = self.tv.insert(item1, 'end')
15011502
self.assertEqual(self.tv.selection(), ())
15021503

1503-
self.tv.selection_set((c1, item2))
1504+
self.tv.selection_set(c1, item2)
15041505
self.assertEqual(self.tv.selection(), (c1, item2))
15051506
self.tv.selection_set(c2)
15061507
self.assertEqual(self.tv.selection(), (c2,))
15071508

1508-
self.tv.selection_add((c1, item2))
1509+
self.tv.selection_add(c1, item2)
15091510
self.assertEqual(self.tv.selection(), (c1, c2, item2))
15101511
self.tv.selection_add(item1)
15111512
self.assertEqual(self.tv.selection(), (item1, c1, c2, item2))
1513+
self.tv.selection_add()
1514+
self.assertEqual(self.tv.selection(), (item1, c1, c2, item2))
15121515

1513-
self.tv.selection_remove((item1, c3))
1516+
self.tv.selection_remove(item1, c3)
15141517
self.assertEqual(self.tv.selection(), (c1, c2, item2))
15151518
self.tv.selection_remove(c2)
15161519
self.assertEqual(self.tv.selection(), (c1, item2))
1520+
self.tv.selection_remove()
1521+
self.assertEqual(self.tv.selection(), (c1, item2))
15171522

1518-
self.tv.selection_toggle((c1, c3))
1523+
self.tv.selection_toggle(c1, c3)
15191524
self.assertEqual(self.tv.selection(), (c3, item2))
15201525
self.tv.selection_toggle(item2)
15211526
self.assertEqual(self.tv.selection(), (c3,))
1527+
self.tv.selection_toggle()
1528+
self.assertEqual(self.tv.selection(), (c3,))
15221529

15231530
self.tv.insert('', 'end', id='with spaces')
15241531
self.tv.selection_set('with spaces')
@@ -1536,6 +1543,40 @@ def test_selection(self):
15361543
self.tv.selection_set(b'bytes\xe2\x82\xac')
15371544
self.assertEqual(self.tv.selection(), ('bytes\xe2\x82\xac',))
15381545

1546+
self.tv.selection_set()
1547+
self.assertEqual(self.tv.selection(), ())
1548+
1549+
# Old interface
1550+
self.tv.selection_set((c1, item2))
1551+
self.assertEqual(self.tv.selection(), (c1, item2))
1552+
self.tv.selection_add((c1, item1))
1553+
self.assertEqual(self.tv.selection(), (item1, c1, item2))
1554+
self.tv.selection_remove((item1, c3))
1555+
self.assertEqual(self.tv.selection(), (c1, item2))
1556+
self.tv.selection_toggle((c1, c3))
1557+
self.assertEqual(self.tv.selection(), (c3, item2))
1558+
1559+
if sys.version_info >= (3, 7):
1560+
import warnings
1561+
warnings.warn(
1562+
'Deprecated API of Treeview.selection() should be removed')
1563+
self.tv.selection_set()
1564+
self.assertEqual(self.tv.selection(), ())
1565+
with self.assertWarns(DeprecationWarning):
1566+
self.tv.selection('set', (c1, item2))
1567+
self.assertEqual(self.tv.selection(), (c1, item2))
1568+
with self.assertWarns(DeprecationWarning):
1569+
self.tv.selection('add', (c1, item1))
1570+
self.assertEqual(self.tv.selection(), (item1, c1, item2))
1571+
with self.assertWarns(DeprecationWarning):
1572+
self.tv.selection('remove', (item1, c3))
1573+
self.assertEqual(self.tv.selection(), (c1, item2))
1574+
with self.assertWarns(DeprecationWarning):
1575+
self.tv.selection('toggle', (c1, c3))
1576+
self.assertEqual(self.tv.selection(), (c3, item2))
1577+
with self.assertWarns(DeprecationWarning):
1578+
selection = self.tv.selection(None)
1579+
self.assertEqual(selection, (c3, item2))
15391580

15401581
def test_set(self):
15411582
self.tv['columns'] = ['A', 'B']

Lib/tkinter/ttk.py

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import tkinter
2929
from tkinter import _flatten, _join, _stringify, _splitdict
3030

31+
_sentinel = object()
32+
3133
# Verify if Tk is new enough to not need the Tile package
3234
_REQUIRE_TILE = True if tkinter.TkVersion < 8.5 else False
3335

@@ -1394,31 +1396,53 @@ def see(self, item):
13941396
self.tk.call(self._w, "see", item)
13951397

13961398

1397-
def selection(self, selop=None, items=None):
1398-
"""If selop is not specified, returns selected items."""
1399-
if isinstance(items, (str, bytes)):
1400-
items = (items,)
1399+
def selection(self, selop=_sentinel, items=None):
1400+
"""Returns the tuple of selected items."""
1401+
if selop is _sentinel:
1402+
selop = None
1403+
elif selop is None:
1404+
import warnings
1405+
warnings.warn(
1406+
"The selop=None argument of selection() is deprecated "
1407+
"and will be removed in Python 3.7",
1408+
DeprecationWarning, 3)
1409+
elif selop in ('set', 'add', 'remove', 'toggle'):
1410+
import warnings
1411+
warnings.warn(
1412+
"The selop argument of selection() is deprecated "
1413+
"and will be removed in Python 3.7, "
1414+
"use selection_%s() instead" % (selop,),
1415+
DeprecationWarning, 3)
1416+
else:
1417+
raise TypeError('Unsupported operation')
14011418
return self.tk.splitlist(self.tk.call(self._w, "selection", selop, items))
14021419

14031420

1404-
def selection_set(self, items):
1405-
"""items becomes the new selection."""
1406-
self.selection("set", items)
1421+
def _selection(self, selop, items):
1422+
if len(items) == 1 and isinstance(items[0], (tuple, list)):
1423+
items = items[0]
1424+
1425+
self.tk.call(self._w, "selection", selop, items)
1426+
1427+
1428+
def selection_set(self, *items):
1429+
"""The specified items becomes the new selection."""
1430+
self._selection("set", items)
14071431

14081432

1409-
def selection_add(self, items):
1410-
"""Add items to the selection."""
1411-
self.selection("add", items)
1433+
def selection_add(self, *items):
1434+
"""Add all of the specified items to the selection."""
1435+
self._selection("add", items)
14121436

14131437

1414-
def selection_remove(self, items):
1415-
"""Remove items from the selection."""
1416-
self.selection("remove", items)
1438+
def selection_remove(self, *items):
1439+
"""Remove all of the specified items from the selection."""
1440+
self._selection("remove", items)
14171441

14181442

1419-
def selection_toggle(self, items):
1420-
"""Toggle the selection state of each item in items."""
1421-
self.selection("toggle", items)
1443+
def selection_toggle(self, *items):
1444+
"""Toggle the selection state of each specified item."""
1445+
self._selection("toggle", items)
14221446

14231447

14241448
def set(self, item, column=None, value=None):

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ What's New in Python 3.6.0 alpha 3
1010
Library
1111
-------
1212

13+
- Issue #27319: Methods selection_set(), selection_add(), selection_remove()
14+
and selection_toggle() of ttk.TreeView now allow to pass multiple items as
15+
multiple arguments instead of passing them as a tuple. Deprecated
16+
undocumented ability of calling the selection() method with arguments.
17+
1318
- Issue #27079: Fixed curses.ascii functions isblank(), iscntrl() and ispunct().
1419

1520
- Issue #27294: Numerical state in the repr for Tkinter event objects is now

0 commit comments

Comments
 (0)