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? > 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. > 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. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor