Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #21025 > unrolled thread
| Started by | John Salerno <johnjsal@gmail.com> |
|---|---|
| First post | 2012-02-28 21:06 -0800 |
| Last post | 2012-03-03 20:27 -0800 |
| Articles | 20 on this page of 32 — 7 participants |
Back to article view | Back to comp.lang.python
Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-28 21:06 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Rick Johnson <rantingrickjohnson@gmail.com> - 2012-02-29 06:24 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Terry Reedy <tjreedy@udel.edu> - 2012-02-29 19:17 -0500
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Rick Johnson <rantingrickjohnson@gmail.com> - 2012-02-29 19:22 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Terry Reedy <tjreedy@udel.edu> - 2012-03-01 00:24 -0500
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Rick Johnson <rantingrickjohnson@gmail.com> - 2012-03-01 18:49 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Rick Johnson <rantingrickjohnson@gmail.com> - 2012-03-01 19:02 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Terry Reedy <tjreedy@udel.edu> - 2012-03-01 22:43 -0500
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Terry Reedy <tjreedy@udel.edu> - 2012-03-02 15:19 -0500
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Mel Wilson <mwilson@the-wire.com> - 2012-03-02 15:52 -0500
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? "Russell E. Owen" <rowen@uw.edu> - 2012-03-05 11:45 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-29 21:40 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Rick Johnson <rantingrickjohnson@gmail.com> - 2012-03-01 18:53 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Mark Roseman <mark@markroseman.com> - 2012-03-02 10:57 -0700
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-03-02 10:53 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-29 20:41 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Terry Reedy <tjreedy@udel.edu> - 2012-03-01 00:40 -0500
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-29 21:45 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-29 22:14 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Rick Johnson <rantingrickjohnson@gmail.com> - 2012-03-01 18:55 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-29 22:14 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-29 21:45 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-29 22:41 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-29 22:41 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-03-01 07:38 +0000
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-02-29 23:58 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Rick Johnson <rantingrickjohnson@gmail.com> - 2012-03-01 18:35 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-03-01 19:15 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Rick Johnson <rantingrickjohnson@gmail.com> - 2012-03-01 19:19 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-03-01 21:22 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? John Salerno <johnjsal@gmail.com> - 2012-03-02 14:16 -0800
Re: Is it necessary to call Tk() when writing a GUI app with Tkinter? Rick Johnson <rantingrickjohnson@gmail.com> - 2012-03-03 20:27 -0800
Page 1 of 2 [1] 2 Next page →
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-02-28 21:06 -0800 |
| Subject | Is it necessary to call Tk() when writing a GUI app with Tkinter? |
| Message-ID | <27603449.17.1330492001624.JavaMail.geo-discussion-forums@vbbfv2> |
The book I'm reading about using Tkinter only does this when creating the top-level window:
app = Application()
app.mainloop()
and of course the Application class has subclassed the tkinter.Frame class.
However, in the Python documentation, I see this:
root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()
Is it necessary to explicitly call Tk(), then pass that result as an argument for the Application call? Is it also necessary to call destroy() on the root frame?
I tried the above and I got the following error:
Traceback (most recent call last):
File "C:\Users\John\Desktop\gui.py", line 12, in <module>
root.destroy()
File "C:\Python32\lib\tkinter\__init__.py", line 1714, in destroy
self.tk.call('destroy', self._w)
_tkinter.TclError: can't invoke "destroy" command: application has been destroyed
So apparently closing the window with the X button (on Windows) implicitly calls the destroy() method of the root frame. If that's the case, why does the documentation explicitly call it?
Furthermore, I pasted the exact example from the documentation into IDLE and ran it, and I also go the same error, so the example in the documentation doesn't even work.
So is it sufficient simply to create an Application instance, use mainloop, and then handle the closing of the window elsewhere in the program (such as a widget calling the destroy method on-click, or just letting the X button do it)?
Thanks!
[toc] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2012-02-29 06:24 -0800 |
| Message-ID | <6e1c521e-14be-4ec0-9ff0-7f23fd9cd3dc@f14g2000yqe.googlegroups.com> |
| In reply to | #21025 |
On Feb 28, 11:06 pm, John Salerno <johnj...@gmail.com> wrote:
> The book I'm reading about using Tkinter only does this when creating the top-level window:
>
> app = Application()
> app.mainloop()
>
> and of course the Application class has subclassed the tkinter.Frame class.
>
> However, in the Python documentation, I see this:
>
> root = Tk()
> app = Application(master=root)
> app.mainloop()
> root.destroy()
>
> Is it necessary to explicitly call Tk(), then pass that result as an argument for the Application call? Is it also necessary to call destroy() on the root frame?
It is not necessarily to call Tk explicitly, which i think is a bug
BTW. Sure, for simple scripts you can save one line of code but only
at the expense of explicitness and intuitiveness. Observe
## START CODE ##
import Tkinter as tk
root = tk.Tk()
root.title('Explicit Root')
root.mainloop()
f = tk.Frame(master=None, width=100, height=100, bg='red')
f.pack()
f.mainloop()
b = tk.Button(master=None, text='Sloppy Coder')
b.pack()
b.mainloop()
## END CODE ##
as you can see all three examples work even though the last two don't
explicitly create a master. The master is still there however Tkinter
just created "magically" for you. Talk about laziness!
> I tried the above and I got the following error:
>
> Traceback (most recent call last):
> File "C:\Users\John\Desktop\gui.py", line 12, in <module>
> root.destroy()
> File "C:\Python32\lib\tkinter\__init__.py", line 1714, in destroy
> self.tk.call('destroy', self._w)
> _tkinter.TclError: can't invoke "destroy" command: application has been destroyed
>
> So apparently closing the window with the X button (on Windows) implicitly calls the destroy() method of the root frame. If that's the case, why does the documentation explicitly call it?
Because the documentation is FLAWED! Please provide links to this
"documentation" so we can post it on the Wall Of Shame.
> Furthermore, I pasted the exact example from the documentation into IDLE and ran it, and I also go the same error, so the example in the documentation doesn't even work.
IDLE uses the same Python as the command line so naturally it will
throw the same error. ;-)
> So is it sufficient simply to create an Application instance, use mainloop, and then handle the closing of the window elsewhere in the program (such as a widget calling the destroy method on-click, or just letting the X button do it)?
Most applications will have both: user destroying, and program
destroying. Again, your example is FLAWED. Here is a simplified
example:
## START CODE ##
from tkMessageBox import askyesnocancel
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title('Close Me -->')
self.protocol("WM_DELETE_WINDOW", self.onDestroyWindow)
def onDestroyWindow(self):
title = 'Confirm App Exit'
msg = 'Save changes before exiting?'
result = askyesnocancel(title, msg, default='cancel')
if result is None:
return
elif result is True:
print 'saving changes'
elif result is False:
print 'dont save changes'
self.destroy()
if __name__ == '__main__':
app = App()
app.mainloop()
## END CODE ##
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-02-29 19:17 -0500 |
| Message-ID | <mailman.306.1330561055.3037.python-list@python.org> |
| In reply to | #21040 |
On 2/29/2012 9:24 AM, Rick Johnson wrote:
> On Feb 28, 11:06 pm, John Salerno<johnj...@gmail.com> wrote:
>> However, in the Python documentation, I see this:
>>
>> root = Tk()
>> app = Application(master=root)
>> app.mainloop()
>> root.destroy()
>> I tried the above and I got the following error:
>>
>> Traceback (most recent call last):
>> File "C:\Users\John\Desktop\gui.py", line 12, in<module>
>> root.destroy()
>> File "C:\Python32\lib\tkinter\__init__.py", line 1714, in destroy
>> self.tk.call('destroy', self._w)
>> _tkinter.TclError: can't invoke "destroy" command: application has been destroyed
>>
>> So apparently closing the window with the X button (on Windows)
>> implicitly calls the destroy() method of the root frame.
>> If that's the case, why does the documentation explicitly call it?
I do not know if tk has changed since the example was written or if it
was buggy from the beginning. I opened an issue to fix it.
http://bugs.python.org/issue14163
> Most applications will have both: user destroying, and program
> destroying.
> from tkMessageBox import askyesnocancel
from tkinter.messagebox in 3.x
> class App(tk.Tk):
> def __init__(self):
> tk.Tk.__init__(self)
> self.title('Close Me -->')
> self.protocol("WM_DELETE_WINDOW", self.onDestroyWindow)
>
> def onDestroyWindow(self):
> title = 'Confirm App Exit'
> msg = 'Save changes before exiting?'
> result = askyesnocancel(title, msg, default='cancel')
> if result is None:
> return
> elif result is True:
> print 'saving changes'
> elif result is False:
> print 'dont save changes'
> self.destroy()
>
> if __name__ == '__main__':
> app = App()
> app.mainloop()
This works as adjusted for 3.x. I presume that a quit button or menu
entry should also call onDestroyWindow so the effect is the same as
clicking the outer [X] button.
I tried the same approach to fix the doc example, but unlike your class
App(Tk), class App(Frame) does not a .protocol attribute. See the
tracker issue for all my comments on the example.
I considered removing both the quit button and 'root.destroy' to get a
beginning example that works properly, but as you said, having both is
common so I would like both if the solution is not too esoteric.
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2012-02-29 19:22 -0800 |
| Message-ID | <c556fe7d-3f45-4479-8b81-cc0c25af41a2@f2g2000yqh.googlegroups.com> |
| In reply to | #21056 |
On Feb 29, 6:17 pm, Terry Reedy <tjre...@udel.edu> wrote:
> On 2/29/2012 9:24 AM, Rick Johnson wrote:
> > On Feb 28, 11:06 pm, John Salerno<johnj...@gmail.com> wrote:
> >> However, in the Python documentation, I see this:
>
> >> root = Tk()
> >> app = Application(master=root)
> >> app.mainloop()
> >> root.destroy()
> >> I tried the above and I got the following error:
>
> >> Traceback (most recent call last):
> >> File "C:\Users\John\Desktop\gui.py", line 12, in<module>
> >> root.destroy()
> >> File "C:\Python32\lib\tkinter\__init__.py", line 1714, in destroy
> >> self.tk.call('destroy', self._w)
> >> _tkinter.TclError: can't invoke "destroy" command: application has been destroyed
>
> >> So apparently closing the window with the X button (on Windows)
>
> >> implicitly calls the destroy() method of the root frame.
> >> If that's the case, why does the documentation explicitly call it?
>
> I do not know if tk has changed since the example was written or if it
> was buggy from the beginning. I opened an issue to fix it.
>
> http://bugs.python.org/issue14163
"protocol" is ONLY a method of Tkinter.Tk and Tkinter.Toplevel.
Actually Toplevel and Tk are exactly the same object but Tk has an TCL
interpretor attached. Tkinter.Tk is meant to be the parent of ALL
widgets within your Tkinter GUI. Tkinter.Frame is nothing more than a
box to stuff widgets into. Tkinter.Frame IS NOT a window and therefor
it DOES NOT have window methods.
HOWEVER!
Most people start falsely believing that a Tkinter.Frame AND
Tkinter.Toplevel are the same thing; since Tkinter will "auto-
magically" pack your frame into a default Tkinter.Tk window (psst:
that's just a fancy Toplevel widget!) if you don't explicitly create
the Tk instance yourself.
>>>Slightly tangential meanderings
This inconsistency also rears it's ugly head in the dialog modules:
tkFileDialog and tkMessageBox. Both of which do not require a parent
argument to their convenience functions. Instead they allow the parent
to be OPTIONALLY passed.
Inquisitive Ivan mused: """ What's wrong with that Rick, the dialog
will still display whether a parent argument is passed or not. Heck,
even if no viable parent exists, Tkinter will create one! Tkinter is a
smart module!"""
True Ivan. However, if you dig a little deeper you will see that the
dialog created WITHOUT a parent does not function in a manner
consistent to modal dialogs; that is, owning the focus and becoming a
transient of another Toplevel window.
Also, about your second point, noobs get confused when that default
root window pops up. Then they come here and ask the same question
over and over. Can't you see the design flaw that is directly in front
of your face NOR smell the pungent odors that reeking from this
module!
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Some might argue that this implicit root window creation is beneficial
for toy GUIs -- and i agree! HOWEVER, you will due enormous damage to
a neophyte's learning process. I say just force the extra line of code
and be consistent. Actually i believe SO strongly in "explicit root
window creation" that i edited the source code of my Tkinter version
to NOT allow ANY widget's master to be None.
I had written a more exhaustive "expo-say" some time back but i
cannot remember the title.
> > Most applications will have both: user destroying, and program
> > destroying.
> > from tkMessageBox import askyesnocancel
>
> from tkinter.messagebox in 3.x
Yes, Tkinter has changed a bit in Python>=3.0, thanks for pointing
this out.
> [...snip code...]
> This works as adjusted for 3.x. I presume that a quit button or menu
> entry should also call onDestroyWindow so the effect is the same as
> clicking the outer [X] button.
Yes, but i think the REAL problem is faulty code logic. Remove the
last line "root.destroy()" and the problem is solved. Obviously the
author does not have an in-depth knowledge of Tkinter.
> I tried the same approach to fix the doc example, but unlike your class
> App(Tk), class App(Frame) does not a .protocol attribute. See the
> tracker issue for all my comments on the example.
see above comments about Tkinter.Frame, Tkinter.Toplevel, and
Tkinter.Tk ^^^
> I considered removing both the quit button and 'root.destroy' to get a
> beginning example that works properly, but as you said, having both is
> common so I would like both if the solution is not too esoteric.
If you want to keep things simple, i would:
1. Create the root window explicitly!
2. Bind the command of the button to root.destroy
(command=root.destroy)
I would offer better advice if i could but i have no idea where this
"book the OP is learning" is located? No one ever provided a link to
the code in question?
PS: I would highly suggest against using the "from Tkinter import *".
Instead, use "import Tkinter as tk" and prefix all module contents
with "tk.". Also, use "from Tkconstants import X, Y, X"
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-03-01 00:24 -0500 |
| Message-ID | <mailman.313.1330579461.3037.python-list@python.org> |
| In reply to | #21061 |
On 2/29/2012 10:22 PM, Rick Johnson wrote:
I do not know what book the OP is referring to,
but the current doc example is
http://docs.python.org/py3k/library/tkinter.html#a-simple-hello-world-program
My current replacement (see below) can be downloaded from the tracker:
http://bugs.python.org/issue14163
> If you want to keep things simple, i would:
>
> 1. Create the root window explicitly!
It already does that.
> 2. Bind the command of the button to root.destroy
> (command=root.destroy)
That works great. My current replacement example is uploaded to the
issue http://bugs.python.org/issue14163
> PS: I would highly suggest against using the "from Tkinter import *".
> Instead, use "import Tkinter as tk" and prefix all module contents
> with "tk.".
I have changed the example to do that. I also showed the alternate to
initialize a widget. Here is the current version, tested on Windows 3.2.2.
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.createWidgets()
def createWidgets(self):
self.hi_there = tk.Button(self)
self.hi_there["text"] = "Hello_World\n(click_me)",
self.hi_there["command"] = self.say_hi
self.hi_there.pack({"side": "top"})
self.QUIT = tk.Button(self, text = "QUIT", fg = "red", command
= root.destroy)
self.QUIT.pack({"side": "bottom"})
def say_hi(self):
print("hi there, everyone!")
root = tk.Tk()
app = Application(master=root)
app.mainloop()
There is a minor problem left. The hi_there Button text has underscores
because if I use spaces instead, tk surrounds the text with {bra ces}.
This seems bizarre. Is there any way to have Button text with spaces and
no braces?
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2012-03-01 18:49 -0800 |
| Message-ID | <3d0bf288-fa5d-48e5-9529-db92d420a915@1g2000yqv.googlegroups.com> |
| In reply to | #21069 |
On Feb 29, 11:24 pm, Terry Reedy <tjre...@udel.edu> wrote:
> On 2/29/2012 10:22 PM, Rick Johnson wrote:
> > PS: I would highly suggest against using the "from Tkinter import *".
> > Instead, use "import Tkinter as tk" and prefix all module contents
> > with "tk.".
>
> I have changed the example to do that. I also showed the alternate to
> initialize a widget. Here is the current version, tested on Windows 3.2.2.
>
> import tkinter as tk
>
> class Application(tk.Frame):
> def __init__(self, master=None):
> tk.Frame.__init__(self, master)
> self.pack()
With all due respect, I would also recommend against "self packing" a
widget. And i can speak from experience on this issue. There was a
time when i was self-packing lots of custom compund widgets; then i
realized later the shortcomings of such action; what if you need to
use the grid or place geometry mangers instead? So remove the
self.pack line and add a line to the bottom:
> root = tk.Tk()
> app = Application(master=root)
> app.pack() # <-- added this line
> app.mainloop()
> There is a minor problem left. The hi_there Button text has underscores
> because if I use spaces instead, tk surrounds the text with {bra ces}.
> This seems bizarre. Is there any way to have Button text with spaces and
> no braces?
Not sure what is happening on your end, but i don't see any braces. In
any event, here is a slightly modified version of your code that
follows PEP8 and removes some inconsistencies.
## START CODE ##
# Python < 3.0
import Tkinter as tk
from Tkconstants import TOP, BOTTOM
from tkMessageBox import showinfo
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.createWidgets()
def createWidgets(self):
self.hi_there = tk.Button(self)
self.hi_there["text"] = "Hello_World\n(click_me)"
self.hi_there["command"] = self.say_hi
self.hi_there.pack() # !!!
self.qbutton = tk.Button(self, text="Close Application",
fg="red", command=root.destroy)
self.qbutton.pack() # !!!
def say_hi(self):
showinfo('Modal Dialog', "hi there, everyone!", parent=self)
print("hi there, everyone!")
if __name__ == '__main__':
root = tk.Tk()
app = Application(master=root)
app.pack()
app.mainloop()
## END CODE ##
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2012-03-01 19:02 -0800 |
| Message-ID | <e44882a2-12d8-4068-a127-03131631ab19@t15g2000yqi.googlegroups.com> |
| In reply to | #21108 |
On Mar 1, 8:49 pm, Rick Johnson <rantingrickjohn...@gmail.com> wrote:
> On Feb 29, 11:24 pm, Terry Reedy <tjre...@udel.edu> wrote:
>
> > On 2/29/2012 10:22 PM, Rick Johnson wrote:
> > > PS: I would highly suggest against using the "from Tkinter import *".
> > > Instead, use "import Tkinter as tk" and prefix all module contents
> > > with "tk.".
>
> > I have changed the example to do that. I also showed the alternate to
> > initialize a widget. Here is the current version, tested on Windows 3.2.2.
>
> > import tkinter as tk
>
> > class Application(tk.Frame):
> > def __init__(self, master=None):
> > tk.Frame.__init__(self, master)
> > self.pack()
>
> With all due respect, I would also recommend against "self packing" a
> widget. And i can speak from experience on this issue. There was a
> time when i was self-packing lots of custom compund widgets; then i
> realized later the shortcomings of such action; what if you need to
> use the grid or place geometry mangers instead? So remove the
> self.pack line and add a line to the bottom:
>
> > root = tk.Tk()
> > app = Application(master=root)
> > app.pack() # <-- added this line
> > app.mainloop()
> > There is a minor problem left. The hi_there Button text has underscores
> > because if I use spaces instead, tk surrounds the text with {bra ces}.
> > This seems bizarre. Is there any way to have Button text with spaces and
> > no braces?
>
> Not sure what is happening on your end, but i don't see any braces. In
> any event, here is a slightly modified version of your code that
> follows PEP8 and removes some inconsistencies.
>
> ## START CODE ##
> # Python < 3.0
> import Tkinter as tk
> from Tkconstants import TOP, BOTTOM
> from tkMessageBox import showinfo
>
> class Application(tk.Frame):
> def __init__(self, master=None):
> tk.Frame.__init__(self, master)
> self.createWidgets()
>
> def createWidgets(self):
> self.hi_there = tk.Button(self)
> self.hi_there["text"] = "Hello_World\n(click_me)"
> self.hi_there["command"] = self.say_hi
> self.hi_there.pack() # !!!
> self.qbutton = tk.Button(self, text="Close Application",
> fg="red", command=root.destroy)
> self.qbutton.pack() # !!!
>
> def say_hi(self):
> showinfo('Modal Dialog', "hi there, everyone!", parent=self)
> print("hi there, everyone!")
>
> if __name__ == '__main__':
> root = tk.Tk()
> app = Application(master=root)
> app.pack()
> app.mainloop()
> ## END CODE ##
Opps, i just realized that "App" is actually a Tkinter.Frame and not a
Tkinter.Toplevel. So the line:
showinfo('Modal Dialog', "hi there, everyone!", parent=self)
...is broken. Since we don't have a reference to the root window from
inside the scope of this Frame class, we can use
"self.winfo_toplevel()" to fetch a reference.
showinfo('Modal Dialog', "hi there, everyone!",
parent=self.winfo_toplevel())
...ahhh! That should work perfectly now!
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-03-01 22:43 -0500 |
| Message-ID | <mailman.335.1330659825.3037.python-list@python.org> |
| In reply to | #21108 |
On 3/1/2012 9:49 PM, Rick Johnson wrote:
> On Feb 29, 11:24 pm, Terry Reedy<tjre...@udel.edu> wrote:
>> There is a minor problem left. The hi_there Button text has underscores
>> because if I use spaces instead, tk surrounds the text with {bra ces}.
>> This seems bizarre. Is there any way to have Button text with spaces and
>> no braces?
>
> Not sure what is happening on your end, but i don't see any braces.
Are you saying that if you change "Hello_World\n(click_me)" to
"Hello World\n(click me)", you see
Hello World
(click me)
as I expected, instead of
{Hellow World
(click me)}
as I do see? What OS are you running? And what tk version? (I have 8.5.9
in Win7)
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-03-02 15:19 -0500 |
| Message-ID | <mailman.352.1330719597.3037.python-list@python.org> |
| In reply to | #21108 |
On 3/1/2012 10:43 PM, Terry Reedy wrote:
>> Not sure what is happening on your end, but i don't see any braces.
>
> Are you saying that if you change "Hello_World\n(click_me)" to
> "Hello World\n(click me)", you see
>
> Hello World
> (click me)
>
> as I expected, instead of
>
> {Hellow World
> (click me)}
>
> as I do see? What OS are you running? And what tk version? (I have 8.5.9
> in Win7)
The problem was another subtle bug in the current example":
self.hi_there["text"] = "Hello",
The spurious comma at the end makes the value of the 'text' attribute a
one-elememt tuple and not just a string. I presume tcl-based tk handles
that in the manner appropriate for the tcl equivalent. I believe tcl
uses spaces rather than commas to separate items, so the braces serve as
'quotes' to indicate that the contents are one item, not three. Removing
the comma solves the problem.
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Mel Wilson <mwilson@the-wire.com> |
|---|---|
| Date | 2012-03-02 15:52 -0500 |
| Message-ID | <jirbub$jg6$1@speranza.aioe.org> |
| In reply to | #21146 |
Terry Reedy wrote: > The problem was another subtle bug in the current example": > self.hi_there["text"] = "Hello", > > The spurious comma at the end makes the value of the 'text' attribute a > one-elememt tuple and not just a string. I presume tcl-based tk handles > that in the manner appropriate for the tcl equivalent. I believe tcl > uses spaces rather than commas to separate items, so the braces serve as > 'quotes' to indicate that the contents are one item, not three. Removing > the comma solves the problem. That looks like it. Tcl is the 'LISP of strings' Composite-object things like indexing work on space-separated strings. Mel.
[toc] | [prev] | [next] | [standalone]
| From | "Russell E. Owen" <rowen@uw.edu> |
|---|---|
| Date | 2012-03-05 11:45 -0800 |
| Message-ID | <mailman.408.1330976772.3037.python-list@python.org> |
| In reply to | #21108 |
In article <3d0bf288-fa5d-48e5-9529-db92d420a915@1g2000yqv.googlegroups.com>, Rick Johnson <rantingrickjohnson@gmail.com> wrote: > On Feb 29, 11:24 pm, Terry Reedy <tjre...@udel.edu> wrote: > > On 2/29/2012 10:22 PM, Rick Johnson wrote: > > > > PS: I would highly suggest against using the "from Tkinter import *". > > > Instead, use "import Tkinter as tk" and prefix all module contents > > > with "tk.". > > > > I have changed the example to do that. I also showed the alternate to > > initialize a widget. Here is the current version, tested on Windows 3.2.2. > > > > import tkinter as tk > > > > class Application(tk.Frame): > > def __init__(self, master=None): > > tk.Frame.__init__(self, master) > > self.pack() > > With all due respect, I would also recommend against "self packing" a > widget. And i can speak from experience on this issue. There was a > time when i was self-packing lots of custom compund widgets; then i > realized later the shortcomings of such action; what if you need to > use the grid or place geometry mangers instead? So remove the > self.pack line and add a line to the bottom: > > > root = tk.Tk() > > app = Application(master=root) > > app.pack() # <-- added this line > > app.mainloop() I agree. Application is simply another widget, like Entry or Canvas. its contents should be packed or gridded (as appropriate) into itself, but the user should then pack or grid the Application widget as appropriate. That makes the code much more reusable. -- Russell
[toc] | [prev] | [next] | [standalone]
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-02-29 21:40 -0800 |
| Message-ID | <22943242.772.1330580414345.JavaMail.geo-discussion-forums@ynil17> |
| In reply to | #21061 |
> Yes, but i think the REAL problem is faulty code logic. Remove the
> last line "root.destroy()" and the problem is solved. Obviously the
> author does not have an in-depth knowledge of Tkinter.
The faulty code is not my own, which is part of the reason I asked the question. The book I'm reading (The Quick Python Book) does not use it, but I saw in the Python docs that it is there, under "tkinter" in the Global Module Docs, "24.1.2.2. A Simple Hello World Program":
from tkinter import *
class Application(Frame):
def say_hi(self):
print("hi there, everyone!")
def createWidgets(self):
self.QUIT = Button(self)
self.QUIT["text"] = "QUIT"
self.QUIT["fg"] = "red"
self.QUIT["command"] = self.quit
self.QUIT.pack({"side": "left"})
self.hi_there = Button(self)
self.hi_there["text"] = "Hello",
self.hi_there["command"] = self.say_hi
self.hi_there.pack({"side": "left"})
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.createWidgets()
root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2012-03-01 18:53 -0800 |
| Message-ID | <fb7d19c3-95e1-440d-b375-087857f851f9@n12g2000yqb.googlegroups.com> |
| In reply to | #21071 |
On Feb 29, 11:40 pm, John Salerno <johnj...@gmail.com> wrote:
> The faulty code is not my own, which is part of the reason I asked
> the question. The book I'm reading (The Quick Python Book) does not
> use it, but I saw in the Python docs that it is there, under
> "tkinter" in the Global Module Docs, "24.1.2.2. A Simple Hello World
> Program":
Book authors and Doc authors are not always the most well informed; as
we have witnessed by this very thread!
> from tkinter import *
don't do that!
> class Application(Frame):
> def say_hi(self):
> print("hi there, everyone!")
>
> def createWidgets(self):
> self.QUIT = Button(self)
> self.QUIT["text"] = "QUIT"
> self.QUIT["fg"] = "red"
> self.QUIT["command"] = self.quit
>
> self.QUIT.pack({"side": "left"})
don't do that either! Widgets take optional keyword arguments now so
stop passing in dictionaries.
self.quit.pack(side=tk.LEFT)
Obviously these tutorials are more like: "What NOT to do when coding
Tkinter GUIs!" No wonder everyone hates Tkinter. :-)
[toc] | [prev] | [next] | [standalone]
| From | Mark Roseman <mark@markroseman.com> |
|---|---|
| Date | 2012-03-02 10:57 -0700 |
| Message-ID | <mark-074310.10573402032012@news.eternal-september.org> |
| In reply to | #21112 |
Rick Johnson <rantingrickjohnson@gmail.com> wrote: > Book authors and Doc authors are not always the most well informed; as > we have witnessed by this very thread! Obviously these tutorials are more > like: "What NOT to do when coding Tkinter GUIs!" No wonder everyone hates Tkinter. :-) Indeed. One of the things that motivated me to write the tutorial at http://www.tkdocs.com is the rather poor state (in terms of being out of date, incorrect, or demonstrating poor practices) of most Tkinter documentation. Call it self-serving, but I think the Tkinter world would be a happier place if everyone just pointed to TkDocs. ;-) To your point about explicit root, etc. I'll make the general observation that lots of different things work in a given situation, which is just fine for quick little hacky things. If people are doing anything more than a throwaway however, they'd be better served by spending a bit of time learning the conceptual underpinnings (e.g. http://www.tkdocs.com/tutorial/concepts.html) after which the "right" thing to do will be more obvious. Mark
[toc] | [prev] | [next] | [standalone]
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-03-02 10:53 -0800 |
| Message-ID | <14334956.332.1330714438657.JavaMail.geo-discussion-forums@vbux23> |
| In reply to | #21137 |
> Indeed. One of the things that motivated me to write the tutorial at > http://www.tkdocs.com is the rather poor state (in terms of being out of > date, incorrect, or demonstrating poor practices) of most Tkinter > documentation. > > Call it self-serving, but I think the Tkinter world would be a happier > place if everyone just pointed to TkDocs. ;-) > > To your point about explicit root, etc. I'll make the general > observation that lots of different things work in a given situation, > which is just fine for quick little hacky things. If people are doing > anything more than a throwaway however, they'd be better served by > spending a bit of time learning the conceptual underpinnings (e.g. > http://www.tkdocs.com/tutorial/concepts.html) after which the "right" > thing to do will be more obvious. > > Mark Nice. I shall be spending some time at your website. I actually like wxPython, but I decided to learn a little Tkinter because it's already included and would be an easier and quicker option for small interfaces.
[toc] | [prev] | [next] | [standalone]
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-02-29 20:41 -0800 |
| Message-ID | <17153317.324.1330576905540.JavaMail.geo-discussion-forums@yncd8> |
| In reply to | #21040 |
> It is not necessarily to call Tk explicitly, which i think is a bug
> BTW. Sure, for simple scripts you can save one line of code but only
> at the expense of explicitness and intuitiveness. Observe
>
> ## START CODE ##
> import Tkinter as tk
>
> root = tk.Tk()
> root.title('Explicit Root')
> root.mainloop()
>
> f = tk.Frame(master=None, width=100, height=100, bg='red')
> f.pack()
> f.mainloop()
>
> b = tk.Button(master=None, text='Sloppy Coder')
> b.pack()
> b.mainloop()
> ## END CODE ##
>
> as you can see all three examples work even though the last two don't
> explicitly create a master. The master is still there however Tkinter
> just created "magically" for you. Talk about laziness!
I'm not sure I understand which method you are advocating. It sounded like you said calling Tk() explicitly is a bug. I certainly would never create widgets without first creating a master frame, but is creating a Frame object enough, or should I create a Tk object and *then* a Frame object?
Also, at what point do you include the destroy method in your program, assuming you do not have a widget that will close the window? If you only want the Windows "X" button to close the window, then is it okay to leave out any call to destroy()? Or should always explicitly destroy it just as I explicitly created a Tk instance? If the latter, then where in the code do you put the call to destroy so it won't conflict with the user closing the window with the X button?
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-03-01 00:40 -0500 |
| Message-ID | <mailman.315.1330580460.3037.python-list@python.org> |
| In reply to | #21066 |
On 2/29/2012 11:41 PM, John Salerno wrote: > window? If you only want the Windows "X" button to close the window, > then is it okay to leave out any call to destroy()? Yes. You must leave it out. > the latter, then where in the code do you put the call to destroy so > it won't conflict with the user closing the window with the X > button? See my other post of a few minutes ago for an example that now works. -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-02-29 21:45 -0800 |
| Message-ID | <18841978.1037.1330580728432.JavaMail.geo-discussion-forums@vbgu10> |
| In reply to | #21072 |
On Wednesday, February 29, 2012 11:40:45 PM UTC-6, Terry Reedy wrote: > On 2/29/2012 11:41 PM, John Salerno wrote: > > > window? If you only want the Windows "X" button to close the window, > > then is it okay to leave out any call to destroy()? > > Yes. You must leave it out. > > > the latter, then where in the code do you put the call to destroy so > > it won't conflict with the user closing the window with the X > > button? > > See my other post of a few minutes ago for an example that now works. > > -- > Terry Jan Reedy When you suggested I create the root frame explicitly, you mean create a Tk object explicitly, as in your example, and then pass that as an argument to the Frame instance? What exactly is the purpose of doing that? Does Tk do some extra work that a simple call to Frame won't do?
[toc] | [prev] | [next] | [standalone]
| From | John Salerno <johnjsal@gmail.com> |
|---|---|
| Date | 2012-02-29 22:14 -0800 |
| Message-ID | <28139175.898.1330582481406.JavaMail.geo-discussion-forums@ynbo36> |
| In reply to | #21074 |
> What exactly is the purpose of doing that? Does Tk do some extra work that a simple call to Frame won't do? More specifically, what is the benefit of doing: root = tk.Tk() app = Application(master=root) app.mainloop() as opposed to: app = Application() app.mainloop() Also, in the first example, what is the difference between calling app.mainloop() and root.mainloop()? They both seemed to work when I ran them.
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2012-03-01 18:55 -0800 |
| Message-ID | <bd781b2b-1826-4b87-9718-2cb0e03593f8@f14g2000yqe.googlegroups.com> |
| In reply to | #21076 |
On Mar 1, 12:14 am, John Salerno <johnj...@gmail.com> wrote: > > What exactly is the purpose of doing that? Does Tk do some extra work that a simple call to Frame won't do? > > More specifically, what is the benefit of doing: > > root = tk.Tk() > app = Application(master=root) > app.mainloop() > > as opposed to: > > app = Application() > app.mainloop() > > Also, in the first example, what is the difference between calling app.mainloop() and root.mainloop()? They both seemed to work when I ran them. I tell you what. Just keep coding Tkinter GUIs like these broken docs tell you to, than after you become proficient you will understand. You will say: "That Rick really knew what he was talking about after all!"
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web