Create a new ttk widget from tkinter

I am trying to create ttk.Spinbox from tkinter.Spinbox . I can manipulate the codes below, like the ttk.Scrollbar template. The tkinter.Spinbox button gives an old look at my GUI, so I want ttk.Spinbox .

Edit: I am using Python 3.4 for Windows 7. I need a Spinbox theme widget. ttk.__init__ file does not have a Spinbox class / module. So, I open this file and write the codes in the same way as the Scrollbar class specified below.

 class Scrollbar(Widget, tkinter.Scrollbar): """Ttk Scrollbar controls the viewport of a scrollable widget.""" def __init__(self, master=None, **kw): """Construct a Ttk Scrollbar with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS command, orient """ Widget.__init__(self, master, "ttk::scrollbar", kw) 

And the codes that I put in the ttk.__init__.py file. It inherits from tkinter.Spinbox .

 class Spinbox(Widget, tkinter.Spinbox): """spinbox widget.""" def __init__(self, master=None, **kw): Widget.__init__(self, master, "ttk::spinbox", kw) 

The test result below is satisfactory. But there is an indentation of the contents of the Spinbox Widget

tkinter.Spinbox Widget tkinter.Spinbox Widget

ttk.Spinbox Widget ttk.Spinbox Widget

Is there something wrong? Why does indentation occur?

 import tkinter as tk import tkinter.ttk as ttk class Spinbox(ttk.Widget): def __init__(self, master, **kw): ttk.Widget.__init__(self, master, 'ttk::spinbox', kw) if __name__ == '__main__': root = tk.Tk() root.grid_columnconfigure(0, weight=1) opts = { 'from_': 5, 'to': 10, 'increment': 1 } sp1 = tk.Spinbox(root, from_=5, to=10) sp1.grid(row=0, column=0) sp2 = Spinbox(root, from_=5, to=10) sp2.grid(row=1, column=0, columnspan=2, sticky="we",pady=2) root.mainloop() 

If you expand the root window, then ttk.Spinbox distributed with it and indented. I assume this is due to columnconfigure , but I need a configuration for a better view.

+5
source share
2 answers

This seems to be a bug inside Tk itself, and your Python code just exposes it. I turned your sample code into a direct Tcl / Tk and ran it against Tk-8.5.17 and Tk-8.6.3 (via TclKits ), and the same problem also happens:

 package require Tk 8.5 grid columnconfigure . 0 -weight 1 spinbox .spin -from 5 -to 10 grid .spin -row 0 -column 0 ttk::spinbox .spin2 -from 5 -to 10 grid .spin2 -row 1 -column 0 -sticky "ew" -pady 2 


Here's what the code above looks like at startup:

ttk Spinbox error present in Tcl / Tk itself


It looks like the problem code is in the vistaTheme.tcl file in the vistaTheme.tcl subdirectory, in the nested code starting with ttk::style layout TSpinbox :

 ttk::style layout TSpinbox { Spinbox.field -sticky nswe -children { Spinbox.background -sticky news -children { Spinbox.padding -sticky news -children { Spinbox.innerbg -sticky news -children { Spinbox.textarea -expand 1 -sticky {} } } Spinbox.uparrow -side top -sticky ens Spinbox.downarrow -side bottom -sticky ens } } } 


In particular, if you remove the -sticky {} bit from Spinbox.textarea -expand 1 -sticky {} in the innermost block, then the indentation seems to go away:

Fixed Spinbox example in Tkinter


I would suggest reading here through the wiki here , then opening an error with them here for this problem. At least not hold your breath. Tcl / Tk releases do not happen very often, because it is a fairly mature and stable language. If a patch is created for Tcl / Tk, you will need to specify an error with the Python maintainers to force them to either update the internal copy of Tcl / Tk for Windows releases, or back up the patch.

It’s possible to work around the problem in Python using the ttk styles and setting the Spinbox.textarea bit to disable the sticky attribute, however I don’t have the exact code snippet that can be done at the moment.

+4
source

Using python 3.4 on Windows 7, I do not get the same indentation. Here is a demo:

 import tkinter as tk import tkinter.ttk as ttk class Spinbox(ttk.Widget): def __init__(self, master, **kw): ttk.Widget.__init__(self, master, 'ttk::spinbox', kw) if __name__ == '__main__': root = tk.Tk() opts = { 'from': 0, 'to': 10, 'increment': 1 } sp1 = tk.Spinbox(root, **opts) sp1.place(x=5, y=5) sp2 = Spinbox(root, **opts) sp2.place(x=5, y=30) root.mainloop() 

This gives the following:

screenshot of a tk spinbox and ttk spinbox

If you get extra indentation in the input field, you might be formatting the value with spaces or tabs.

+3
source

All Articles