Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
a48e78a0
Commit
a48e78a0
authored
Feb 08, 2018
by
Alan D Moore
Committed by
Serhiy Storchaka
Feb 09, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-32585: Add tkinter.ttk.Spinbox. (#5221)
parent
32921f90
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
300 additions
and
7 deletions
+300
-7
Doc/library/tkinter.ttk.rst
Doc/library/tkinter.ttk.rst
+86
-5
Doc/whatsnew/3.7.rst
Doc/whatsnew/3.7.rst
+6
-0
Lib/tkinter/test/test_ttk/test_widgets.py
Lib/tkinter/test/test_ttk/test_widgets.py
+178
-1
Lib/tkinter/ttk.py
Lib/tkinter/ttk.py
+28
-1
Misc/ACKS
Misc/ACKS
+1
-0
Misc/NEWS.d/next/Library/2018-01-18-13-09-00.bpo-32585.qpeijr.rst
...S.d/next/Library/2018-01-18-13-09-00.bpo-32585.qpeijr.rst
+1
-0
No files found.
Doc/library/tkinter.ttk.rst
View file @
a48e78a0
...
@@ -66,13 +66,13 @@ for improved styling effects.
...
@@ -66,13 +66,13 @@ for improved styling effects.
Ttk Widgets
Ttk Widgets
-----------
-----------
Ttk comes with 1
7 widgets, eleven
of which already existed in tkinter:
Ttk comes with 1
8 widgets, twelve
of which already existed in tkinter:
:class:`Button`, :class:`Checkbutton`, :class:`Entry`, :class:`Frame`,
:class:`Button`, :class:`Checkbutton`, :class:`Entry`, :class:`Frame`,
:class:`Label`, :class:`LabelFrame`, :class:`Menubutton`, :class:`PanedWindow`,
:class:`Label`, :class:`LabelFrame`, :class:`Menubutton`, :class:`PanedWindow`,
:class:`Radiobutton`, :class:`Scale`
and :class:`Scrollbar`. The other six are
:class:`Radiobutton`, :class:`Scale`
, :class:`Scrollbar`, and :class:`Spinbox`.
new: :class:`Combobox`, :class:`Notebook`, :class:`Progressbar
`,
The other six are new: :class:`Combobox`, :class:`Notebook
`,
:class:`
Separator`, :class:`Sizegrip` and :class:`Treeview`. And all them are
:class:`
Progressbar`, :class:`Separator`, :class:`Sizegrip` and
subclasses of :class:`Widget`.
:class:`Treeview`. And all them are
subclasses of :class:`Widget`.
Using the Ttk widgets gives the application an improved look and feel.
Using the Ttk widgets gives the application an improved look and feel.
As discussed above, there are differences in how the styling is coded.
As discussed above, there are differences in how the styling is coded.
...
@@ -381,6 +381,87 @@ ttk.Combobox
...
@@ -381,6 +381,87 @@ ttk.Combobox
Sets the value of the combobox to *value*.
Sets the value of the combobox to *value*.
Spinbox
-------
The :class:`ttk.Spinbox` widget is a :class:`ttk.Entry` enhanced with increment
and decrement arrows. It can be used for numbers or lists of string values.
This widget is a subclass of :class:`Entry`.
Besides the methods inherited from :class:`Widget`: :meth:`Widget.cget`,
:meth:`Widget.configure`, :meth:`Widget.identify`, :meth:`Widget.instate`
and :meth:`Widget.state`, and the following inherited from :class:`Entry`:
:meth:`Entry.bbox`, :meth:`Entry.delete`, :meth:`Entry.icursor`,
:meth:`Entry.index`, :meth:`Entry.insert`, :meth:`Entry.xview`,
it has some other methods, described at :class:`ttk.Spinbox`.
Options
^^^^^^^
This widget accepts the following specific options:
.. tabularcolumns:: |l|L|
+----------------------+------------------------------------------------------+
| Option | Description |
+======================+======================================================+
| from | Float value. If set, this is the minimum value to |
| | which the decrement button will decrement. Must be |
| | spelled as ``from_`` when used as an argument, since |
| | ``from`` is a Python keyword. |
+----------------------+------------------------------------------------------+
| to | Float value. If set, this is the maximum value to |
| | which the increment button will increment. |
+----------------------+------------------------------------------------------+
| increment | Float value. Specifies the amount which the |
| | increment/decrement buttons change the |
| | value. Defaults to 1.0. |
+----------------------+------------------------------------------------------+
| values | Sequence of string or float values. If specified, |
| | the increment/decrement buttons will cycle through |
| | the items in this sequence rather than incrementing |
| | or decrementing numbers. |
| | |
+----------------------+------------------------------------------------------+
| wrap | Boolean value. If ``True``, increment and decrement |
| | buttons will cycle from the ``to`` value to the |
| | ``from`` value or the ``from`` value to the ``to`` |
| | value, respectively. |
+----------------------+------------------------------------------------------+
| format | String value. This specifies the format of numbers |
| | set by the increment/decrement buttons. It must be |
| | in the form "%W.Pf", where W is the padded width of |
| | the value, P is the precision, and '%' and 'f' are |
| | literal. |
+----------------------+------------------------------------------------------+
| command | Python callable. Will be called with no arguments |
| | whenever either of the increment or decrement buttons|
| | are pressed. |
| | |
+----------------------+------------------------------------------------------+
Virtual events
^^^^^^^^^^^^^^
The spinbox widget generates an **<<Increment>>** virtual event when the
user presses <Up>, and a **<<Decrement>>** virtual event when the user
presses <Down>.
ttk.Spinbox
^^^^^^^^^^^^
.. class:: Spinbox
.. method:: get()
Returns the current value of the spinbox.
.. method:: set(value)
Sets the value of the spinbox to *value*.
Notebook
Notebook
--------
--------
...
...
Doc/whatsnew/3.7.rst
View file @
a48e78a0
...
@@ -663,6 +663,12 @@ Added :attr:`sys.flags.dev_mode` flag for the new development mode.
...
@@ -663,6 +663,12 @@ Added :attr:`sys.flags.dev_mode` flag for the new development mode.
Deprecated :func:`sys.set_coroutine_wrapper` and
Deprecated :func:`sys.set_coroutine_wrapper` and
:func:`sys.get_coroutine_wrapper`.
:func:`sys.get_coroutine_wrapper`.
tkinter
-------
Added :class:`tkinter.ttk.Spinbox`.
time
time
----
----
...
...
Lib/tkinter/test/test_ttk/test_widgets.py
View file @
a48e78a0
...
@@ -1105,6 +1105,183 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase):
...
@@ -1105,6 +1105,183 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase):
self
.
nb
.
event_generate
(
'<Alt-a>'
)
self
.
nb
.
event_generate
(
'<Alt-a>'
)
self
.
assertEqual
(
self
.
nb
.
select
(),
str
(
self
.
child1
))
self
.
assertEqual
(
self
.
nb
.
select
(),
str
(
self
.
child1
))
@
add_standard_options
(
IntegerSizeTests
,
StandardTtkOptionsTests
)
class
SpinboxTest
(
EntryTest
,
unittest
.
TestCase
):
OPTIONS
=
(
'background'
,
'class'
,
'command'
,
'cursor'
,
'exportselection'
,
'font'
,
'foreground'
,
'format'
,
'from'
,
'increment'
,
'invalidcommand'
,
'justify'
,
'show'
,
'state'
,
'style'
,
'takefocus'
,
'textvariable'
,
'to'
,
'validate'
,
'validatecommand'
,
'values'
,
'width'
,
'wrap'
,
'xscrollcommand'
,
)
def
setUp
(
self
):
super
().
setUp
()
self
.
spin
=
self
.
create
()
self
.
spin
.
pack
()
def
create
(
self
,
**
kwargs
):
return
ttk
.
Spinbox
(
self
.
root
,
**
kwargs
)
def
_click_increment_arrow
(
self
):
width
=
self
.
spin
.
winfo_width
()
height
=
self
.
spin
.
winfo_height
()
x
=
width
-
5
y
=
height
//
2
-
5
self
.
spin
.
event_generate
(
'<ButtonPress-1>'
,
x
=
x
,
y
=
y
)
self
.
spin
.
event_generate
(
'<ButtonRelease-1>'
,
x
=
x
,
y
=
y
)
self
.
spin
.
update_idletasks
()
def
_click_decrement_arrow
(
self
):
width
=
self
.
spin
.
winfo_width
()
height
=
self
.
spin
.
winfo_height
()
x
=
width
-
5
y
=
height
//
2
+
4
self
.
spin
.
event_generate
(
'<ButtonPress-1>'
,
x
=
x
,
y
=
y
)
self
.
spin
.
event_generate
(
'<ButtonRelease-1>'
,
x
=
x
,
y
=
y
)
self
.
spin
.
update_idletasks
()
def
test_command
(
self
):
success
=
[]
self
.
spin
[
'command'
]
=
lambda
:
success
.
append
(
True
)
self
.
spin
.
update
()
self
.
_click_increment_arrow
()
self
.
spin
.
update
()
self
.
assertTrue
(
success
)
self
.
_click_decrement_arrow
()
self
.
assertEqual
(
len
(
success
),
2
)
# testing postcommand removal
self
.
spin
[
'command'
]
=
''
self
.
spin
.
update_idletasks
()
self
.
_click_increment_arrow
()
self
.
_click_decrement_arrow
()
self
.
spin
.
update
()
self
.
assertEqual
(
len
(
success
),
2
)
def
test_to
(
self
):
self
.
spin
[
'from'
]
=
0
self
.
spin
[
'to'
]
=
5
self
.
spin
.
set
(
4
)
self
.
spin
.
update
()
self
.
_click_increment_arrow
()
# 5
self
.
assertEqual
(
self
.
spin
.
get
(),
'5'
)
self
.
_click_increment_arrow
()
# 5
self
.
assertEqual
(
self
.
spin
.
get
(),
'5'
)
def
test_from
(
self
):
self
.
spin
[
'from'
]
=
1
self
.
spin
[
'to'
]
=
10
self
.
spin
.
set
(
2
)
self
.
spin
.
update
()
self
.
_click_decrement_arrow
()
# 1
self
.
assertEqual
(
self
.
spin
.
get
(),
'1'
)
self
.
_click_decrement_arrow
()
# 1
self
.
assertEqual
(
self
.
spin
.
get
(),
'1'
)
def
test_increment
(
self
):
self
.
spin
[
'from'
]
=
0
self
.
spin
[
'to'
]
=
10
self
.
spin
[
'increment'
]
=
4
self
.
spin
.
set
(
1
)
self
.
spin
.
update
()
self
.
_click_increment_arrow
()
# 5
self
.
assertEqual
(
self
.
spin
.
get
(),
'5'
)
self
.
spin
[
'increment'
]
=
2
self
.
spin
.
update
()
self
.
_click_decrement_arrow
()
# 3
self
.
assertEqual
(
self
.
spin
.
get
(),
'3'
)
def
test_format
(
self
):
self
.
spin
.
set
(
1
)
self
.
spin
[
'format'
]
=
'%10.3f'
self
.
spin
.
update
()
self
.
_click_increment_arrow
()
value
=
self
.
spin
.
get
()
self
.
assertEqual
(
len
(
value
),
10
)
self
.
assertEqual
(
value
.
index
(
'.'
),
6
)
self
.
spin
[
'format'
]
=
''
self
.
spin
.
update
()
self
.
_click_increment_arrow
()
value
=
self
.
spin
.
get
()
self
.
assertTrue
(
'.'
not
in
value
)
self
.
assertEqual
(
len
(
value
),
1
)
def
test_wrap
(
self
):
self
.
spin
[
'to'
]
=
10
self
.
spin
[
'from'
]
=
1
self
.
spin
.
set
(
1
)
self
.
spin
[
'wrap'
]
=
True
self
.
spin
.
update
()
self
.
_click_decrement_arrow
()
self
.
assertEqual
(
self
.
spin
.
get
(),
'10'
)
self
.
_click_increment_arrow
()
self
.
assertEqual
(
self
.
spin
.
get
(),
'1'
)
self
.
spin
[
'wrap'
]
=
False
self
.
spin
.
update
()
self
.
_click_decrement_arrow
()
self
.
assertEqual
(
self
.
spin
.
get
(),
'1'
)
def
test_values
(
self
):
self
.
assertEqual
(
self
.
spin
[
'values'
],
()
if
tcl_version
<
(
8
,
5
)
else
''
)
self
.
checkParam
(
self
.
spin
,
'values'
,
'mon tue wed thur'
,
expected
=
(
'mon'
,
'tue'
,
'wed'
,
'thur'
))
self
.
checkParam
(
self
.
spin
,
'values'
,
(
'mon'
,
'tue'
,
'wed'
,
'thur'
))
self
.
checkParam
(
self
.
spin
,
'values'
,
(
42
,
3.14
,
''
,
'any string'
))
self
.
checkParam
(
self
.
spin
,
'values'
,
''
,
expected
=
''
if
get_tk_patchlevel
()
<
(
8
,
5
,
10
)
else
()
)
self
.
spin
[
'values'
]
=
[
'a'
,
1
,
'c'
]
# test incrementing / decrementing values
self
.
spin
.
set
(
'a'
)
self
.
spin
.
update
()
self
.
_click_increment_arrow
()
self
.
assertEqual
(
self
.
spin
.
get
(),
'1'
)
self
.
_click_decrement_arrow
()
self
.
assertEqual
(
self
.
spin
.
get
(),
'a'
)
# testing values with empty string set through configure
self
.
spin
.
configure
(
values
=
[
1
,
''
,
2
])
self
.
assertEqual
(
self
.
spin
[
'values'
],
(
'1'
,
''
,
'2'
)
if
self
.
wantobjects
else
'1 {} 2'
)
# testing values with spaces
self
.
spin
[
'values'
]
=
[
'a b'
,
'a
\
t
b'
,
'a
\
n
b'
]
self
.
assertEqual
(
self
.
spin
[
'values'
],
(
'a b'
,
'a
\
t
b'
,
'a
\
n
b'
)
if
self
.
wantobjects
else
'{a b} {a
\
t
b} {a
\
n
b}'
)
# testing values with special characters
self
.
spin
[
'values'
]
=
[
r'a\tb'
,
'"a"'
,
'} {'
]
self
.
assertEqual
(
self
.
spin
[
'values'
],
(
r'a\tb'
,
'"a"'
,
'} {'
)
if
self
.
wantobjects
else
r'a\\tb {"a"} \
}
\ \
{
')
# testing creating spinbox with empty string in values
spin2 = ttk.Spinbox(self.root, values=[1, 2, ''])
self.assertEqual(spin2['
values
'],
('
1
', '
2
', '') if self.wantobjects else '
1
2
{}
')
spin2.destroy()
@add_standard_options(StandardTtkOptionsTests)
@add_standard_options(StandardTtkOptionsTests)
class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
...
@@ -1679,7 +1856,7 @@ tests_gui = (
...
@@ -1679,7 +1856,7 @@ tests_gui = (
FrameTest
,
LabelFrameTest
,
LabelTest
,
MenubuttonTest
,
FrameTest
,
LabelFrameTest
,
LabelTest
,
MenubuttonTest
,
NotebookTest
,
PanedWindowTest
,
ProgressbarTest
,
NotebookTest
,
PanedWindowTest
,
ProgressbarTest
,
RadiobuttonTest
,
ScaleTest
,
ScrollbarTest
,
SeparatorTest
,
RadiobuttonTest
,
ScaleTest
,
ScrollbarTest
,
SeparatorTest
,
SizegripTest
,
TreeviewTest
,
WidgetTest
,
SizegripTest
,
SpinboxTest
,
TreeviewTest
,
WidgetTest
,
)
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
...
...
Lib/tkinter/ttk.py
View file @
a48e78a0
...
@@ -19,7 +19,7 @@ __author__ = "Guilherme Polo <ggpolo@gmail.com>"
...
@@ -19,7 +19,7 @@ __author__ = "Guilherme Polo <ggpolo@gmail.com>"
__all__
=
[
"Button"
,
"Checkbutton"
,
"Combobox"
,
"Entry"
,
"Frame"
,
"Label"
,
__all__
=
[
"Button"
,
"Checkbutton"
,
"Combobox"
,
"Entry"
,
"Frame"
,
"Label"
,
"Labelframe"
,
"LabelFrame"
,
"Menubutton"
,
"Notebook"
,
"Panedwindow"
,
"Labelframe"
,
"LabelFrame"
,
"Menubutton"
,
"Notebook"
,
"Panedwindow"
,
"PanedWindow"
,
"Progressbar"
,
"Radiobutton"
,
"Scale"
,
"Scrollbar"
,
"PanedWindow"
,
"Progressbar"
,
"Radiobutton"
,
"Scale"
,
"Scrollbar"
,
"Separator"
,
"Sizegrip"
,
"Style"
,
"Treeview"
,
"Separator"
,
"Sizegrip"
,
"S
pinbox"
,
"S
tyle"
,
"Treeview"
,
# Extensions
# Extensions
"LabeledScale"
,
"OptionMenu"
,
"LabeledScale"
,
"OptionMenu"
,
# functions
# functions
...
@@ -1149,6 +1149,33 @@ class Sizegrip(Widget):
...
@@ -1149,6 +1149,33 @@ class Sizegrip(Widget):
Widget
.
__init__
(
self
,
master
,
"ttk::sizegrip"
,
kw
)
Widget
.
__init__
(
self
,
master
,
"ttk::sizegrip"
,
kw
)
class
Spinbox
(
Entry
):
"""Ttk Spinbox is an Entry with increment and decrement arrows
It is commonly used for number entry or to select from a list of
string values.
"""
def
__init__
(
self
,
master
=
None
,
**
kw
):
"""Construct a Ttk Spinbox widget with the parent master.
STANDARD OPTIONS
class, cursor, style, takefocus, validate,
validatecommand, xscrollcommand, invalidcommand
WIDGET-SPECIFIC OPTIONS
to, from_, increment, values, wrap, format, command
"""
Entry
.
__init__
(
self
,
master
,
"ttk::spinbox"
,
**
kw
)
def
set
(
self
,
value
):
"""Sets the value of the Spinbox to value."""
self
.
tk
.
call
(
self
.
_w
,
"set"
,
value
)
class
Treeview
(
Widget
,
tkinter
.
XView
,
tkinter
.
YView
):
class
Treeview
(
Widget
,
tkinter
.
XView
,
tkinter
.
YView
):
"""Ttk Treeview widget displays a hierarchical collection of items.
"""Ttk Treeview widget displays a hierarchical collection of items.
...
...
Misc/ACKS
View file @
a48e78a0
...
@@ -1073,6 +1073,7 @@ The Dragon De Monsyne
...
@@ -1073,6 +1073,7 @@ The Dragon De Monsyne
Bastien Montagne
Bastien Montagne
Skip Montanaro
Skip Montanaro
Peter Moody
Peter Moody
Alan D. Moore
Paul Moore
Paul Moore
Ross Moore
Ross Moore
Ben Morgan
Ben Morgan
...
...
Misc/NEWS.d/next/Library/2018-01-18-13-09-00.bpo-32585.qpeijr.rst
0 → 100644
View file @
a48e78a0
Add Ttk spinbox widget to to tkinter.ttk. Patch by Alan D Moore.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment