On Tue, 18 Oct 2005 22:30:33 -0400, Ron Provost <[EMAIL PROTECTED]> wrote:

> Hello,
>
> I'm using python 2.4.2 on Win XP Pro.  I'm trying to understand a behavior
> I'm seeing in some Tkinter code I have.  I've reduced my question to a small
> piece of code:
>
>
> #####BEGIN CODE
> #################
> import Tkinter as Tk
> import tkFont
>
> sampleText = """Here is a test string.  This is more text
> Here is a second line of text.  How much
> more can I type.  I can't think of anything else to type.
> """
>
> root = Tk.Tk( )
> t = Tk.Text( root )
> t.pack( )
>
> t.insert( Tk.END, sampleText )
>
> t.tag_config( 'AB', font=tkFont.Font( family='ariel', size=24,
> weight=tkFont.BOLD ) )
> t.tag_config( 'TBU', font=tkFont.Font( family='times', size=10,
> weight=tkFont.BOLD, underline=1 ) )

Here is what I think is happening:
- The first tag_config creates a font using tkFont.Font. At tcl level, this 
font is not known as an object as in Python, but just as a font name, which is 
a string. This name happens to be built using the internal identifier for the 
Python object.
- Once this tag_config is over, no Python variable references your tkFont.Font 
instance anymore. It is is fact still known at tcl level (via the font name), 
but Python doesn't know that. So the reference counter for your tkFont.Font 
instance falls to 0, and the object is discarded.
- The second tag_config seems to create a new font using tkFont.Font. 
Unfortunately, since the previous font has been discarded, the space occupied 
by this font is reused for the new font. So the new font happens to have the 
same internal identifier as the font object created by the first tkFont.Font. 
So its name is in fact the same as your previous font, and is registered as 
such at tcl level. So in fact, you didn't create a new font at tcl level, but 
modified the previous one.

All this actually happens by accident. If you add something allocating some 
memory between the two tag_config, you'll certainly see your code working. It 
works when I run it myself...

[snip]
> f1 = font=tkFont.Font( family='ariel', size=24, weight=tkFont.BOLD )
> f2 = font=tkFont.Font( family='times', size=10, weight=tkFont.BOLD,
> underline=1 )
> t.tag_config( 'AB', font=f1 )
> t.tag_config( 'TBU', font=f2 )

You should now see why it works here: your first tkFont.Font is remembered at 
Python level in a variable. So it is not discarded once the tag_config is over. 
So the second tkFont.Font is not allocated at the same location, so it doesn't 
have the same id, and it doesn't have the same name at tcl level. This is the 
general solution to the problem: keep your fonts in Python variables, so they 
won't be discarded and their names will never be re-used. You could have 
written:

f1 = font=tkFont.Font( family='ariel', size=24, weight=tkFont.BOLD )
t.tag_config( 'AB', font=f1 )
f2 = font=tkFont.Font( family='times', size=10, weight=tkFont.BOLD, underline=1 
)
t.tag_config( 'TBU', font=f2 )

This should still work. The order is not important; it's just the fact that 
your fonts are actually known at Python level which prevents Tkinter to reuse 
their name.

BTW, this is a variant of a well known problem biting newbies regularly, 
documented here:
http://tkinter.unpythonic.net/wiki/Images

It's basically the same problem for images: it does not suffice to reference an 
image at tcl level; it must also be referenced at Python level or it will be 
discarded by Python and you won't be able to use it in your widgets.

HTH
-- 
python -c "print ''.join([chr(154 - ord(c)) for c in 
'U(17zX(%,5.zmz5(17;8(%,5.Z65\'*9--56l7+-'])"
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to