[Tutor] TKinter display dialog 2nd time?

Abel Daniel abli@freemail.hu
Thu Mar 20 15:25:02 2003


Bob Gailer wrote:
> 
> I find it amusing that, having stated a month or so ago that I have no 
> interest in TKinter, now I'm using it. I find the various reference 
> materials to be inadequate to help me really understand what's going on. 
> The immediate problem is, I want to display a dialog, allow the user to 
> close it, then display it again. Attempts to display it again lead to no 
> results or errors
> 
[snipped code]
> So far so good.
> 
> If I follow this with another app.mainloop(), nothing happens.
> 
> If I follow this with app = App('txt') I get:
> ....
[snipped traceback]
I'm not much of a Tkinter expert, so what I say might be wrong.

I added an 'from Tkinter import *' at the top.
The font = 'arial 8, txt' thing didnt work, so i got rid of that.
with these modifications, the following works:

from Tkinter import *
class App(Frame):
  def __init__(self, txt='Start', parent=Tk()):
    Frame.__init__(self, parent)
    self.pack()
    self.Label = Label(self, text = 'arial 8, txt')
    self.Label.pack({"side": "top"})
    self.QUIT = Button(self, text = "OK", command = self.quit)
    self.QUIT.pack({"side": "top"})

if __name__ == '__main__':
  app = App('txt')
  app.mainloop()
  print 'hi'
  #app = App('txt')
  app.mainloop()

This shows the dialog, after clicking on OK, 'hi' gets printed to the console.
The dialog looks unchanged, but after clicking on it, the program exits.
I don't get the problems you mention. (even if I uncomment the second
app=App(txt) line).

Anyway, I don't think you should be doing this. 

First some observations to the code you posted:
If you want to display a dialog box, you should inherit form Toplevel,
not Frame. If you inherit any widget, you shouldn't pack() it in it's
__init__, as that should be the responsibility of the class that uses it.
Standard widgets don't pack themselves, so yours shouldn't, either.
(For example what if I want to use grid instead of pack?)
Personally I wouldn't hardcode font information like that. (Imagine having
to change the font if you have more than a handfull of classes like this.
Not to mention that this gave an error for me on python version 2.1.3 :
TclError: expected integer but got "8,")
I think that parent=Tk() trick is wrong. I would do it like this:

class App(Toplevel):
    def __init__(self, txt='Start'):
        Toplevel.__init__(self)
        self.Label = Label(self, text = 'txt')
        self.Label.pack({"side": "top"})
        self.QUIT = Button(self, text = "OK", command = self.quit)
        self.QUIT.pack({"side": "top"})

if __name__ == '__main__':
    app = App('txt')
    app.mainloop()

But even this is not what you need. You want to show a dialog window, close
it, then show it again. The 'have to calls to mainloop' idea won't fly,
because the window stays visible. (Try it with 'import time' adding
a 'time.sleep(0.5)' call between the to calls to mainloop.)

I think what you really need is the tkMessageBox module. With that,
you can do things like 

if tkMessageBox.askyesno('title of dialog', 'do this?'):
        # do it
else:
        # dont do it

I think this would be the simplest way of adding a few dialog windows to an
otherwise non-gui program. (Thats what you are doing, right?)

Hope this helps,
Abel Daniel