Using a window style in a Toplevel window

Eric Brunel eric.brunel at pragmadev.nospam.com
Thu Dec 9 04:00:39 EST 2010


In article <mailman.185.1291395907.2649.python-list at python.org>,
 craf <prog at vtr.net> wrote:

> Hi.
> 
> I use Python 3.1 and Tkinter.ttk 8.5 on Ubuntu 9.10.
> 
> CODE:----------------------------------------------------
> 
> module:FMain.py
> 
> from tkinter import ttk
> from FSecondWindow import *
> 
> class App:
>     def __init__(self,master):
> 
>         button1 = ttk.Button(master,text='Show
> TopLevel',command=lambda:window())
>         button1.pack()
> 
>        
> master = Tk()
> app = App(master)
> style = ttk.Style()
> style.theme_use('clam')
> master.mainloop()
> 
> 
> module:FSecondWindow.py
> 
> from tkinter import *
> from tkinter import ttk
> 
> def window():
>     t = Toplevel()
>     button2 = Button(t,text='Hello').pack()    
>     
> 
> CODE EXPLANATION:-------------------------------------------
> 
> 1. From the main module FMain.py call the window function that is
> located in FSecondWindow module and create a toplevel window.
> 
> 2.I apply a theme called 'clam' to the master window to improve the
> appearance of their widgets.
> 
> QUERY:--------------------------------------------------
> 
> How I can make the toplevel window also take the theme 'clam'?

Short answer: you can't. No directly anyway.

Long answer: As you might be aware, there are 2 widget sets in 
tk/tkinter, the "old" one for which classes are directly in the tkinter 
module, and the new one that are in the ttk submodule. Only the second 
set supports theming, not the first one. Unfortunately, there are a few 
widgets that exist only in the first set, and Toplevel is one of those. 
So no theming is directly available for toplevels, and you can change 
whatever you want via style.theme_use, it won't be reflected on 
toplevels.

By the way, as you wrote the code above, it won't be reflected on your 
button either, since you used the Button class, which is taken in 
tkinter directly, so it is the "old" Button class, not the new one. To 
get the new one, use ttk.Button, not Button.

For your toplevel, there is however a simple workaround: Since there is 
a Frame widget in the new widget set, you can simply insert such a frame 
in your toplevel, make sure it will take the whole space, and then 
insert your widgets in this frame rather than in the toplevel directly. 
The code for your 'window' function would then become:

def window()
    t = Toplevel()
    frm = ttk.Frame(t)
    frm.pack(fill=BOTH, expand=True)
    button2 = ttk.Button(frm, text='Hello')
    button2.pack()

(Note also that I have put the creation of the button and its packing in 
2 lines. You should never do variable = widget.pack(…) since pack does 
not return the widget. It always returns None, so doing so won't put 
your widget in the variable).

The code above should do what you're after.

> Thanks in advance.

HTH
 - Eric -



More information about the Python-list mailing list