Re: (n00b) Tkinter trouble

2011-11-16 Thread Jason Swails
On Tue, Nov 15, 2011 at 10:49 PM, Chris Angelico  wrote:

> On Wed, Nov 16, 2011 at 2:02 PM, Jason Swails 
> wrote:
> > Apparently I could not do what I was wanting to (state=DISABLED is not a
> > valid option to Toplevel).  What I wanted to do was something similar to
> > what the dialogs were doing from tkMessageBox.
>
> Yes, that would be what you'd want. I wonder, though: Is Toplevel the
> right window class? There may be a better class for a subwindow.
> Again, I'm not familiar with Tkinter, but a quick google suggests that
> Frame or Window might be worth looking into. Ideally, you want the
> window to disable its parent and claim all events.
>

I think Toplevel is right.  Frame isn't actually a window (a window has to
be its parent), and I've never seen any documentation regarding a Window
class (perhaps it's just meant to be a base class that Toplevel inherits
from?).  I think a separate window needs to be a Toplevel instance (or
instance of a Toplevel-derived class).

Pulling on the tkMessageBox example again, their base Dialog class inherits
from Toplevel.  In any case, I've actually found that Tkinter is relatively
straightforward to learn, despite some of the bashing it's received here
(admittedly I've never tried PyGTK or wxpython or any of the other toolkits
because I want to keep dependencies within the stdlib as much as possible).

Thanks!
Jason
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: (n00b) Tkinter trouble

2011-11-15 Thread Chris Angelico
On Wed, Nov 16, 2011 at 2:02 PM, Jason Swails  wrote:
> Apparently I could not do what I was wanting to (state=DISABLED is not a
> valid option to Toplevel).  What I wanted to do was something similar to
> what the dialogs were doing from tkMessageBox.

Yes, that would be what you'd want. I wonder, though: Is Toplevel the
right window class? There may be a better class for a subwindow.
Again, I'm not familiar with Tkinter, but a quick google suggests that
Frame or Window might be worth looking into. Ideally, you want the
window to disable its parent and claim all events.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: (n00b) Tkinter trouble

2011-11-15 Thread Jason Swails
On Tue, Nov 15, 2011 at 12:32 AM, Chris Angelico  wrote:

>
> As a general rule, if any parent is invisible, you won't see the
> child, and if any parent is disabled, you can't access the child.


Yea, I'm becoming more familiar and comfortable with the GUI hierarchy as I
play around.  I do like how simple it is to test a concept in Tkinter (just
a couple lines builds you a window with any kind of widget you want).


> You
> may find that there's even a one-line command that will disable the
> window, open a new window, wait for the new window to close, and
> automatically reenable the window - an "open modal dialog" function or
> something.
>

Apparently I could not do what I was wanting to (state=DISABLED is not a
valid option to Toplevel).  What I wanted to do was something similar to
what the dialogs were doing from tkMessageBox.  The window didn't appear
changed, but no buttons could be clicked.  After looking through the
tkMessageBox.py source code, I found the method I was looking for:
grab_set.  Essentially, I just have to have my new window call its
grab_set() method to hog all events.  Not really "disabling" the root
window (which is why I had a hard time finding it on Google), but it's the
exact behavior I was looking for.
http://www.python-forum.org/pythonforum/viewtopic.php?f=15&t=4930 was
helpful here.

The only other approach I (successfully) tried was to use the .withdraw()
method on the window during the constructor of the *new* window and execute
.deiconify() on it during the new window's destroy() method (before calling
Toplevel's destroy on self).  I still like the first way better.

Thanks!
Jason
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: (n00b) Tkinter trouble

2011-11-14 Thread Chris Angelico
On Tue, Nov 15, 2011 at 4:18 PM, Jason Swails  wrote:
> Of course!  Windows are widgets just like everything else is, and so can be
> configured to be in the DISABLED state just like a button can.  I'm not used
> to this hierarchy in which the root window presides over all, yet is still a
> widget just like everything else.
>
> But there's a lot of GUI programming that I haven't wrapped my head around
> yet (which is why I'm running with this pet project -- but it's bound to be
> ugly :)).

Heh, I grew up on OS/2 and everything was an object. (With a few
exceptions; the minimize/maximize/close buttons are all a single
object, rather than being three.) It's not normal to disable the title
bar while leaving the window enabled, but if you want to, you can!

As a general rule, if any parent is invisible, you won't see the
child, and if any parent is disabled, you can't access the child. You
may find that there's even a one-line command that will disable the
window, open a new window, wait for the new window to close, and
automatically reenable the window - an "open modal dialog" function or
something.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: (n00b) Tkinter trouble

2011-11-14 Thread Jason Swails
On Mon, Nov 14, 2011 at 3:49 AM, Chris Angelico  wrote:

> On Mon, Nov 14, 2011 at 6:11 PM, Jason Swails 
> wrote:
> > Then, I can reactivate all of the buttons in the destroy() method before
> > calling the destroy() method of Toplevel on self.
>
> Small side point that might save you some work: Instead of disabling
> and enabling all the buttons, disable the whole window. I don't know
> Tkinter well enough to know if there's an easy way to create a modal
> window, but the thing to do is to disable the entire window rather
> than just its command buttons - that's the least astonishing[1] user
> interface technique.
>

Of course!  Windows are widgets just like everything else is, and so can be
configured to be in the DISABLED state just like a button can.  I'm not
used to this hierarchy in which the root window presides over all, yet is
still a widget just like everything else.

But there's a lot of GUI programming that I haven't wrapped my head around
yet (which is why I'm running with this pet project -- but it's bound to be
ugly :)).

Thanks!
Jason
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: (n00b) Tkinter trouble

2011-11-14 Thread Chris Angelico
On Mon, Nov 14, 2011 at 6:11 PM, Jason Swails  wrote:
> Then, I can reactivate all of the buttons in the destroy() method before
> calling the destroy() method of Toplevel on self.

Small side point that might save you some work: Instead of disabling
and enabling all the buttons, disable the whole window. I don't know
Tkinter well enough to know if there's an easy way to create a modal
window, but the thing to do is to disable the entire window rather
than just its command buttons - that's the least astonishing[1] user
interface technique.

ChrisA

[1] http://en.wikipedia.org/wiki/Principle_of_least_astonishment
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: (n00b) Tkinter trouble

2011-11-13 Thread Jason Swails
On Sun, Nov 13, 2011 at 1:27 PM, Jason Swails wrote:

> Hello,
>
> I'm trying my hand at creating a Tkinter application, but not having much
> luck.  I'm trying to have my top level window be a series of buttons with
> different options on them.  Every time a button is pressed, it opens up a
> new window with options.  While that new window is open, all of the buttons
> on the original window are disabled.  However, I want all of those buttons
> to become active again once I quit my new window.  I can't seem to
> reactivate those buttons no matter what I do.
>
> This is the approach I'm trying:
>
> #!/usr/bin/env python
>
> from Tkinter import *
>
> class ActionButton(Button):
>def __init__(self, frame, text):
>   self.frame = frame
>   Button.__init__(self, master=self.frame, text=text,
> command=self.execute)
>def execute(self):
>   window = Toplevel()
>   new_button = ActionButton(window, '2nd level button')
>   quit_button = Button(window, text='Quit!', command=window.destroy)
>   window.buttons = [new_button, quit_button]
>   for button in window.buttons: button.pack()
>   # Deactivate buttons from containing shell
>   for button in self.frame.buttons: button.config(state=DISABLED)
>   window.mainloop()
>   for button in self.frame.buttons: button.config(state=ACTIVE)
>
>
> top = Tk()
> top_button = ActionButton(top, 'Button on top!')
> top_button.pack()
> quit_button = Button(top, text='Quit', command=top.destroy)
> quit_button.pack()
>
> top.buttons = [top_button, quit_button]
>
> top.mainloop()
>
> I'm really kind of running around in the dark here, so any advice or
> explanation is appreciated.
>

Another approach I think will work, and that I'm going to try, is to
subclass Toplevel and simply assign the higher-level frame/window as an
instance attribute.  Then, I can reactivate all of the buttons in the
destroy() method before calling the destroy() method of Toplevel on self.
Something like this:

[untested]

class MyToplevel(Toplevel):

   def __init__(self, root, **options):
  self.root = root
  Toplevel.__init__(self, options)
  for button in self.root.buttons: button.config(state=DISABLED)

   def destroy(self):
  for button in self.root.buttons: button.config(state=ACTIVE)
  Toplevel.destroy(self)

This allows me to avoid running "mainloop()" on a non-root Toplevel
instance, but links the re-activation of the buttons with the destruction
of the child window (which was the effect I was going for).  I must not
understand what mainloop() does, fully (does it only make sense to run it
on Tkinter.Tk()?)

Thanks!
Jason
-- 
http://mail.python.org/mailman/listinfo/python-list