Title: IDLE: use ttk.spinbox with configdialog
Type: enhancement Stage: patch review
Components: IDLE Versions: Python 3.8, Python 3.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: terry.reedy Nosy List: cheryl.sabella, markroseman, serhiy.storchaka, terry.reedy
Priority: normal Keywords: patch

Created on 2018-06-26 03:29 by terry.reedy, last changed 2020-10-25 21:30 by markroseman.

File name Uploaded Description Edit
tkversions.png markroseman, 2020-10-25 21:30
Pull Requests
URL Status Linked Edit
PR 22954 open markroseman, 2020-10-25 01:04
Messages (6)
msg320465 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2018-06-26 03:29
Spinoff from #27755, which has a image of tk and ttk versions of a spinbox on Mac and asks about using ttk.spinbox.

ttk Spinbox was added to tcl/tk in 8.5.9 and to tkinter.ttk in 3.7. I believe there are three cases to consider.
tcl/tk   python  action
>= 8.5.9  >=3.7  from tkinter.tkk import Spinbox
>= 8.5.9   3.6   import Entry and copy class Spinbox(Entry) code
< 8.5.9          from tkinter import Spinbox

Serhiy, is tcl/tk < 8.5.9 something we realistically need to worry about, on Linux?

In Dec 2018 or Jan 2019, when 3.6 switches to security fixes only, the 3.6 code can be deleted.

For the present, only use config options in the common subset:
cursor, takefocus, validate, validatecommond, invalidcommand,
xscrollcommand, command, to, from_, increment, values, wrap, format.
Is this sufficient?

Whenever we make 8.5.9 or later a requirement, the tkinter Spinbox can be dropped and the class and style options used.  Or we can subclass tkinter.Spinbox and accept and somehow deal with class and style options.  (We are not presently using custom styles.)

For the present, the code can go in, presently only 300 lines.  When we only need to cater to 3.7+ and 8.5.9+, the code will be replaced by normal import from ttk.

Comman methods: identify, bbox, delete, icursor, index, insert, get.
ttk has set, while tk sets through a textvariable.  If we subclass tk.spinbox, it could have a set method that uses a private Var.

 Do the universal widget methods listed on
all apply to ttk widgets?
msg320499 - (view) Author: Mark Roseman (markroseman) * Date: 2018-06-26 15:21
For now, using a (likely very minimal) subset of commands/options common to both classic and ttk spinbox versions in IDLE sounds good. 

I was originally thinking stick with "-textvariable" for setting (which works on both) but I like your idea of adding "set" to a tk.spinbox subclass.
msg320501 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2018-06-26 15:52
ttk.Spinbox inherits from ttk.Entry.  My option list left out the options for Entry, which is one of the ttk widget not in the doc.  The additional entry options include exportselection, justify, show, state, textvariable, and width.
explicitly says textvariable is supported.  This is important because configdialog uses tracers on Var to detect and record user changes.
msg379560 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-10-25 03:53
#27755 was about replacing uses of our custom DynOptionMenu with ttk.Combobox, which I believe we can do now, wherever we don't replace it with something else.   One use is for font size choice; Spinbox was suggested as an alternative replacement.

Spinbox was also proposed somewhere else to remplace the indent size Label scale.  But I/we had decided, somewhere,  to use a simple entry box, like those for entering counts on the General tab, with validation limits of 1 and 16, and move the choice to the General tab.  (If we don't have validate(min, max) function, should make one.)  SO

The transfer cannot be done until the General tab is split into 2, as it is now too long (does not fix on Macbook Air -- cannot see buttons).  I think General windows preferences (where indent should go) + help resources for 1, Specific Editor only or Shell only for other.  Not sure of names.

This all said, I tried out the patch.  The spinbox appears to be an Entry with added arrows.  If it worked right, it could be used for some other int entries instead of plain Entry.  But in some ways, it seems partly worse than Entry.
0. No doc in Shipman (written before 8.5.9); must use tk doc.
1. Expands to space available; is Entry char width really disabled?
2. Deleting digit to replace it generates 2 TclErrors*.
3. Clicking arrow 'selects' entry.  Patch used text selection, but my dark theme select looks awful for single digit.  We can fix this with different config.

* ...
  File "f:\dev\3x\lib\tkinter\", line 536, in get
    return self._tk.getint(value)
_tkinter.TclError: expected integer but got ""
During handling of the above exception, another exception occurred:
  File "f:\dev\3x\lib\tkinter\", line 538, in get
    return int(self._tk.getdouble(value))
_tkinter.TclError: expected floating-point number but got ""

I will look more later.
msg379582 - (view) Author: Mark Roseman (markroseman) * Date: 2020-10-25 15:46
Whoops, sorry... there's a "readonly" state flag that disables direct editing of the entry (like with combobox) and just allows manipulation of the arrows. I've updated the PR to set that. I've also changed it so that the contents of the entry part isn't selected whenever the arrows are used (agreed, it looks ugly). Please give it a try and let me know.

p.s. I just checked, the entry's width configuration option works. You just have to remove the "fill=X" when the widget is packed. FWIW, I kept the previous layout to keep the patch as minimal as possible, under the assumption that other layout changes (here, on in general) were planned.
msg379611 - (view) Author: Mark Roseman (markroseman) * Date: 2020-10-25 21:30
Just as a side note for Terry and anyone else testing on macOS... the recent updates in Tk have smoothed out many of the appearance issues for the classic widgets. See the attached screen shot tkversions.png comparing 8.6.9 with the current trunk of the Tk repo. Notice things like the background color around the optionmenu aren't as jarring on the newer Tk versions.

Having said that, I'll likely stick with the older ones for development purposes, just because the blemishes with the classic widgets and other things are so much more noticeable! 

Incidentally, if you've got several versions of Tcl/Tk on your system, you can use /usr/bin/install_name_tool to point the Tkinter shared library at the one you want to use. Use like "install_name_tool -change OLD NEW file", e.g.:
    install_name_tool -change /Library/Frameworks/Tk.framework/Versions/8.6/Tk /Users/roseman/tmp/tcl86core/Library/Frameworks/Tk.framework/Versions/8.6/Tk build/lib.macosx-10.15-x86_64-3.10/
Date User Action Args
2020-10-25 21:30:56markrosemansetfiles: + tkversions.png

messages: + msg379611
2020-10-25 15:46:58markrosemansetmessages: + msg379582
2020-10-25 03:53:27terry.reedysetmessages: + msg379560
2020-10-25 01:04:21markrosemansetkeywords: + patch
stage: test needed -> patch review
pull_requests: + pull_request21872
2018-12-11 22:34:03terry.reedysetversions: - Python 3.6
2018-09-24 01:19:01terry.reedysettitle: IDLE: use ttk.spinbox -> IDLE: use ttk.spinbox with configdialog
2018-06-26 15:52:53terry.reedysetmessages: + msg320501
2018-06-26 15:21:58markrosemansetmessages: + msg320499
2018-06-26 03:29:08terry.reedycreate