From: Matt Gushee Date: 2002-11-03T11:22:09+09:00 Subject: Re: PullDownList -- failings are obvioius On Sun, Nov 03, 2002 at 10:17:40AM +0900, Alan (Ursus Major) wrote: > > This start at a pulldown list accepts insertions, accepts a callback > method. > It does /not/ yet accept parenting or keys during initialization. > There is a problem with packing with the 'pd = PullDown.new.pack' statement. That's because @frame doesn't have a parent. So when you create a PullDown instance, you need to pass it a parent widget, and then create @frame as a child of that parent. Also, if you intend for this widget to be reusable, you should try to make it conform as closely as possible to normal Tk widget behavior. Concretely, that means two things: 1) Initialize should return self, not @frame. 2) You should override pack(), place(), and grid() like so: def pack(*args) @frame.pack(*args) end My rule of thumb in creating compound widgets is that the base class should be the class whose behavior is most useful to expose ... in this case that's presumably TkListbox, so you've started off all right: > class PullDown < TkListbox But this really confuses things: > @frame.pack > end In fact, that's not just un-Tk-like, it violates the expectations of just about every OO programmer on the planet, since it means that PullDown.new doesn't return an instance of PullDown! However, in order to properly pack your compound widget, the component that receives the pack() call has to be the outermost container, which of course is your @frame . So you need to provide a pack() method (and I suppose unpack() too) that delegates to @frame. The other alternative would be to subclass from TkFrame. Then the logical object structure would match the physical widget hierarchy, and you would have to mess around with pack(), place(), and grid(). But that probably isn't what you want, because once you've constructed the widget, you will most likely never need to invoke any other methods on the outer frame ... but you will very likely need to invoke some methods on the listbox itself, so you would end up having to write a ton of methods to delegate to the listbox. As for the more general question of the best way to construct a drop-down list ... well, Tk has somewhat limited capabilities, so there aren't too many alternatives. The only question I have about your approach is, when the lower section is displayed, what happens to the widgets that are already there? Or is the entire root window going to get resized? Something like that has to happen to give your thingie a space to appear in. Not pretty. Of course, there's a better solution than that ... though I wouldn't call it a good one, and it's certainly not easy: use a Toplevel window for the dropdown section. Then you have to deal with the window manager to get screen x & y so you can position your Toplevel correctly. Like I said, it's not easy. But if you think you want to try it, I may have some code lying around (probably Python) that I could dig up as a sample. If none of the above sounds acceptable, you may just have to work with a different GUI toolkit. Unless someone else knows some other interesting tricks. -- Matt Gushee When a nation follows the Way, Englewood, Colorado, USA Horses bear manure through mgushee@havenrock.com its fields; http://www.havenrock.com/ When a nation ignores the Way, Horses bear soldiers through its streets. --Lao Tzu (Peter Merel, trans.)