0

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.

0

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

The reason you were getting that error is because you did not declare area as an attribute. If you change all your area instances to self.area, this will solve the problem.
Thanks, works cool. But my handle() method contains some heavy functionality and it takes at least 5 mins for the first self.area.insert() to be called. When I click on the window in the meantime, the title bar shows Not Responding and the whole window goes gray. Some way to handle that?
looks like I have to use multithreading to tackle Not Responding. thanks anyway.
Yep, sounds like you need to spawn the handle method in a new thread.

Your Answer

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.