RE: Tkinter Dialog Management problems:

Discussion in 'Python' started by Michael Yanowitz, May 18, 2006.

  1. > Hello:
    >
    > Below I have included a stripped down version of the GUI I am working
    > on.
    > It contains 2 dialog boxes - one main and one settings. It has the
    > following
    > problems, probably all related, that I am hoping someone knows what I am
    > doing wrong:
    >
    > 1) Pressing the Settings.. Button multiple times, brings up many
    > instances
    > of the Settings Panel. I just want it to bring up one. Is there an
    > easy
    > way to do that?


    In fact, the two windows you created are not dialogs; they're just
    windows. To turn a window into an actual "dialog", i.e basically to make
    it modal, you have to do the following operations (supposing your dialog
    window is named dlg and your main window in named root):

    ## Ensure only window can receive user events
    dlg.grab_set()
    ## Force Dialog to stay on top of main window
    dlg.transient(root)
    ## Wait for dialog to be destroyed
    root.wait_window(dlg)

    > 2) Pressing the Done button in the Settings Panel, just erases the Done
    > button
    > (and any other widgets in the Panel). It does not dismiss the Panel.
    > Pressing
    > the X button does work. What callback is that? Can I make the Done
    > button
    > call
    > that instead? How?


    This is not the way it works. In fact, what you did wrong is something
    that has been around for years in some Tkinter tutorial(s): you made your
    classes inherit from Frame. This is a Bad Idea: a Frame is not a window,
    but only a generic container. There are 2 classes for windows: Tk for the
    main window and Toplevel for all others. They both also act as containers,
    so you can do in them everything you do in Frames. So make your
    ScriptDialog inherit from Tk, your SettingsDialog inherit from Toplevel,
    remove all explicit creations of Tkinter.Tk or Tkinter.Toplevel and
    instantiate your classes instead. Then calling destroy on either on the
    dialogs will actually close the window.

    > 3) Pressing the Done button from the Main Panel has no effect? Why not?
    > It
    > used
    > to work (self.quit()). Again, I would like to call whatever is called
    > when the
    > X button (top Right corner) is pressed.


    This should work. BTW, your "done" method is not needed: creating the
    Button with command=self.quit works without problem.


    Thanks. That helped alot.
    However it leaves a couple very minor problems which I think I can live
    with.
    1) It brings up an empty additional 'main window'.
    I have tried using the Tkinter.NoDefaultRoot() option, but run into
    other problems with other things not defined.
    NameError: global name '_default_root' is not defined
    Exception exceptions.AttributeError: "IntVar instance has no attribute
    '_tk'" in
    <bound method IntVar.__del__ of <Tkinter.IntVar instance at 0x009C7990>>
    ignored

    2) By deriving the 'dialog' from Tk, existing calls to self.pack() no
    longer are valid, but they don't appear to be necessary.

    My only 'Tkinter tutorial' is what is included in Orielly's "Programming
    Python". Still looking for a good tutorial. I am not clear what the
    difference
    between Tk() and Toplevel() are. They seem totally interchangeable.
    Michael Yanowitz, May 18, 2006
    #1
    1. Advertising

  2. If you need a beginners tutorial for Tkinter, try this one :
    http://www.pythonware.com/library/tkinter/introduction/

    >> Hello:
    >>
    >> Below I have included a stripped down version of the GUI I am working
    >> on.
    >> It contains 2 dialog boxes - one main and one settings. It has the
    >> following
    >> problems, probably all related, that I am hoping someone knows what I am
    >> doing wrong:
    >>
    >> 1) Pressing the Settings.. Button multiple times, brings up many
    >> instances
    >> of the Settings Panel. I just want it to bring up one. Is there an
    >> easy
    >> way to do that?

    >
    > In fact, the two windows you created are not dialogs; they're just
    > windows. To turn a window into an actual "dialog", i.e basically to make
    > it modal, you have to do the following operations (supposing your dialog
    > window is named dlg and your main window in named root):
    >
    > ## Ensure only window can receive user events
    > dlg.grab_set()
    > ## Force Dialog to stay on top of main window
    > dlg.transient(root)
    > ## Wait for dialog to be destroyed
    > root.wait_window(dlg)
    >
    >> 2) Pressing the Done button in the Settings Panel, just erases the Done
    >> button
    >> (and any other widgets in the Panel). It does not dismiss the Panel.
    >> Pressing
    >> the X button does work. What callback is that? Can I make the Done
    >> button
    >> call
    >> that instead? How?

    >
    > This is not the way it works. In fact, what you did wrong is something
    > that has been around for years in some Tkinter tutorial(s): you made your
    > classes inherit from Frame. This is a Bad Idea: a Frame is not a window,
    > but only a generic container. There are 2 classes for windows: Tk for the
    > main window and Toplevel for all others. They both also act as containers,
    > so you can do in them everything you do in Frames. So make your
    > ScriptDialog inherit from Tk, your SettingsDialog inherit from Toplevel,
    > remove all explicit creations of Tkinter.Tk or Tkinter.Toplevel and
    > instantiate your classes instead. Then calling destroy on either on the
    > dialogs will actually close the window.
    >
    >> 3) Pressing the Done button from the Main Panel has no effect? Why not?
    >> It
    >> used
    >> to work (self.quit()). Again, I would like to call whatever is called
    >> when the
    >> X button (top Right corner) is pressed.

    >
    > This should work. BTW, your "done" method is not needed: creating the
    > Button with command=self.quit works without problem.
    >
    >
    > Thanks. That helped alot.
    > However it leaves a couple very minor problems which I think I can live
    > with.
    > 1) It brings up an empty additional 'main window'.
    > I have tried using the Tkinter.NoDefaultRoot() option, but run into
    > other problems with other things not defined.
    > NameError: global name '_default_root' is not defined
    > Exception exceptions.AttributeError: "IntVar instance has no attribute
    > '_tk'" in
    > <bound method IntVar.__del__ of <Tkinter.IntVar instance at 0x009C7990>>
    > ignored
    >
    > 2) By deriving the 'dialog' from Tk, existing calls to self.pack() no
    > longer are valid, but they don't appear to be necessary.
    >
    > My only 'Tkinter tutorial' is what is included in Orielly's "Programming
    > Python". Still looking for a good tutorial. I am not clear what the
    > difference
    > between Tk() and Toplevel() are. They seem totally interchangeable.



    --
    ---
    Rony Steelandt
    BuCodi
    rony dot steelandt (at) bucodi dot com

    Visit the python blog at http://360.yahoo.com/bucodi
    Rony Steelandt, May 18, 2006
    #2
    1. Advertising

  3. Michael Yanowitz

    Eric Brunel Guest

    On Thu, 18 May 2006 11:52:54 -0400, Michael Yanowitz
    <> wrote:
    > Thanks. That helped alot.


    No problem.

    > However it leaves a couple very minor problems which I think I can live
    > with.
    > 1) It brings up an empty additional 'main window'.
    > I have tried using the Tkinter.NoDefaultRoot() option, but run into
    > other problems with other things not defined.
    > NameError: global name '_default_root' is not defined
    > Exception exceptions.AttributeError: "IntVar instance has no attribute
    > '_tk'" in
    > <bound method IntVar.__del__ of <Tkinter.IntVar instance at 0x009C7990>>
    > ignored
    >
    > 2) By deriving the 'dialog' from Tk, existing calls to self.pack() no
    > longer are valid, but they don't appear to be necessary.
    >
    > My only 'Tkinter tutorial' is what is included in Orielly's
    > "Programming
    > Python". Still looking for a good tutorial. I am not clear what the
    > difference
    > between Tk() and Toplevel() are. They seem totally interchangeable.


    No, they're not! Never - and I mean *never* - create two instances of Tk
    in the same application! The Tk instance does not only represent the main
    window for the application, but also creates the underlying tcl
    interpreter. Creating two instances of Tk will then create two
    interpreters and you'll never know which one executes your commands,
    producing weird TclError's everywhere.

    If you have a window which can be considered as the main window for your
    application - there is only one of it, it is always there and closing it
    means quitting the application -, then make it a sub-class of Tk. If you
    do not have such a window, use the following trick at the beginning of
    your application:

    root = Tkinter.Tk()
    root.withdraw()

    This basically creates a main window and immediately hides it. All your
    other windows must be sub-classes of Toplevel. Calling the quit method of
    these windows should still quit the application, and calling the destroy
    method should only close the window.

    As for tutorials, there are many; just see there:
    http://tkinter.unpy.net/wiki/Tkinter
    Apart from the one already given by Rony (which is more a reference than a
    tutorial), my favorite ones are:
    - Stephen Ferg's "Thinking in Tkinter" -
    http://www.ferg.org/thinking_in_tkinter/index.html
    - The one at http://doctormickey.com/python/index.html
    - Gerard Swinnen's "Apprendre a programmer avec Python" (in French) -
    http://www.cifen.ulg.ac.be/inforef/swi/python.htm
    At least, these ones avoid the confusion Frame/window usually found in
    many others: the first two don't use inheritance at all; only the last
    (the one in French) implements windows as sub-classes of Tk or Toplevel.
    Unfortunately, I don't know any english translation of it.

    A last advice: if you want to do serious Tkinter, it really helps to know
    how the underlying tcl/tk layer works. So maybe you should learn at least
    the basics of tcl/tk. And if you do that, you will be able to use tcl/tk
    resources, such as:
    http://www.tcl.tk/man/
    which is the only documentation I ever need now...

    HTH
    --
    python -c "print ''.join([chr(154 - ord(c)) for c in
    'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"
    Eric Brunel, May 19, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Floris van Haaster

    Project management / bug management

    Floris van Haaster, Sep 23, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    1,237
    Jon Paal
    Sep 23, 2005
  2. pouet
    Replies:
    2
    Views:
    752
    Will Hartung
    Jul 30, 2004
  3. Michael Yanowitz

    Tkinter Dialog Management problems:

    Michael Yanowitz, May 18, 2006, in forum: Python
    Replies:
    1
    Views:
    392
    Eric Brunel
    May 18, 2006
  4. yw
    Replies:
    3
    Views:
    814
    Phlip
    Jul 2, 2005
  5. Matt
    Replies:
    1
    Views:
    277
    Randy Webb
    Nov 20, 2004
Loading...

Share This Page