0

I want to create a class for a Tk.Button in a Tk.Frame so that the button can have a border color independent of its background color.

I wrote this code which creates a button in a frame just as I want but I cannot later get or set the text, bcolor and bg of a previously created FrameButton.

I thought I should be able to do this @profile and @bgsetter constructions but these give me an error.

import tkinter as tk
class FramedButton(tk.Frame):
 def __init__(self, parent, text="HELLO", bcolor="red", *args, **kwargs):
 tk.Frame.__init__(self, parent, bg="green", *args, **kwargs)
 self.parent = parent
 self.button=tk.Button(self, text=text, bg=bcolor, borderwidth=1) 
 self.button.grid(row=0, column=0, padx=5, pady=5)
 self.pack()
root = tk.Tk()
root.title="FramedButton"
fb=FramedButton(root)
fb.pack(padx=10,pady=10)
# but these do not work... what do I need to add/change?
fb.text="WORLD"
fb.bg="blue"
fb.bcolor="yellow"
root.mainloop()
acw1668
48k5 gold badges30 silver badges39 bronze badges
asked Jun 5, 2025 at 20:33

2 Answers 2

2

You need to call fb.button.config() to set the options for the internal button and fb.config() to set the options for the outer frame:

fb.config(bg='blue') # set the "outer border" to blue
fb.button.config(text='WORLD', bg='yellow') # the the button text and background color
answered Jun 6, 2025 at 0:59
Sign up to request clarification or add additional context in comments.

Comments

1

The tkinter module is an interface to the Tcl/Tk GUI toolkit. To make actual changes to the widgets, we need to call Tk commands.

Your code doesn't work because you're just creating new data attributes for your instance, not accessing the widget options themselves.

The actual value of a Tk widget option is not related to the attributes of the Python class instance.

The tkinter module defines special methods for getting or setting widget options.

As we can see in the source code, these methods use self.tk.call(args) to call Tk commands to control the Tk GUI.

import tkinter as tk
# inherited from class Misc
print(tk.Frame.configure)
print(tk.Frame.config)
print(tk.Tk.configure)
print(tk.Tk.config)
# inherited from class Wm
# class Wm provides functions for the communication with the window manager.
# for tk.Tk and tk.Toplevel
print(tk.Tk.title)
print(tk.Tk.wm_title)
class FramedButton(tk.Frame):
 def __init__(self, parent, text="HELLO", bcolor="red", *args, **kwargs):
 tk.Frame.__init__(self, parent, bg="green", *args, **kwargs)
 self.parent = parent
 self.button=tk.Button(self, text=text, bg=bcolor, borderwidth=1) 
 self.button.grid(row=0, column=0, padx=5, pady=5)
 self.pack()
 # get button text: self.tk.call(self.button, "cget", "-text")
root = tk.Tk()
# set title
root.title("FramedButton")
# same as root.wm_title("FramedButton") or root.tk.call("wm", "title", root, "FramedButton")
# get title
print(root.title())
fb=FramedButton(root)
fb.pack(padx=10,pady=10)
# available config options
print(root.keys()) # print(root.config())
print(fb.keys()) # print(fb.config())
print(fb.button.keys()) # print(fb.button.config())
# set options
# widget.config(option=value) or widget["option"] = value
fb.button["text"]="WORLD" # set new text to self.button, __setitem__
fb.config(bg="blue") # set new bg to frame
fb.button.config(bg="yellow") # set new bg to self.button
# get button text
print(fb.button["text"]) # __getitem__
print(fb.button.cget("text"))
print(fb.button.config("text"))
root.mainloop()

If you want to customize the attribute lookup, you can use descriptors such as property.

import tkinter as tk
class FramedButton(tk.Frame):
 def __init__(self, parent, text="HELLO", bcolor="red", *args, **kwargs):
 tk.Frame.__init__(self, parent, bg="green", *args, **kwargs)
 self.parent = parent # same as self.master
 self.button=tk.Button(self, text=text, bg=bcolor, borderwidth=1) 
 self.button.grid(row=0, column=0, padx=5, pady=5)
 self.pack()
 self.text = text
 @property
 def text(self):
 return self.button["text"]
 @text.setter
 def text(self, value):
 self.button["text"] = value
root = tk.Tk()
root.title("FramedButton")
fb=FramedButton(root)
fb.pack(padx=10,pady=10)
print(dir(fb))
# [..., 'button', ..., 'parent', ..., 'text', ...]
print(fb.text) # HELLO
fb.text="WORLD"
print(fb.text) # WORLD
print(FramedButton.text)
# <property object at 0x0000012D7E957CE0>
root.mainloop()
answered Jun 12, 2025 at 16:51

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.