Chemistpp
Chemistpp

Reputation: 2046

tkinter ttk style Layout not found

Getting an error on the following code. Keep looking at examples and re-evaluating code but cannot really spot any reason this shouldn't run. Is there anything incorrect such that the 'mRRed' layout cannot be found? (And I'm sure the subsequent)...

import tkinter as tk
from tkinter import ttk

class MainFrame:
    def __init__(self,parent):
        self.frame = ttk.Frame(parent,padding='3 3 12 12')
        self.frame.grid(column=0, row=0)

        self.mRRed = ttk.Style()
        self.mRBlue = ttk.Style()
        self.mPurple = ttk.Style()
        self.mPink = ttk.Style()
        self.mSCyan = ttk.Style()
        self.mVYellow = ttk.Style()
        self.mGreen  = ttk.Style()

        self.mRRed.configure("mRRed",background="#E61E50")
        self.mRBlue.configure("mRBlue",background="#0F69AF")
        self.mPurple.configure("mPurple",background="#503291")
        self.mPink.configure("mPink",background="#EB3C96")
        self.mSCyan.configure("mSCyan",background="#2BDECD")
        self.mVYellow.configure("mVYellow",background="#FFC832")
        self.mGreen.configure("mGreen",background="#149B5F")


        self.toolRibbon    = ttk.Frame(self.frame, style='mRRed')
        self.subtoolRibbon = ttk.Frame(self.frame, style='mRBlue')
        self.titleFrame    = ttk.Frame(self.frame, style='mPruple')
        self.contentFrame  = ttk.Frame(self.frame, style='mPink')
        self.optionRibbon  = ttk.Frame(self.frame, style='mSCyan')
        self.statusFrame   = ttk.Frame(self.frame, style='mVYellow')
        self.infoFrame     = ttk.Frame(self.frame, style='mGreen')

        self.toolRibbon.grid(column=0,row=0)
        self.subtoolRibbon.grid(column=0,row=1)
        self.titleFrame.grid(column=1,row=1)
        self.contentFrame.grid(column=1,row=2)
        self.optionRibbon.grid(column=1,row=3)
        self.statusFrame.grid(column=1,row=4)
        self.infoFrame.grid(column=4,row=1)

root = tk.Tk()
root.title("test")

main = MainFrame(root)
root.mainloop()

--------------------------------------------------------------------------- TclError Traceback (most recent call last) in 43 root.title("test") 44 ---> 45 main = MainFrame(root) 46 root.mainloop()

in init(self, parent) 24 25 ---> 26 self.toolRibbon = ttk.Frame(self.frame, style='mRRed') 27 self.subtoolRibbon = ttk.Frame(self.frame, style='mRBlue') 28 self.titleFrame = ttk.Frame(self.frame, style='mPruple')

D:\Programs\Anaconda\lib\tkinter\ttk.py in init(self, master, **kw) 740 borderwidth, relief, padding, width, height 741 """ --> 742 Widget.init(self, master, "ttk::frame", kw) 743 744

D:\Programs\Anaconda\lib\tkinter\ttk.py in init(self, master, widgetname, kw) 557 # Load tile now, if needed 558 _load_tile(master) --> 559 tkinter.Widget.init(self, master, widgetname, kw=kw) 560 561

D:\Programs\Anaconda\lib\tkinter__init__.py in init(self, master, widgetName, cnf, kw, extra) 2297 del cnf[k] 2298
self.tk.call( -> 2299 (widgetName, self._w) + extra + self._options(cnf)) 2300 for k, v in classes: 2301
k.configure(self, v)

TclError: Layout mRRed not found

Upvotes: 6

Views: 8099

Answers (2)

Buzz B
Buzz B

Reputation: 117

To create new styles, style names must be in the form 'newName.defaultName'. The default style names are typically the widget class (obtained by the method .winfo_class()) prefixed with a 'T', e.g. for a tkinter.ttk.Button: 'TButton'.

However, this is not true for all widget classes (taken from Using and customizing ttk styles):

  • Widget class: Style name
  • Button: TButton
  • Checkbutton: TCheckbutton
  • Combobox: TCombobox
  • Entry: TEntry
  • Frame: TFrame
  • Label: TLabel
  • LabelFrame: TLabelFrame
  • Menubutton: TMenubutton
  • Notebook: TNotebook
  • PanedWindow: TPanedwindow (not TPanedWindow!)
  • Progressbar: Horizontal.TProgressbar or Vertical.TProgressbar, depending on the orient option.
  • Radiobutton: TRadiobutton
  • Scale: Horizontal.TScale or Vertical.TScale, depending on the orient option.
  • Scrollbar: Horizontal.TScrollbar or Vertical.TScrollbar, depending on the orient option.
  • Separator: TSeparator
  • Sizegrip: TSizegrip
  • Treeview: Treeview (not TTreview!)

For example:

import tkinter as tk
from tkinter import ttk

# Create widget
a_button = ttk.Button(None)

# Create Style instance
style = ttk.Style()

# Configure style
style.configure('TButton', foreground='grey')  # Changes default text
style.configure('Success.TButton', foreground='green')  # New style text

# Apply style
a_button.config(style='Success.TButton')

Upvotes: 0

Axe319
Axe319

Reputation: 4365

ttk.Style() follows the naming convention of T<widget name> for user created styles. This is actually isn't really in the python tkinter docs other than the fact that they use the naming convention in the examples but never explain it.

So in short, if you want to apply the style to a Frame widget you would need to use the suffix .TFrame in your style name.

I also noticed, I misread your question and was under the impression you were using a Label and not a Frame.

I added some Labels to demonstrate the effect but in your example, your code would be:

import tkinter as tk
from tkinter import ttk

class MainFrame:
    def __init__(self,parent):
        self.frame = ttk.Frame(parent,padding='3 3 12 12')
        self.frame.grid(column=0, row=0)

        self.mRRed = ttk.Style()
        self.mRBlue = ttk.Style()
        self.mPurple = ttk.Style()
        self.mPink = ttk.Style()
        self.mSCyan = ttk.Style()
        self.mVYellow = ttk.Style()
        self.mGreen  = ttk.Style()

        self.mRRed.configure("mRRed.TFrame",background="#E61E50")
        self.mRBlue.configure("mRBlue.TFrame",background="#0F69AF")
        self.mPurple.configure("mPurple.TFrame",background="#503291")
        self.mPink.configure("mPink.TFrame",background="#EB3C96")
        self.mSCyan.configure("mSCyan.TFrame",background="#2BDECD")
        self.mVYellow.configure("mVYellow.TFrame",background="#FFC832")
        self.mGreen.configure("mGreen.TFrame",background="#149B5F")


        self.toolRibbon    = ttk.Frame(self.frame, style='mRRed.TFrame',borderwidth=4)
        self.subtoolRibbon = ttk.Frame(self.frame, style='mRBlue.TFrame',borderwidth=4)
        self.titleFrame    = ttk.Frame(self.frame, style='mPurple.TFrame',borderwidth=4)
        self.contentFrame  = ttk.Frame(self.frame, style='mPink.TFrame',borderwidth=4)
        self.optionRibbon  = ttk.Frame(self.frame, style='mSCyan.TFrame',borderwidth=4)
        self.statusFrame   = ttk.Frame(self.frame, style='mVYellow.TFrame',borderwidth=4)
        self.infoFrame     = ttk.Frame(self.frame, style='mGreen.TFrame',borderwidth=4)

        self.toolRibbon.grid(column=0,row=0)
        self.subtoolRibbon.grid(column=0,row=1)
        self.titleFrame.grid(column=1,row=1)
        self.contentFrame.grid(column=1,row=2)
        self.optionRibbon.grid(column=1,row=3)
        self.statusFrame.grid(column=1,row=4)
        self.infoFrame.grid(column=4,row=1)

        self.test = ttk.Label(self.optionRibbon, text='cyan test')
        self.test.pack()

        self.test2 = ttk.Label(self.contentFrame, text='pink test')
        self.test2.pack()

root = tk.Tk()
root.title("test")

main = MainFrame(root)
root.mainloop()

Upvotes: 14

Related Questions