Syntactic problems

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Syntactic problems

Francisco Gracia
Many thanks to you both, Kevin and Michael for your quick and sensible responses. My problems are more in the line suggested by Michael, although his hint has not solved them, at least as I have tried to implement it.

In order for you to have all the information together, I transcribe the original Tcl code and my *porting* of it to *tkinter*. I commented it for my own use, in the process of conjecturing and confirming what the original code was intended to perform.

If you run the original code with *tclsh* or *wish* and then my code with *Idle*, you will see very clearly where the problem lies.

Kind regards

Francisco

# original Tcl code
# offered as example in the *font manual page* of TkDocs.
# Runs without problems with *tclsh* and *wish*

# pack [text .t -wrap none] -fill both -expand 1
# set count 0
# set tabwidth 0
# foreach family [lsort -dictionary [font families]] {
#    .t tag configure f[incr count] -font [list $family 10]
#    .t insert end ${family}:\t {} \
#            "This is a simple sampler\n" f$count
#    set w [font measure [.t cget -font] ${family}:]
#    if {$w+5 > $tabwidth} {
#        set tabwidth [expr {$w+5}]
#        .t configure -tabs $tabwidth
#    }
# }


from tkinter import *
from tkinter import font


# creation of the main window
master = Tk()

# creation of a text widget
tw = Text( master )
tw.config( wrap = NONE )
tw.pack( fill = BOTH, expand = 1 )

tw.insert( END, "Display of available fonts:\n\n" )

count = 0
tabwidth = 0

# identification of the font being used
f1 = tw.cget( 'font' )

# a measurement function used later
# is a method of class *tkinter.font.Font*,
# so that it is good to have the required instance of it
fo = font.Font( font = ( f1, 10 ) )

# let us get the ordered list of all
# available font families
sampler = sorted( list( font.families() ) )

# handling and display of the elements
for f in sampler :
    # the counter is updated
    count += 1
    # display of the provided font name plus
    # a separator and a tabulator
    tw.insert( END, f + ":\t" )
    # creation of an individual name for the tag
    # that will be applied to the sample for this item
    ftag = f + str( count )

    # my (vain) efforts to solve the multiword problem
    if ' ' in f :
#        fm = "('" + f + "', '10')"   # as for Michael's hint
        fm = '[list ' + f + ']'
#        fm = f.replace( ' ', '_' )
#        fm = f.replace( ' ', '' )
        tw.tag_config( ftag, font = ( fm, 10 ) )
#        tw.tag_config( ftag, font = fm )
    else :
        # single word names work as expected
        tw.tag_config( ftag, font = ( f, 10 ) )
    # and the sample text:
    tw.insert( END, "This is a simple sampler\n", ftag )
   
    # nice columnar disposition by
    # a clever configuration of the tabulator
    w = fo.measure( f + ':' )
    if ( w + 5 ) > tabwidth :
        tabwidth = w + 5
        # this equalizes all the lines as required
        tw.config( tabs = tabwidth )

if __name__ == '__main__' :
    master.mainloop()




_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Syntactic problems

Michael Lange
Hi Francisco,

Thus spoketh Francisco Gracia <[hidden email]>
unto us on Sat, 3 Dec 2011 18:48:36 +0100:

> Many thanks to you both, Kevin and Michael for your quick and sensible
> responses. My problems are more in the line suggested by Michael,
> although his hint has not solved them, at least as I have tried to
> implement it.

The problem in you code is not the white space in the font name but the
white space in the tag name (actually this is where the python code
differs from the tcl example, maybe due to a typo).
I changed (the relevant part of) your code into:

for f in sampler :
    # the counter is updated
    count += 1
    # display of the provided font name plus
    # a separator and a tabulator
    tw.insert( END, f + ":\t" )
    # creation of an individual name for the tag
    # that will be applied to the sample for this item

    ftag =  'f' + str( count )# please note the quotes !

    tw.tag_config( ftag, font = ( f, 10 ) )
    # and the sample text:
    tw.insert( END, "This is a simple sampler\n", ftag )

and then it worked as expected.

Best regards

Michael

.-.. .. ...- .   .-.. --- -. --.   .- -. -..   .--. .-. --- ... .--. . .-.

First study the enemy.  Seek weakness.
                -- Romulan Commander, "Balance of Terror", stardate 1709.2
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Syntactic problems

Francisco Gracia


2011/12/3 Michael Lange <[hidden email]> said:

Hi Francisco,
 
The problem in you code is not the white space in the font name but the
white space in the tag name ...

You are right, Michael, that was a mistake on my side. It was not a typo, but a
confusion due to my bad knowledge of *Tcl*'s syntax and to my not
having given due consideration to the bussines at hand. Changing the name of the tag to an only word eliminates the problem in this case and the tag's handling becomes unproblematic.

... and then it worked as expected.

But with this not all problems are solved. Although the display
varies with the machine used, if one scans carefully
the whole output, one usually finds one or more lines where long font
names of several words invade the area of the samples display; this should not happen and does not happen with Tcl's script. This is due to the
malfunction of the measuring function and in this case one cannot
avoid that the string to be measured has several words; on the contrary this should be the normal case.

It seems however that I have been lucky enough to find an apparently general solution. You can see it in the transcription of the whole script that follows; for the moment this seems to be my final version.

I even consider the patch general because it also solves the difficulty of your initial sample code, so that while

>>> c = 'Bitstream Vera Sans 12'
>>> l.config(font=c)

continues originating an error,

>>> c = '"[list Bitstream Vera Sans 12]"'
>>> l.config(font=c)

seems to work.

I want to thank you very much for your kindness and your interest.

Best regards

Francisco

# *Sampler.py*
# Display the names of the typographical fonts
# available in the present machine
# with a sample of the appearance of each one.

# Python version of the following *Tcl* code
# offered as example in the *font* manual page of *TkDocs*:

# pack [text .t -wrap none] -fill both -expand 1
# set count 0
# set tabwidth 0
# foreach family [lsort -dictionary [font families]] {
#    .t tag configure f[incr count] -font [list $family 10]
#    .t insert end ${family}:\t {} \
#            "This is a simple sampler\n" f$count
#    set w [font measure [.t cget -font] ${family}:]
#    if {$w+5 > $tabwidth} {
#        set tabwidth [expr {$w+5}]
#        .t configure -tabs $tabwidth
#    }
# }


from tkinter import *
from tkinter import font

# creation of the main window
master = Tk()

# creation of a text widget
tw = Text( master )
tw.config( wrap = NONE )
tw.pack( fill = BOTH, expand = 1 )

tw.insert( END, "Display of available fonts:\n\n" )

count = 0           # cardinal of the element
tabwidth = 0        # tabulator's position (in pixel)

# identification of the font in use (default)
f1 = tw.cget( 'font' )

# a measurement function to be applied later
# is a method of class *tkinter.font.Font*, so that
# it is good to get now the required instance of it
fo = font.Font( font = ( f1, 10 ) )

# let us get the alphabetically ordered list
# of all the font families available in this machine
sampler = sorted( list( font.families() ) )

# handling and display of its elements
for f in sampler :
    # the counter is updated
    count += 1
    # the provided font name is displayed
    # plus a separator and a tabulator
    tw.insert( END, f + ":\t" )
    # creation of an individual name for the tag
    # to be applied to this item's sample
    ftag = 'f' + str( count )
    # creation and typographical configuration of *ftag*
    tw.tag_config( ftag, font = ( f, 10 ) )
    # the sample text is finally tagged and displayed
    tw.insert( END, "This is a simple sampler\n", ftag )
   
    # nice columnar disposition of the output by
    # a clean and clever (re)configuration of the tabulator
   
    f = f + ':'
    if ' ' in f :       # the name has several words
        # (these strings of several words
        # are not well handled here by the complex *Tkinter/Tcl/Tk*;
        # fortunately it seems that the problem can be solved
        # by mimicking *Tcl*'s syntax for the occasion,
        # i.e. by flanking them with
        # the *magic* prefix:     '"[list '
        # and the *magic* suffix: ']"'      )
        f = '"[list ' + f + ']"'       

    w = fo.measure( f )         # in pixel as unit
    if ( w + 5 ) > tabwidth :
        tabwidth = w + 5
        # this aligns all the lines as required
        tw.config( tabs = tabwidth )

if __name__ == '__main__' :
    master.mainloop()




_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss