Creating a custom widget in tkinter - python

I want to create a custom widget in tkinter such that when instantiated, displays a label and an entry box. Example I created a class named entry and call as.. entry ('name', master ) and this would display a label with text as main along side an entry box.
I have succeeded in doing that but my problem is with the geometry managers. they all seem to mess up everything

Your widget should subclass Frame. Within the frame you can use any geometry manager you want without affecting any other code. It's important that the widget class does not call grid, pack or place on itself -- that's the job of the function that creates the widget. Every widget, or function that creates a widget, should only ever worry about laying out its children.
Here's an example that creates a couple of different custom widgets. Each uses a different geometry manager to illustrate that they don't interfere with each other:
try:
# python 3.x
import tkinter as tk
except ImportError:
# python 2.x
import Tkinter as tk
class CustomWidget(tk.Frame):
def __init__(self, parent, label, default=""):
tk.Frame.__init__(self, parent)
self.label = tk.Label(self, text=label, anchor="w")
self.entry = tk.Entry(self)
self.entry.insert(0, default)
self.label.pack(side="top", fill="x")
self.entry.pack(side="bottom", fill="x", padx=4)
def get(self):
return self.entry.get()
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.label = tk.Label(self)
self.e1 = CustomWidget(self, "First Name:", "Inigo")
self.e2 = CustomWidget(self, "Last Name:", "Montoya")
self.submitButton = tk.Button(self, text="Submit", command=self.submit)
self.e1.grid(row=0, column=0, sticky="ew")
self.e2.grid(row=1, column=0, sticky="ew")
self.label.grid(row=2, column=0, sticky="ew")
self.submitButton.grid(row=4, column=0)
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(2, weight=1)
def submit(self):
first = self.e1.get()
last = self.e2.get()
self.label.configure(text="Hello, %s %s" % (first, last))
if __name__ == "__main__":
root = tk.Tk()
Example(root).place(x=0, y=0, relwidth=1, relheight=1)
root.mainloop()

I agree with Mr. Oakley. You should subclass frame to do your job.
The simplest way to do what you want is to create a module with the following code:
# AnnotatedEntry.py
def AnnotatedEntry(master, name="An annoted entry box"):
'''
As a little extra, name is a keyword-argument, which defaults to "An annotated
entry box."
'''
import tkinter as tk
overlord = tk.Frame(master, height=5, width=40)
labeller = tk.Label(overlord, text=name, font="Times 14 bold")
labeller.grid(sticky='new')
inputter = tk.Entry(overlord, font="Times 14 bold")
inputter.grid(sticky='sew', pady=(10,0))
return overlord
This would be used as follows:
# Main program
import tkinter
import AnnotatedEntry
root = tkinter.Tk()
hold = AnnotatedEntry.AnnotatedEntry(root, name="Hello, world!")
hold.grid()
I hereby affirm, on my Scout Honor, that this code has been fully tested, and is guaranteed to work in Python 3.7.4. That being said, there is currently no method for returning the data contained in the Entry; you will have to work that out for yourself.

Based on #Bryan Oakley answer, I do have some modification. I know it's out of topic somehow. This is how to return a value from the widget and it only allows integer up to some number of digits that the user must entered.
#create a global value
global tbVal
tbVal = 0
class CustomWidget(tk.Frame):
def __init__(self, parent, nDigits):
tk.Frame.__init__(self, parent)
self.entry = tk.Entry(self)
self.entry.pack(side="bottom", fill="x", padx=4)
self.entry.configure(validate='all',validatecommand=windows.register(self.sbValidate),'%P','%W',nDigits))
def get(self):
return self.entry.get()
def sbValidate(self, userInput, widget, nDigits):
global tbVal
tbVal = userInput
if userInput == '':
return True
if '.' in userInput or ' ' in userInput:
return False
n = len(userInput)
if n > int(nDigits):
return False
try:
val = int(float(userInput))
except ValueError:
return False
return val
class Example(tk.Frame):
def __init__(self, parent, nDigitsLimit):
tk.Frame.__init__(self, parent)
self.e1 = CustomWidget(self, nDigitsLimit)
self.e1.grid(row=0, column=0, sticky="ew")
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(2, weight=1)
def btnStartClick():
print(tbVal)
nDigitsLimit = 8
tbTest = ttk.Entry(Example(windows, nDigitsLimit).place(x=20, y=20, relwidth=0.25, relheight=0.05))
btnStart = tk.Button(frame, text='Start', command=btnStartClick)
btnStart.place(relx=0.50, rely=0.50)

Related

How to avoid destroying data when using tkinter Toplevel parent/child windows?

How do I pass data between parent and child windows and preserve data/unique IDs?
If I use the destroy() method for closing a child window, associated values are destroyed too, even when the dictionary that I send values to was initiated with the parent. Clicking on the Get child1config button after destroying the child window gives the error:
_tkinter.TclError: invalid command name ".!child1.!entry"
So, I don't destroy. Is it recommended to withdraw and deiconify many child windows?
How do I refer to the child window (and associated values) from parent window? Am I doing it correctly?
import tkinter as tk
class parent(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.dic={}
self.dic["var"]=['default']
self.title("Parent")
self.button1=tk.Button(self,text="open child1", command = self.open_child1, width=20)
self.button1.grid(row=0,column=0, padx=5, pady=5)
self.button2=tk.Button(self,text="Get child1 config", command = self.get_child1_value, width=20)
self.button2.grid(row=0,column=1, padx=5, pady=5)
self.label1 = tk.Label(self, text="", width=10)
self.label1.grid(row=0,column=2, sticky='ew')
self.child1_from_parent=child1(self)
self.child1_from_parent.withdraw()
def open_child1(self):
self.child1_from_parent.deiconify()
def get_child1_value(self):
self.label1.config(text=(self.dic["var"][0]+' \n'+self.child1_from_parent.child1_entry.get()))
class child1(tk.Toplevel):
def __init__(self,master):
tk.Toplevel.__init__(self, master)
self.frame = tk.Frame(self)
self.title("Child")
self.label1 = tk.Label(self, text="Config 1", width=10)
self.label1.grid(row=0,column=0)
self.child1_entry = tk.Entry(self, width=10)
self.child1_entry.grid(row=0, column=1, padx=5, pady=5)
self.child1_entry.insert ( tk.END, self.master.dic['var'][0])
self.child1_entry.bind('<Return>', self.update_value)
self.button4=tk.Button(self,text="Close", command = self.close_child1, width=20)
self.button4.grid(row=0,column=2, padx=5, pady=5)
self.button5=tk.Button(self,text="destroy", command = self.destroy_child1, width=20)
self.button5.grid(row=0,column=3, padx=5, pady=5)
def update_value(self, event):
self.master.dic["var"][0]=self.master.child1_from_parent.child1_entry.get()
def close_child1(self):
self.withdraw()
def destroy_child1(self):
self.destroy()
def main():
parent().mainloop()
if __name__ == '__main__':
main()
My program will grow, so I am looking for expandability. Classes 'seems' like a good idea. I have a parent tkinter window running with live data, and I will open/navigate to different child windows to perform different functions while the main window is running, accessible, and receiving data from child windows.
The code you have can be changed fairly easily to fix the problem. Tkinter supports something called "Variable Classes" — see The Variable Classes (BooleanVar, DoubleVar, IntVar, StringVar) — which are very handy for storing and passing around data within tkinter apps. In particular, Entry widgets support storing their contents in one (see Entry widget options) simply by passing one to it via the textvariable= keyword argument when its created. Once that's done, the widgets current (or last) value can be retrieved at any time whether the Entry still exists or not.
Below is a modified version of your code with the modifications needed to create and use one to pass information that's put into the widget in the child window back to its parent. I've indicated the most important changes with # ALL CAPS COMMENTS. Also note that I have also reformatted your code so it follows the PEP 8 - Style Guide for Python Code recommendations and is more readable. I strongly suggest you read and follow these guidelines.
import tkinter as tk
class Parent(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.dic = {}
self.dic['var'] = ['default']
self.dic['child1_value'] = tk.StringVar(value='') # ADDED.
self.title("Parent")
self.button1 = tk.Button(self, text="open Child1",
command=self.open_child1, width=20)
self.button1.grid(row=0, column=0, padx=5, pady=5)
self.button2 = tk.Button(self, text="Get Child1 config",
command=self.get_child1_value, width=20)
self.button2.grid(row=0, column=1, padx=5, pady=5)
self.label1 = tk.Label(self, text="", width=10)
self.label1.grid(row=0, column=2, sticky='ew')
self.Child1_from_parent = Child1(self)
self.Child1_from_parent.withdraw()
def open_child1(self):
self.Child1_from_parent.deiconify()
def get_child1_value(self):
self.label1.config(text=self.dic['var'][0] + '\n' +
self.dic['child1_value'].get()) # CHANGED.
class Child1(tk.Toplevel):
def __init__(self, master):
tk.Toplevel.__init__(self, master)
self.frame = tk.Frame(self)
self.title("Child")
self.label1 = tk.Label(self, text="Config 1", width=10)
self.label1.grid(row=0, column=0)
# ADDED `textvariable=` keyword argument.
self.child1_entry = tk.Entry(self, width=10,
textvariable=master.dic['child1_value'])
self.child1_entry.grid(row=0, column=1, padx=5, pady=5)
self.child1_entry.insert(tk.END, self.master.dic['var'][0])
self.child1_entry.bind('<Return>', self.update_value)
self.button4=tk.Button(self, text="Close", command=self.close_child1, width=20)
self.button4.grid(row=0, column=2, padx=5, pady=5)
self.button5=tk.Button(self, text="destroy", command=self.destroy_child1,
width=20)
self.button5.grid(row=0, column=3, padx=5, pady=5)
def update_value(self, event):
self.master.dic['var'][0] = self.master.Child1_from_parent.child1_entry.get()
def close_child1(self):
self.withdraw()
def destroy_child1(self):
self.destroy()
def main():
Parent().mainloop()
if __name__ == '__main__':
main()
If I understand your question correctly then this code may help.
It is a minimal demonstration of a one parent many children implementation.
All data and micro changes to each child are maintained after closing child.
Keyboard short-cuts give access to all children and parent
Parent is accessible while child is active.
Real exit is via gate keeper dialog from messagebox.
Creating children is easy and open ended.
import tkinter as tk
from tkinter.messagebox import askyesno
def flexx(m, r = 0, c = 0, rw = 1, cw = 1):
if r != None:
m.rowconfigure(r, weight = rw)
if c != None:
m.columnconfigure(c, weight = cw)
class child(tk.Toplevel):
def __init__(self, master, title, key):
super().__init__(master)
self.transient(master)
self.title(title)
flexx(self)
self.protocol('WM_DELETE_WINDOW', self.toggle)
self.bind('<Escape>', self.toggle)
self.bind(key, self.toggle)
def toggle(self, event = None):
'''toggle child on|off'''
if self.winfo_viewable():
self.withdraw()
else:
self.deiconify()
self.focus_force()
class parent(tk.Tk):
def __init__(self, title, icon = None):
super().__init__()
self.title(title)
flexx(self)
self.protocol('WM_DELETE_WINDOW', self.closer)
self.bind('<Escape>', self.closer)
if icon:
self.iconbitmap(default = icon)
self.withdraw()
def maker(self, title, key, geom):
anon = child(self, title, key)
# Connect parent and child
self.bind(key, anon.toggle)
anon.geometry(geom)
return anon
def closer(self, event = None):
if askyesno(
title = 'Confirm', message = 'Really',
detail = 'Close Program?', default = 'no'):
self.destroy()
if __name__ == '__main__':
the = parent('The Parent', icon = None) # icon = '.\\Icons\\Py-006.ico')
w,h,x,y = 500, 500, 100, 50
the.geometry(f'{w}x{h}+{x}+{y}')
the.boy = the.maker('harri', '<Control-h>', f'200x200+{x+w+5}+{y}')
the.girl = the.maker('suzie', '<Control-s>', f'200x200+{x+w+5}+{y+235}')
# make all other children
# inter-connect all children
the.girl.bind('<Control-h>', the.boy.toggle)
the.boy.bind('<Control-s>', the.girl.toggle)
the.deiconify()
the.mainloop( )

how to get a value out of a class's init function python

I am working with tkinter's class-based structure and I need to get a value of text input. How do I do that?
Here is the relevant code:
#GUI
class PseudostreamWidget(tk.Frame):
def __init__(self, master=None, **kw):
tk.Frame.__init__(self, master, **kw)
self.targetIP = tk.Entry(self.Ipconfig)
self.targetIP.configure(background='black', font='{Lato} 12 {}', foreground='white', highlightbackground='black')
self.targetIP.configure(highlightcolor='black', justify='left', relief='raised')
_text_ = '''Friend's Public IP Here'''
self.targetIP.delete('0', 'end')
self.targetIP.insert('0', _text_)
self.targetIP.grid(column='1', row='0')
#
#
#
target_ip = self.targetIP
#
#
How do I get it to print target_ip outside the class?
if __name__ == '__main__':
root = tk.Tk()
widget = PseudostreamWidget(root)
widget.pack(expand=True, fill='both')
root.mainloop()
print(target_ip)
Try this:
import tkinter as tk
class PseudostreamWidget(tk.Frame):
def __init__(self, master=None, callback=None, **kwargs):
super().__init__(master, **kwargs)
self.targetIP = tk.Entry(self, fg="white", justify="left",
relief="raised", highlightbackground="black",
highlightcolor="black", bg="black",
insertbackground="white", font=("Lato", 12))
# self.targetIP.delete(0, "end") # No need for this
self.targetIP.insert(0, "Friend's Public IP Here")
self.targetIP.grid(column=1, row=0)
self.targetIP.bind("<Return>", callback)
def submit_data(event=None):
print("You typed in:", widget.targetIP.get())
root = tk.Tk()
widget = PseudostreamWidget(root, callback=submit_data)
widget.pack()
root.mainloop()
To use it just write something inside the entry and press the Enter key on your keyboard.
It passes in a function (submit_data) and binds to it.

Tkinter Python- function which can access data from other tabs

I would like to create a function in Main_Application which would access data from other tabs... how can i achieve it?
I was trying to access it by typing "Page_2.entry2.insert(0, "test")" but it returns Attribute error
I would appreciate any kind of help as i am struggling with it for some time already
class Main_Application(tk.Tk):
def __init__(self):
super().__init__()
self.title("HAT")
first_label = ttk.Label(self, text="lol").pack()
#Notebook
nb = ttk.Notebook(self)
nb.pack()
#Frames
p1 = tk.Frame(nb)
p2 = tk.Frame(nb)
p3 = tk.Frame(nb)
p4 = tk.Frame(nb)
nb.add(p1, text="Page1")
nb.add(p2, text="Page2")
nb.add(p3, text="Page3")
nb.add(p4, text="Page4")
Page_1(p1).pack()
Page_2(p2).pack()
def load_it_all(self):
print(Page_01(self).user_input.get())
Page_02.entry2.insert(0, "test")
# <HERE I WOULD LIKE TO CALL THE DATA FROM
#First one prints the data from Page_01 and second i would like to insert data in Page_02.entry2
class Page_1(ttk.Frame):
def __init__(self, container):
super().__init__(container)
#Stringvar
self.user_input = tk.StringVar()
#Labels
label = ttk.Label(self, text="HU3: ")
#Entries
entry = ttk.Entry(self, textvariable=self.user_input)
#Inserts
entry.insert(0, "4500")
#Buttons
button = ttk.Button(self, text="Apply", command=lambda: Main_Application.load_it_all(self))
#Geo
label.pack()
entry.pack()
button.pack()
def test(self):
print(self.user_input.get())
class Page_2(ttk.Frame):
def __init__(self, container):
super().__init__(container)
self.user_input = tk.StringVar()
label = ttk.Label(self, text="Trend from last cycle ")
#Entries
entry2 = ttk.Entry(self, textvariable=self.user_input)
#Inserts
# self.entry2.insert(0, "4500")
#Buttons
# button = ttk.Button(self, text="Apply", command=self.test2)
#Geo
label.pack()
entry2.pack()
# button.pack()
Your issues included
improperly initiating super
too many containers
randomly using ttk widgets
poor understanding of scope
naming syntax errors
unnecessary vars
Below is a working example of what you are trying to do
import tkinter as tk, tkinter.ttk as ttk
class Main(tk.Tk):
def __init__(self):
#this is how to properly init a super
tk.Tk.__init__(self)
#make notebook fill display
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
#Notebook
nb = ttk.Notebook(self)
nb.grid(row=0, column=0, sticky='nswe')
#keep a reference to the pages
self.p1 = Page_1(self)
self.p2 = Page_2(self)
#tabs
nb.add(self.p1, text="Page 1")
nb.add(self.p2, text="Page 2")
def load_it_all(self):
#use the page references to access and share data
self.p2.input = self.p1.input
class Page_1(tk.Frame):
#property
def input(self):
return self.userinput.get()
#input.setter
def input(self, value):
self.userinput.delete(0, 'end')
self.userinput.insert(0, value)
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
tk.Label(self, text="HU3: ").grid(row=0, column=0)
self.userinput = tk.Entry(self)
self.userinput.grid(row=0, column=1)
self.input="4500"
tk.Button(self, text="Apply", command=master.load_it_all).grid(row=0, column=2)
class Page_2(tk.Frame):
#property
def input(self):
return self.userinput.get()
#input.setter
def input(self, value):
self.userinput.delete(0, 'end')
self.userinput.insert(0, value)
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
tk.Label(self, text="Trend from last cycle ").grid(row=0, column=0)
self.userinput = tk.Entry(self)
self.userinput.grid(row=0, column=1)
if __name__ == "__main__":
root = Main()
root.geometry('800x600')
root.title("HAT")
root.mainloop()

Python 3 - Tkinter nameError

NameError: name 'onOpen' is not defined
There is something wrong with the command function. I am not sure what I did wrong here. I had the code tested before the onOpen function and it works fine.
import tkinter as tk
from tkinter import filedialog
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.createWidgets()
def onOpen():
""" Ask the user to choose a file and update the values of label change button"""
button_label.set(filedialog.askopenfilename(filetypes = ()))
def createWidgets(self):
#instruction label
self.labelInstruct = tk.Label(self, text="Instructions:", padx=10, pady=10)
self.labelInstruct = tk.Label(self, text="All you have to do is insert the file and save it.\n The conversion is instant", padx=10, pady=10)
self.labelInstruct.pack()
#insertfile button
self.ifbut = tk.Button(self, text="Insert File", command=onOpen)
self.ifbut.pack()
button_label = tk.StringVar(self)
text = tk.Label(self, textvariable = button_label)
text.pack()
#save button
self.saveLabel = tk.Label(self, text="Save File", padx=10, pady=10)
self.saveLabel.pack()
self.saveButton = tk.Button(self)
self.saveButton.pack()
#quit button
self.quitButton = tk.Button(self, text='Quit',
command=self.quit)
self.quitButton.pack()
app = Application()
app.master.title('Sample application')
app.mainloop()
Seeing that there are many problems with the way this code is written I am only going to point out a few of them and tackle the main question from the OP.
Lets start with the fact that you need to define the main window with something like root = tk.Tk() and you also need to make sure all your methods in your class have the argument self as the first argument.
Also any variable you are defining also should have self so that the class can interact with it. This (button_label) for example should be self.button_label.
There is no reason to use return the way you are trying to in the onOpen(self): method. Return does not work like that. Return is there so you can return a value to something that is calling the function/method to be used for something else and is not for setting the value of something.
Note that I also add the root window variable to the app = Application(root) line. This lets us pass the main window into the class.
all and all the following should work for the onOpen(self): function but the rest still needs some work.
import tkinter as tk
from tkinter import filedialog
class Application(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.pack()
self.createWidgets()
def onOpen(self):
""" Ask the user to choose a file and update the values of label change button"""
self.button_label.set(filedialog.askopenfilename(filetypes = ()))
def createWidgets(self):
#instruction label
self.labelInstruct = tk.Label(self.parent, text="Instructions:", padx=10, pady=10)
self.labelInstruct = tk.Label(self.parent, text="All you have to do is insert the file and save it.\n The conversion is instant", padx=10, pady=10)
self.labelInstruct.pack()
#insert file button
self.ifbut = tk.Button(self.parent, text="Insert File", command = self.onOpen)
self.ifbut.pack()
self.button_label = tk.StringVar()
self.text = tk.Label(self.parent, textvariable = self.button_label)
self.text.pack()
#save button
self.saveLabel = tk.Label(self.parent, text="Save File", padx=10, pady=10)
self.saveLabel.pack()
self.saveButton = tk.Button(self.parent, text = "Save")
self.saveButton.pack()
#quit button
self.quitButton = tk.Button(self.parent, text='Quit', command=self.quit)
self.quitButton.pack()
root = tk.Tk()
app = Application(root)
app.master.title('Sample application')
app.mainloop()
You need to return the function value as below:
def onOpen():
""" Ask the user to choose a file and update the values of label change button"""
return button_label.set(filedialog.askopenfilename(filetypes = ()))

Adding python functionality to Tkinter front end

This is the front end I developed for my application using Tkinter:
from Tkinter import *
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Simple")
self.pack(fill=BOTH, expand=1)
frame = Frame(self, relief="flat", borderwidth=1)
label=Label(frame,text="Scope:")
label.pack(side="left", fill=None, expand=False)
var = StringVar()
var.set("today")
list = OptionMenu(frame, var, "today","yesterday","this week","last week","this month","last month")
list.pack(side="left", fill=None, expand=False)
fetchButton = Button(frame, text="Fetch",command=self.handle(var))
fetchButton.pack(side="left", fill=None, expand=False)
frame.grid(row=1,column=1,pady=4,padx=5,sticky=W)
area = Text(self,height=15,width=60)
area.grid(row=2,column=1,rowspan=1,pady=4,padx=5)
scroll = Scrollbar(self)
scroll.pack(side=RIGHT, fill=Y)
area.config(yscrollcommand=scroll.set)
scroll.config(command=area.yview)
scroll.grid(row=2, column=2, sticky='nsew')
quitButton = Button(self, text="Cancel",command=self.quit)
quitButton.grid(pady=4,padx=5,sticky=W,row=3, column=1)
root = Tk()
app = Example(root)
root.mainloop()
Where exactly do I have to put the handle() method so it can write repeatedly to the text widget? When I put handle() within the Example class and use self.area.insert(), it shows an error saying
Example instance has no attribute 'area'
Please help out.
You need to pass the function object to the Button instance, not a function call. i.e.
fetchButton = Button(frame, text="Fetch",command=self.handle)
To make the handle work in the context of the rest of the code:
from Tkinter import *
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.parent.title("Simple")
self.pack(fill=BOTH, expand=1)
self.init_ui()
def init_ui(self):
self.frame = Frame(self, relief="flat", borderwidth=1)
self.frame.grid(row=1,column=1,pady=4,padx=5,sticky=W)
self.label=Label(self.frame,text="Scope:")
self.label.pack(side="left", fill=None, expand=False)
self.var = StringVar()
self.var.set("today")
self.list = OptionMenu(self.frame, self.var, "today","yesterday",
"this week","last week","this month",
"last month")
self.list.pack(side="left", fill=None, expand=False)
self.fetchButton = Button(self.frame, text="Fetch",command=self.handle)
self.fetchButton.pack(side="left", fill=None, expand=False)
self.area = Text(self,height=15,width=60)
self.area.grid(row=2,column=1,rowspan=1,pady=4,padx=5)
self.scroll = Scrollbar(self)
self.scroll.pack(side=RIGHT, fill=Y)
self.area.config(yscrollcommand=self.scroll.set)
self.scroll.config(command=self.area.yview)
self.scroll.grid(row=2, column=2, sticky='nsew')
self.quitButton = Button(self, text="Cancel",command=self.quit)
self.quitButton.grid(pady=4,padx=5,sticky=W,row=3, column=1)
def handle(self):
self.area.delete(1.0, END)
self.area.insert(CURRENT,self.var.get())
if __name__ == "__main__":
root = Tk()
app = Example(root)
root.mainloop()
Declaring your widgets as attributes will save you a lot of pain an suffering as your application expands. Also keeping references to everything in Tk can stop some unwanted garbage collection, particularly with images in Label instances.
It is also worth noting that using grid and pack interchangeably is likely to lead to bugs later on.

Categories

Resources