On 07/27/2016 04:04 AM, Alan Gauld via Tutor wrote:
On 27/07/16 04:44, Jim Byrnes wrote:
OOP has always driven me crazy. I read the material and follow the
examples until I feel I understand them, but when I try to implement it
I end up with an error filled mess.
That suggests that its not the OOP concept thats confusing
you but the language syntax. How to turn the concept into code?
That's exactly my problem, which is why I am solving problems with OOP
when it's not necessary. I wanted the practice.
So I decided to give it another try. When I got to the chapter on
tkinter I decided to solve all the exercises using OOP even though the
book solutions did not use OOP. The first one went fine:
Actually not as fine as you thought. In effect you got lucky by
making a mistake that still resulted in your code doing
approximately what you expected. But it didn't really do
what you thought it did.
import tkinter
class Goodbye:
def __init__(self):
self.frame = tkinter.Frame(window)
self.frame.pack()
You are using a global variable as your parent here. It would be
better to pass that in as an argument. Or better still to make
the call to Tk() inside the __init__ method. That's not really
an OOP thing though just a general good practice issue.
It's best to avoid relying on global variables in your
functions.
Ok thanks. When I wrote that I was mimicking the style used in the
book. I have read about avoiding globals if possible, but didn't think
it through.
self.goodbye_button = tkinter.Button(self.frame, text='Goodbye',
#command=quit)
command=lambda: quit() )
self.goodbye_button.pack()
Here you assign quit to the button's command. That's OK because
there is a top level built-in function called quit which exits
the interpreter. It's a bit of a brutal way to exit your GUI
but it works.
But I guess you really wanted to call your quit method. Remember
to access anything in your class you have to use the self
prefix, so you should have said:
command=self.quit
or
command=lambda: self.quit()
Lambda doesn't really help in this case but it doesn't do
any harm either.
def quit():
self.window.destroy()
When you define a method inside a class you need to
explicitly include the self parameter. So this should be:
def quit(self):
self.window.destroy()
But there's a snag, you don't store the window inside the
class. So self.window will cause an error. You either need
a line like
self.window = window
in your__init__ method
or use the global window variable like
def quit():
window.destroy()
My preference would be to create a self.window instance variable,
inside init()then access the self.window in quit(). You would also
call mainloop() using self.window in your init()
if __name__=='__main__':
window = tkinter.Tk()
myapp = Goodbye()
window.mainloop()
So if you took my advice this section of code would look like:
if __name__=='__main__':
Goodbye()
and init() would look like:
def __init__(self):
self.window = tkinter.Tk()
self.frame = tkinter.Frame(self.window)
self.frame.pack()
self.goodbye_button = tkinter.Button(self.frame, text='Goodbye',
command=self.quit)
self.goodbye_button.pack()
self.window.mainloop()
If you read through that and understand it, it should give
you the clues as to why the second one behaved as it did.
Ok thanks. I don't want to belabor the point but I basically had it
that way because I didn't know any better. Now I know of a
different/better way to do it.
Regards, Jim
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor