5

I'm actually trying to create ttk.Spinbox from tkinter.Spinbox. I can manipulate codes below like ttk.Scrollbar pattern. tkinter.Spinbox button gives an old look for my GUI that is why i want to ttk.Spinbox.

Edit: I am using Python 3.4 on Windows 7 OS. I need a themed Spinbox widget. ttk.__init__ file has not Spinbox class/module. So, I open that file and wrote codes just like Scrollbar class given 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 codes that I placed into 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 given below is satisfactory.But there is an indent before content of Spinbox Widget

tkinter.Spinbox Widget tkinter.Spinbox Widget

ttk.Spinbox Widget ttk.Spinbox Widget

Is there something wrong? Why an indentation occurs?

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 root window the ttk.Spinbox spreads with it and an indentation occurs. I guess it is due to columnconfigure but i need configuration for better look.

Fatih1923
  • 2,665
  • 3
  • 21
  • 28
  • Your question is "what do you think about patterned codes"? That question doesn't make much sense, and will likely be closed since it's asking for an opinion. Also, I really don't understand what "create ttk.Spinbox from tkinter.Spinbox" means. You can't create one from the other. For one thing, they both already exist so there's no reason to create a ttk.Spinbox. Are you asking how to subclass a ttk.Spinbox? – Bryan Oakley Jun 11 '15 at 14:54
  • Are you serious about ttk has `Spinbox` module? I tried to run codes before embedding patterned codes to `ttk.__init__ ` file and got an error message like this: `AttributeError: 'module' object has no attribute 'Spinbox'`. I asked two question. First, why an indent occurs? And second, is it true manipulating original `ttk.__init__ `? – Fatih1923 Jun 11 '15 at 17:07
  • No problem. You may tell me how can i get tcl/ttk package to tkinter. Is it compatible python 3.4? – Fatih1923 Jun 11 '15 at 17:32
  • Ok, now I see what you're doing, though I still don't understand what you're asking. You've already got the tcl/ttk version with a Spinbox and are trying to use it. Are you asking why the ttk spinbox has less (more?) padding (indentation) than the tkinter spinbox? Your question would be much better if you gave a complete working example _without_ all of that help text. AND, clarify what you're asking. It would also help if you mentioned the platform (Windows, I'm guessing). – Bryan Oakley Jun 11 '15 at 17:45
  • where are you getting the `Widget` class from? Both tkinter and ttk define this class. Can you please supply a _complete_ working program? – Bryan Oakley Jun 11 '15 at 18:51
  • Widget class is from `ttk`. This codes are in `ttk.__init__.py` and I am calling it to another simple gui file. `self.sb=ttk.Spinbox(self, *_options_)` – Fatih1923 Jun 11 '15 at 19:39
  • @BryanOakley you can see my edited question with a complete program. Sorry for latency :( – Fatih1923 Jun 14 '15 at 18:08
  • 1
    FWIW: A `tkinter.ttk.Spinbox` class was added to Python 3.7 (according to [What’s New In Python 3.7](https://docs.python.org/3/whatsnew/3.7.html#tkinter)). – martineau Oct 04 '18 at 15:22

2 Answers2

4

This appears to be a bug within Tk itself, and your Python code is simply exposing it. I converted your example code into straight Tcl/Tk and ran it against both Tk-8.5.17 and Tk-8.6.3 (via TclKits), and the same issue is happening there, too:

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


This is what the above code looks like when run:

ttk Spinbox bug present in Tcl/Tk itself


It appears that the problem code is in the vistaTheme.tcl file within the ttk subdirectory, in the nested code beginning 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
        }
    }
}


Specifically, if you remove the -sticky {} bit from Spinbox.textarea -expand 1 -sticky {} in the inner-most block, then it looks like the indentation goes away:

Fixed Spinbox example in Tkinter


I'd suggest reading through the Tcl/Tk bug wiki here, then open a bug with them here for this issue. Wouldn't hold your breath, though. Tcl/Tk releases don't happen very often, because it's a pretty mature and stable language. If a fix is produced for Tcl/Tk, then you'll need to file a bug with the Python maintainers to get them to either update their internal copy of Tcl/Tk for the Windows releases or backport a fix.

It might be possible to work around the problem in Python by using ttk's styles and configuring the Spinbox.textarea bit to unset the sticky attribute, however, I don't have an exact code snippet to do that at the moment.

Kumba
  • 2,390
  • 3
  • 33
  • 60
  • 1
    Fixed now in Tk (http://core.tcl.tk/tk/info/f91b7065bf1bf655) following your investigation here. – patthoyts Sep 22 '16 at 13:55
  • Awesome, thanks! I suppose someone should get a bug opened on Python to get this fix backported into at least Python 3.x. Dunno if they'd take this for 2.x. – Kumba Sep 24 '16 at 06:00
3

Using python 3.4 on windows 7 I don't 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 yields the following:

screenshot of a tk spinbox and ttk spinbox

If you are getting an extra indent in the entry field area perhaps you are formatting the value with spaces or tabs.

patthoyts
  • 32,320
  • 3
  • 62
  • 93
  • You right. Your codes give that look. But I haven't find the mistake on my machine yet. May you please try `from=5` for start value? It always begins with "0" whatever number you write. – Fatih1923 Jun 14 '15 at 17:39