Ask, and it shall be given # 7

How to post on Ask-pages

This page is not intended for new questions. Please post your question on the latest version of Ask, and it shall be given.


In order to leave room for unanswered questions, please move your question to the appropriate page on Wikit once it has been answered. If you cannot find a page, please create a new one.




Questions


Easy question

Phil Here is the name of the procedure. I try to put in on the menu. The program does not recongnize it.

proc MultipleReplace {filename} {

What is wrong?

Tx!

Optimizing some code

JSB 2009-04-29: I have a selection of code I use a good bit in some data convert utilities I have written in the past month. What I need to do is simply insert a decimal point 2 places from the end. To do this I have used the following two methods:

  1. append rec_batch [string replace $TOT_BAL end-1 end-1 ".[string index $TOT_BAL end-1]"]
  2. append rec_batch "[string range $ TOT_BAL 0 end-2].[string range $ TOT_BAL end-1 end]"

TOT_BAL would look something like: set TOT_BAL {000034567}

Method 1 is the fastest way of doing it, but a little. What really would be nice is if you could do:

append rec_batch  [string insert $ TOT_BAL  {.} end-2]

This method would use a native string subcommand to do it, but there is not one so that’s that.

Does anyone have a faster way to do an string or character insert? I know the time to do this is not that much but I have 500 plus scripts that do this anywhere from 12million to 658million times a day and any boost helps in the long run.

MG: Is keeping the leading 0's important? If not, using expr and dividing by 100 seems to be about twice as fast as the string replace

append rec_batch [expr {"$TOT_BAL.0" / 100}]

JSB: Unfortunately they are needed as I am converting them from a bcd fomat to a fixed format nummeric. I may try a expr and format combo and see what the times like there. Thanks.


ttk::treeview selection

MG 2009-04-25: I'm having some problems with the visual selection in a ttk::treeview widget. When you select an item in the tree, the background turns dark blue and the foreground white, which is fine. But some of my items have a tag which configures the -bg; when those lines are selected, the background colour no longer changes (but the fg colour still does), and because some of them are configured with white backgrounds, the text disappears completely on selection. Is there any simple way to get around this? Ideally, I'd still like the background to become blue on selected items like it does by default. But I can't find anywhere in the item configuration, tags or the ttk::style settings where this is controlled, so can't even write code manually and bind to selection to duplicate the colouring. Does anyone know how I might go about this?


bignum with floating radix point

BMA 2009-04-04: Nice as math::bignum and math::bigfloat are, the middle ground between the two needs to be addressed. Namely, bignums which are in different radices and have a radix point . At present math::bignum only handles integers (afaict) and math::bigfloat won't let you specify different radices to math::bigfloat::fromstr (ditto).

Can anyone offer a way out?


text widget wrapping/geometry issue

MG 2009-04-03: I have a text widget which can be configured (by the app user) to either wrap at a specific number of characters, or to not wrap at all. I've basically been doing:

text .t
if { $wrap } {
    pack .t -fill y
        .t configure -width 78 -wrap word
    } else {
        pack .t -expand 1 -fill both
        .t configure -wrap none
    }

But I'm having a couple of issues. If the toplevel containing the text widget is resized so that it's too narrow to hold a 78-char wide text widget, the text wraps at the edge of the window, instead of continuing to wrap at 78 chars and needing to be scrolled horizontally.

After some fiddling with various methods, the simplest solution I've found to avoid that is to do the "scrolled frame" effect of placing the widget onto a cavas, with $canvas create window -window .t, and then scrolling the canvas. But then the text widget is only as high as its -height argument, and I need it to fill the screen vertically. (Even with the canvas packed to expand, the text widget stays the same height; setting a very large -height just causes the bottom of the text widget to disappear off the bottom of the canvas, meaning the vertical scrollbar attached to the text widget says the entire widget is visible even when it's not.)

Can anyone offer a better solution? I'm using Tcl 8.5, if it makes any difference. Any help would be greatly appreciated, as I've been mulling this over for quite a while and have yet to come up with an adequate solution. Thanks.


Package version numbering scheme supported by Tclkit

XO 2009-03-31: While I was trying the latest unstabled release of TWAPI, i.e. twapi-2.1a1.kit, I couldn't get this starkit working under Tclkit, and got the error complaining ...

C:\tmp>tclkitsh
% set tcl_patchLevel
8.4.17
% source twapi-2.1a1.kit
% package require twapi
error reading package index file C:/tmp/twapi-2.1a1.kit/lib/twapi/pkgIndex.tcl:
expected version number but got "2.1a1"
can't find package twapi
%
% package provide xxx 2.1a1
expected version number but got "2.1a1"
%

Later I came to realize it's resulted from Tclkit's limitation on the version numbering scheme supported, Tclkit won't recognize version number like 2.1a1. This starkit works just fine under ActiveTcl though. Why Tclkit imposes such a limitation? Or is it a bug?

MG: I just tried this, and for me it worked in TclKit but not in my ActiveTcl install. My ActiveTcl install is Tcl 8.4.9, though, and my TclKit is 8.5.1, so possibly this is actually an 8.4/8.5 issue, not a Tclkit/ActiveTcl one?

[APN] Tcl releases prior to 8.4 do not understand this versioning scheme, something I was not aware of. I have switched back to only using . as a separator so 2.1.3 should work for you.


Tcl indentation script

Hello, I happened to use this: https://wiki.tcl-lang.org/15731 But this doesn't work for me. Errors out saying syntax errors, though I don't find any syntax errors. Did anybody else use it ever? Is there a revised version present or something that works..some alternative. Thanks in advance. SR

GWM: see the page again and test the modified script. Error in lines with "} else {" or similar constructs (the continuation beiong on the same line as the close bracket caused a miscount in number of braces).

Martyn Smith - My TCL Editor on Martyn Smith can reindent the current selection (ctrl-w) using the spacing of the first line as the initial spacing (to see the code type 'pedit IndentRegion' in the console (F12)) I need to update it to handle continuation lines properly.


format question

pcam 2009-03-24:

Can someone tell me why the format command is not executed (when the event is fired) in this simple example ? To try, just hover above the newly created red canvas.

canvas .c -bg red
pack .c -fill both
bind .c <Motion> {
    set myScale 1.33
    set xpos [expr %x / $myScale]
    set ypos [expr %y / $myScale]
    set formatedX [format "%0.3f" $xpos]
    set formatedY [format "%0.3f" $ypos]
    puts " Scaled pos ($xpos,$ypos):  $formatedX , $formatedY "
} 

I guess the argument form the event is the culprit, but I cannot figure out how to get around it.

pcam: No longer than 2 minutes later I solved this issue myself. I leave the Q/A anyway, can be useful I guess. Simply had to double up the % sign in my format string, as it gets munched by the event "pre-processor", before the command gets evaluated.

Here it is:

canvas .c -bg red
pack .c -fill both
bind .c <Motion> {
    set myScale 1.33
    set xpos [expr %x / $myScale]
    set ypos [expr %y / $myScale]
    set formatedX [format "%%0.3f" $xpos]
    set formatedY [format "%%0.3f" $ypos]
    puts " Scaled pos ($xpos,$ypos):  $formatedX , $formatedY "
} 

global versus fully qualified variables names

In the global wiki page it is stated that: : Globals are expensive if you call them only a few times in the proc - the cost of the initial linking to a local variable weighs heavily; they are quite fast if you use them a lot [the breakeven seems to be around 15 reads ...]. For fewer calls, use fully qualified variable names instead. I am wondering if this statement is still true ?

With Tcl/Tk 8.6b1 :

set a 12
set b 31.

proc toto {n} {
    global a b
    while {$n} {
        set c [expr {$a*$b}]
        incr n -1
    }
}

proc titi {n} {
    while {$n} {
        set c [expr {$::a*$::b}]
        incr n -1
    }
}

% time {toto 1000000} 10
212703.1 microseconds per iteration
% time {titi 1000000} 10
813360.2 microseconds per iteration

Everything seems ok, global is better when calling many times a global variable. But :

% time {toto 2} 10
3.2 microseconds per iteration
% time {titi 2} 10
4.1 microseconds per iteration

Is there any advantage to use fully qualified nvariable names ? Could someone explain me what is happening when the interpreter sees "global" versus "::" ?

MS: When it sees [global foo] within a proc body, the compiler will create a local var foo and link it to the global variable when global is invoked at runtime. That is one lookup by name, every later reference to that variable in the body is a reference to an indexed local variable, which is very fast. The first lookup is relatively slow: non-:: references are not cached.

When ::foo is seen a literal will be compiled in; the reference to the global variable will be cached in the corresponding Tcl_Obj on first use. This means that the lookup by name happens just once too. But later references in the body still go through the slower non-local mechanism. OTOH, on later reentry to the same body even the first lookup profits from the cached reference (assuming it did not shimmer away in the meantime), so that it is faster than the lookup done by [global foo]


QuicktimeTcl Problem

I'm trying to put a .mov file into a tcl/tk application and I'm getting this error from the wish console when I try to source the file:

no suitable image found. Did find:

        /Library/Tcl/QuickTimeTcl3.1/QuickTimeTcl3.1.dylib: mach-o, but wrong architecture
NSCreateObjectFileImageFromFile() error: not a Mach-O MH_BUNDLE file

Not sure what this means....

This is the code I was trying to source, and I'm on a Mac using OSX 10.5.6 (fairly short and straightforward, an example from the QuicktimeTcl site)

package require QuickTimeTcl

movie .m -file ./SF_Experiments/Curve1FULL.mov
pack .m

My version of Quicktime is 7.6, and it says on the website QuicktimeTcl was only tested wit 5 and 6.4...could this be the problem? It seems to me if it worked with 6.4 I would hope it works with 7.6 but you never know...

Any ideas? Apologies if this is an amateur question...but I'm afraid I'm a bit of a Tcl/Tk newbie, only really started in about two weeks ago...Any help is much appreciated!

thanks,

-C

MSH 2009-03-12: The message looks like it is saying that the dylib is not for the correct processor, remember that Macs have two different processor architectures Intel and PowerPC, check that Quicktime TCL is compatible with your architecture it is probably not a FAT binary. (I think you can find the info on the Apple menu -> about this Mac), a quick look at the compatible versions on the Quicktimetcl suggests it may only be for PowerPC so a recompile may be needed.


tcom Variant problem

I am trying to replicate some VBA code to communicate with a COM interface but am having problems with tcom providing the correct VARIANT.

VBA code:

Dim PayLoadWr(1) As Long
Dim RetVal

m_sNodeAddress.byLocalPort = 0
m_sNodeAddress.nDestID = -1
m_sNodeAddress.nHopCount = 0
m_sInput.lOffset = 0
WordCount = 1
Stride = 4

RetVal = m_objRapidFet.MaintRead(m_sNodeAddress.byLocalPort, m_sNodeAddress.nDestID,  
                       m_sNodeAddress.nHopCount, m_sInput.lOffset, WordCount, Stride)

PayLoadWr(1) = 10
m_sOutput.bResult = m_objRapidFet.MaintWrite(m_sNodeAddress.byLocalPort, m_sNodeAddress.nDestID,
    m_sNodeAddress.nHopCount, m_sInput.lOffset, WordCount, PayloadWr, Stride)

I am able to perform the read in TCL but the write reports invalid VARIANT type, expected VT_BYREF | VT_ARRAY | VT_I4. As the read works I believe the problem is with the WordCount variable which I have tried setting in many ways. How do I force TCL to use one of the expected types ?

Thanks, MarkE.


plotting demo

2009-02-17: i modified the tcl8.5 plotting demo to label the points and have trouble dropping the pick routine for another point. After i pick a few points, the previous point will hop to the cursor and grab the control. I started to write this up as a mod to the random que demo, but not much to offer so far. thanks, gold.

proc pickpoint { w x y } {
    #set lcoords [.c coords  [.c find withtag current]  ]
    # set xx [lindex $lcoords 0];
    # set yy [lindex $lcoords 1];
    # set xxxx [expr {[lindex $lcoords 0] + 10} ] ;
    # set yyyy [expr {[lindex $lcoords 1] + 10} ] ;
    set victims [.c find overlapping  $x $y  [expr {$x+4 }] [expr {$y+4}] ];  
    set previousselect 1 
    foreach element $victims { 
        .c itemconfigure $element  -tag selected; 
        #.c itemconfigure [.c find withtag current] -fill blue; 
        #.c itemconfigure [.c find withtag previous] -tag previous2
    }          
}    

proc xplot { args } {
    set sum 0
    set c ".c"
    set font {Helvetica 8}
    pack [canvas $c -relief sunken -width 450 -height 300 -cursor top_left_arrow]
    $c create text 100 20 -text "A Simple Plot" -font $font -fill brown
        for {set i 0} {$i <= 10} {incr i} {
        set x [expr {100 + ($i*30)}]
        $c create line $x 250 $x 245 -width 2
        $c create text $x 254 -text [expr {10*$i}] -anchor n -font $font
    }
    for {set i 0} {$i <= 5} {incr i} {
        set y [expr {250 - ($i*40)}]
        $c create line 100 $y 105 $y -width 2
        $c create text 96 $y -text [expr {$i*50}].0 -anchor e -font $font
    }

    # 12 56 20 94 33 98 32 120 61 180 75 160 98 223

    foreach {item item2}  $args  {
        $c create line 100 250 400 250 -width 2
        $c create line 100 250 100 50 -width 2

        #set x [ expr {100+$item * 1} ]
        #set y  [ expr {100-$item2*.2 } ]
 
        #set x [expr {100 + (3*[lindex $point 0])}]
        #set y [expr {250 - (4*[lindex $point 1])/5}]

        set x [expr {100 + (3*$item)}]
        set y [expr {250 - (4*$item2)/5}]
        set point {$item $item2} 


        $c create text [ expr {$x + 1} ] [ expr {$y+1 } ] -text "* [
            expr {$item * 1} ],$item2" -font $font -fill brown -tag point
        
        set item [$c create oval [expr {$x-6}] [expr {$y-6}] \
            [expr {$x+6}] [expr {$y+6}] -width 1 -outline black \
            -fill SkyBlue2]
        
    
        $c addtag point withtag $item
    }
    $c bind point <Any-Enter> "$c itemconfig current -fill red"
    $c bind point <Any-Leave> "$c itemconfig current -fill SkyBlue2
    $c itemconfig selected -fill SkyBlue2;$c itemconfig selected \
        -tag unselected;$c itemconfig current -tag uncurrent;"
    $c bind point <1> "$c itemconfig current -tag uncurrentembPlotDown $c %x %y"
    $c bind point <ButtonRelease-1> "$c dtag selected"
    bind $c <B1-Motion> "embPlotMove $c %x %y"
    return [ expr { 1+1 }   ]
}

set embPlot(lastX) 0
set embPlot(lastY) 0
console hide
proc embPlotDown {w x y} {
    global embPlot
    $w dtag selected
    
    $w addtag selected withtag current
   

     pickpoint $w  $x  $y

    $w raise current
    set embPlot(lastX) $x
    set embPlot(lastY) $y
}

proc embPlotMove {w x y} {
    global embPlot
    $w move selected [expr {$x-$embPlot(lastX)}] [expr {$y-$embPlot(lastY)}]
    set embPlot(lastX) $x
    set embPlot(lastY) $y
    

}

xplot 12 56  20 94  33 98  32 120  61 180  75 160  98 223
#end of deck 

Ttk Megawidget

MG: I'm trying to create a very basic megawidget using Ttk on Tk 8.5. Under one theme, it's just a styled ttk::entry widget (I have this working fine). On other themes, though, it should be a normal-looking ttk::entry with a ttk::button displayed next to it. All my attempts to set this up some how using a single ttk widget with -style have failed, though. (Admittedly, I don't really know what I'm doing, and have largely been guessing based on snippets of mostly-unrelated code on the wiki or in the *Theme.tcl files shipped with Ttk.) I would've thought this would be possible (a combination of widget-types is how scrollbars work, I think?), but I'm completely at a loss. Currently I'm just checking the loaded theme, and using separate entry and button widgets if the button's needed. But I'd like to be able to let users change the Ttk theme being used, which means the button should appear/disappear on its own when the theme is changed. Can anyone offer any suggestions? (The button doesn't need to be configurable; when it's visible it will always display the same -image and and run the same -command when clicked. Don't know if that makes any difference...)

Thanks for your help.


TCL8.5 plotter demo script

gold 2009-02-03:

Can someone show me how to put the x,y points as arguments to the plotter routine? This plotter routine is from the embedded text widget demo of TCL8.5. When i try to pass the data as a list to the plotter subroutine, i get a non numeric char warning at the line:

set x [expr {100 + (3*[lindex $point 0])}]

Maybe some kind of intermediate subroutine to load the data into a list of pairs? Prefer to keep the calling line (plotter 12 56 20 94 33 98 etc) without a lot of typing brackets. i used the plotter for a mockup chart in https://wiki.tcl-lang.org/19640 . Thanks, gold

proc plotter { args} {
    set c .c
    pack [canvas $c -relief sunken -width 450 -height 300 -cursor top_left_arrow]

    set font {Helvetica 18}

    $c create line 100 250 400 250 -width 2
    $c create line 100 250 100 50 -width 2
    $c create text 225 20 -text "A Simple Plot" -font $font -fill brown
    
    for {set i 0} {$i <= 10} {incr i} {
        set x [expr {100 + ($i*30)}]
        $c create line $x 250 $x 245 -width 2
        $c create text $x 254 -text [expr {10*$i}] -anchor n -font $font
    }
    for {set i 0} {$i <= 5} {incr i} {
        set y [expr {250 - ($i*40)}]
        $c create line 100 $y 105 $y -width 2
        $c create text 96 $y -text [expr {$i*50}].0 -anchor e -font $font
    }
    
    foreach point {
        {12 56} {20 94} {33 98} {32 120} {61 180} {75 160} {98 223}
    } {
        set x [expr {100 + (3*[lindex $point 0])}]
        set y [expr {250 - (4*[lindex $point 1])/5}]

        set item [$c create oval [expr {$x-6}] [expr {$y-6}] \
                [expr {$x+6}] [expr {$y+6}] -width 1 -outline black \
                -fill SkyBlue2]
        $c addtag point withtag $item
    }

    $c bind point <Any-Enter> "$c itemconfig current -fill red"
    $c bind point <Any-Leave> "$c itemconfig current -fill SkyBlue2"
    $c bind point <1> "embPlotDown $c %x %y"
    $c bind point <ButtonRelease-1> "$c dtag selected"
    bind $c <B1-Motion> "embPlotMove $c %x %y"
}
  
set embPlot(lastX) 0
set embPlot(lastY) 0
console hide
proc embPlotDown {w x y} {
    global embPlot
    $w dtag selected
    $w addtag selected withtag current
    $w raise current
    set embPlot(lastX) $x
    set embPlot(lastY) $y
}

proc embPlotMove {w x y} {
    global embPlot
    $w move selected [expr {$x-$embPlot(lastX)}] [expr {$y-$embPlot(lastY)}]
    set embPlot(lastX) $x
    set embPlot(lastY) $y
}
    #original data hard loaded in plotter subroutine
    # {12 56} {20 94} {33 98} {32 120} {61 180} {75 160} {98 223}

     
plotter   12 56    20 94   33 98   32 120   61 180   75 160   98 223 

Lars H: You can start from the following main loop instead:

foreach {px py} {
    12 56  20 94  33 98  32 120  61 180  75 160  98 223
} {
    set x [expr {100 + 3*$px}]
    set y [expr {250 - 4*$py/5}]

    set item [$c create oval [expr {$x-6}] [expr {$y-6}] \
            [expr {$x+6}] [expr {$y+6}] -width 1 -outline black \
            -fill SkyBlue2]
    $c addtag point withtag $item
}

Alternatively, combine what you have with what's on Striding a list.


ttk/Tile listbox

MG: Is there any way to simulate the classic Tk listbox's -listvar with a Ttk widget? At the moment all I can see to do is use a ttk::treeview and put a trace on my variable which updates the treeview's contents, but I wanted to check if there was a better way first. Thanks.

Martyn Smith: I think that the Canvas, Text and Listbox widgets are not added to tile because their graphical display is always the same so you should just use the good old listbox command !

MG: Thanks for your reply. I wanted to avoid that because there are a few differences, and I've been trying really hard to only use Ttk widgets for consistency since I started rewriting my app (the text widget being about the only place I'm still using classic Tk widgets). The differences aren't major for me on Win XP with Tile's winnative theme, but if I change to the clam theme, for instance, the classic listbox is totally out of place compared to all my other widgets.

Something like

ttk::treeview .widget -show {} -columns one
.widget insert {} end -values Foo
.widget insert {} end -values Bar
.widget insert {} end -values Baz

to simulate a simple listbox works OK, so it's not a big deal. This is just one of the few occasions where I've wanted a listbox and actually already had all the values stored in a list, instead of as array elements or something like that, and I missed the simplicity of -listvar for updating the display when the values changed.


mahjong style deletion in tcl

2009-01-20:

This question has been pretty well answered and closed out. I have posted the answer etc in a new wiki page. Thanks,gold

aricb 2009-1-23: Does the following code do what you have in mind? aricb: https://wiki.tcl-lang.org/22318


replacing error messages in Itcl

If I create an object in Itcl, such as the simplified toaster example, and call an unknown method:

package require Itcl
itcl::class Toaster {
    variable crumbs 0
    method toast {nslices} {
        set crumbs [expr $crumbs+4*$nslices]
    }
    method clean {} {
        set crumbs 0
    }
}
Toaster tt
tt toad
bad option "toad": should be one of...
tt cget -option
tt clean
tt configure ?-option? ?value -option value...?
tt isa className
tt toast nslices tt toast 5

How do I intercept the 'bad option' message to improve assistance?


segmentation fault on running wish

compiling tk8.5.6 on fedora 7, compilation completed without error, 'wish' generated and when execute,fail with a message 'segmentation fault', can anyone help? Thanks

MJ: This would probably be better answered after a query on comp.lang.tcl. Also when asking there add all the information you have, for instance any errors other than the segmentation error and a backtrace in a debugger if possible. Also provide info on which version of Tcl you compiled, where you got that version and how you downloaded it.


Double Factorial and bignums?

Has anyone coded up a Tcl version of Double Factorial[L1 ] that uses bignums that they're prepared to share so that I don't have to write it myself?

Thanks, BMA

Lars H: Yes, I have in infix done a semifactorial using math::bignum. The key part of the implementation is the following "anyfactorial":

proc xfactorial {k n} {
    if {[::math::bignum::le $n 1]} then {
        return 1
    } elseif {[::math::bignum::le $n $k]} then {
        return $n
    } else {
        set kk [::math::bignum::add $k $k]
        ::math::bignum::mul [
            xfactorial $kk $n
        ] [
            xfactorial $kk [::math::bignum::sub $n $k]
        ]
    }
}

k=1 gives you the ordinary factorial, k=2 the semifactorial. The idea in the recursion is to try and keep the two factors being multiplied of roughly equal size.


Problem with referencing a variable within a namespace

Dear Tcl/Tk programmers,

I'm building a GUI to incorporate it into a software package as a plugin. I have a problem related to Object Oriented Tcl and particularly referencing variable $w which points to the top level widget. The problem occurs when I try to open a .psf file (see 2 last lines of code):

package provide tt_GUI 1.0

namespace eval ::tt_GUI:: {
    namespace export startGUI
    variable w
}

proc ::tt_GUI::startGUI {} {
    variable w
    
    # make the initial window
    set w [toplevel ".tt_GUI"]
    wm title $w "Truncate Trajcetory"
    wm resizable $w 0 1 
    
    label $w.psfLab -text {  Select trajcetory .psf file :  }
    label $w.psfPathLab -text {No file selected}
    
    button $w.psfBut -command {set types {
            {".psf Files"     {.psf}    }
            }
            set file [tk_getOpenFile -filetypes $types -parent .]
            $w.psfPathLab configure -text $file} \
            -text Open 
   
    ....(irrelevant code)....
   
}

The error message I get is:

can't read "w": no such variable
can't read "w": no such variable
    while executing
"$w.psfPathLab configure -text $file"
    invoked from within
".tt_GUI.psfBut invoke"
    ("uplevel" body line 1)
    invoked from within
"uplevel #0 [list $w invoke]"
    (procedure "tk::ButtonUp" line 22)
    invoked from within
"tk::ButtonUp .tt_GUI.psfBut
"
    (command bound to event)

That should be a piece of cake for a Tcl programmer but unfortunately I'm not that familiar with OO Tcl. I would deeply appreciate any help.

Tom

MG 2008-12-22: The problem is that your -command is enclosed in curly braces, which prevents the $w from being evaluated when the button command is run. Instead, it's only evaluated (in the global scope) when the button is clicked and the -command string is run, and at that time $w doesn't exist. There are two ways around it. One is to force the $w to be evaluated/expanded during the button command, using something like:

button $w.psfBut -command [format {set types {
    {".psf Files"     {.psf}    }
    }
    set file [tk_getOpenFile -filetypes $types -parent .]
    %s.psfPathLab configure -text $file} $w] \
    -text Open

The other is to use a proc for the button command:

proc ::tt_GUI::btnPress {w} {
  global file;

  set types {
          {".psf Files"     {.psf}    }
          }
  set file [tk_getOpenFile -filetypes $types -parent .]
  $w.psfPathLab configure -text $file
}

proc ::tt_GUI::startGUI {} {
    # code....
    button $w.psfBut -command [list ::tt_GUI::btnPress $w] -text Open 
    # more code...
}

How can I execute a tcl file, and keep the parent file active IN WINDOWS

Shelly 2008-12-11: Hello, I am using Windows (XP), and need my main tcl script to call other tcl files, which I would like running in the backgroud, while the parent file is still active. In UNIX, it is possible to use the '&' after exec, but exec doesn't run on Windows. I use 'source' to run the called files, but 'source' doesn't take '&' as an argument, and I have not been able to find a Windows equivalent to 'exec filename &'. Right now, when my script sources another file, it immediately terminates. Any Ideas? Thanks.

Shelly 2008-12-11: Update: I found the answer: exec can run on Windows, it just needs to be passed the application name. e.g.:

exec notepad myfile.txt &

or

exec wish85 myfile.tcl &

Tcl/Tk 8.5 doesn't colorize scrollbars and buttons after tk_bisque

tb: Hi, after reading about tk_bisque, I gave it a try on version 8.5. Everything fine so far, except scrollbars and buttons stay gray. Any suggestions?

Duoas 2008-11-18:

The tk_bisque command is designed to work with the old motif-style UI. It has been extended to do its best with modern widgets, but it can't do all things. The reason is that there is a fundamental difference in the way things work underneath.

When X was designed, an explicit decision was made to not impose any sort of style on the applications. An "example" of a basic widget toolkit was created, which became "Xaw" or the "Athena" toolkit. Out of this grew the Motif toolkit that people typically associate with X (and Tk) and its modern, [L]GPL-ed sister: LessTif. X was stunted by it for years. (It is only relatively recently that WM's like Gnome and KDE and Sawfish, etc. have begun to bring *nix GUIs into the modern age. CDE is an abomination [as a GUI].)

The simplicity of this toolkit design made it very easy to modify however you like. Need a red button? No problem. Need a scrollbar with funny behaviors? No problem. Modern systems are much less flexible: they exert some control on how standard widgets appear and how they behave (the so-called "look-and-feel"). The purpose is to make it easier for 'normal' people to use the computer --because they know how things work just by looking at them.

It is no small coincidence that Apple and Microsoft systems are ubiquitous: the masses understand them. Knowing how one program works --> knowing how all programs work. (Remember, what a program does is different than how the program "look-and-feel"s to the end-user. To Jane Doe, solitaire player, the way a program "works" is how it interacts with her --not how fancy the card-shuffling algorithm is.)

Tk has used native widgets for a while now. Hence, they are not so simple to modify --since that is not how they are designed to be used.

(You can make your own widgets --including modifications to existing widgets, but that is a separate widget --not just a simple color/behavior change applied to one instance of some widget.)

Hope this helps.

tb: No, not really :) I understand that this decision had to be made on one hand, on the other I think it's a pity. For myself I got pretty used to having several GUI's on my desk. I run Linux only for nearly 16 years now and never had a desktop showing only one design. Let it be KDE, Gnome, XFCE et al, none of them integrates Blender :) - Java apps always burn a design hole into the desk and KDE and Gnome always get mixed up, as they offer different programs. But who is me? :)

Duoas: Yoinks! It seems I forgot to actually answer the question...

Take a look at "styles" in ttk. While a pain, yes, it really is the right decision.

I find that KDE is pretty good at normalizing application interfaces... but again, part of the design philosophy behind X is that each application can control its own style, so a mixture can be well expected. Blender cannot be "styled" by any WM --its entire interface is OpenGL. But if Blender were ever to loose its innovative (and superior) UI, I'd personally create a fork on sourceforge and put it back in (as would many others at BA). [BTW. You can modify Blender's theme. Check out the old Blender Theme Repository . Or just grab the bottom edge of the main menu bar and drag it down to get at the preferences and mess with it yourself...


Tcl/Tk Applications page, Whatever happened to

Lars H 2008-11-10: Whatever happened to the big page that listed all those Tcl(/Tk) applications? Searching for "applications" right now doesn't turn it up (although it does find the Applications page, which certainly could do with some content), just a few leftovers from unperson's push on trying to break it apart. Was the original page lost in the process, or does it just have a different name? (I've noticed the wiki title search is sometimes more restrictive than one would expect as to what constitutes a match.)

MG: The page you're looking for is Applications in Tcl and Tcl/Tk, I believe. Not to much to see now, but look back in the revision history for the page, the long list is still in there somewhere.

Lars H: Aha! It looks like revision 313 [L2 ] is the last one before the big content loss. Clearly not a page without problems (far too many big and slowly loading images), but a kind of collection that should be available (especially for those new to Tcl).


Break apart the Tcl Tk event loop

Xyem 2008-11-04 14:47 UTC: I'm currently programming something in OpenGL for research purposes and would like to use Tcl/Tk for the controls. However, both OpenGL ( rather, GLUT ) and Tcl/Tk have "closed" event loops.

Tcl will allow me to update the GUI from within OpenGL/GLUT ( by calling 'update' in the GLUT 'idle' callback ). Would this be okay? I can't think of any way it will recurse..

Duoas: Have you seen GLUT/Tk ?

Xyem 2008-11-04 18:02 UTC: I had not but that might be quite useful.. Thanks!

ferrieux: What about Paul Obermeier's Tcl3D ? Aren't you recreating the same thing basically ?

Xyem 2008-11-10 21:45 UTC: I'm using the OpenGL and Tcl::Tk modules for Perl so I don't think so!


How to write a download procedure for big (2-3GB) files on server side?

Ross: On a http server I wrote the cgi:

set f [open $tar_file r]
set siz [file size $tar_file]
fconfigure $f -translation binary
set dd [read $f $siz]
close $f

puts -nonewline "Content-type:application/x-download\n"
puts "Content-Disposition:attachment;filename=$ris"
puts "Content-Transfer-Encoding: binary"
puts "Content-Length: $siz\n"
puts -nonewline "$dd"

But for file size > 1020 MB this doesn't work (I get a segmentation fault during the read command). How move around this buffer limit?

Lars H: The obvious solution would be to copy the file in smaller chunks, e.g. using fcopy. Attempting to keep an entire 2–3 GB file in RAM is frankly to beg for trouble…

NEM: Concretely, something like the following:

set f [open $tar_file r]
set siz [file size $tar_file]
fconfigure $f -translation binary

puts "Content-Type: application/x-download"
puts "Content-Disposition: attachment;filename=$ris"
puts "Content-Transfer-Encoding: binary"
puts "Content-Length: $siz"
puts "" ;# end of headers
fconfigure stdout -translation binary
fcopy $f stdout
flush stdout
close $f

You may also want to play with the -buffering/-buffersize on stdout.

Ross: thanks! Now it works (I used chunks of 1024).


Binding problem

MG: I remember seeing a code snippet several years ago (by JH, I think) that showed how to tell which modifiers (Control/Alt/etc) were held down during a KeyPress event, but I can't find it now. From some playing with bind and the manpages, the only thing I've found that might've been it is using the %s substitution - as far as I can see from my testing,

bind . <KeyPress> {puts %s}

always prints 8 for an unmodified keypress, 9 for Shift+Key, 12 for Ctrl+Key, 13 for Ctrl+Shift+Key, 131080 for Alt+Key, 131084 for AltGr+Key. Anyone know if this is actually correct (ie, always gives those same figures at all times on all platforms), or whether there's another way? My fallback if I can't get this to work or find the original snippet is to use something like

bind . <KeyPress_Shift_L> {set shift 1}
bind . <KeyRelease_Shift_L> {set shift 0}

and just check those vars when a valid keypress (which is a printable char or F1-F12, in this case) fires, to see which modifiers were in use, but that's not really foolproof itself.

Also, on MS Windows, the numbers on the keypad fire on the same keysym as the regular numbers, but I've noticed that the result of '%k' is different (regular 1 key has an %k of 49, KP_1 has 97). Can I depend on that to always be the same? (Will KP_* bindings always work on non-Windows platforms?)

Any help would be very greatly appreciated.

aricb: I can confirm that the %s codes are different in SuSE Linux than the ones you posted above. It would be nice to have a cross-platform solution to this issue, but at the moment I don't know what it would be other than binding on each modifier key.

Duoas: See the Xlib Manual section 10.5.2 for information on where those substitution values come from. The State field is a bit mask indicating which of certain modifier keys and mouse buttons were down or active when the event triggered. Typically, the values are:

  Shift Keys           ShiftMask         1
  Caps Lock            LockMask          2
  Control Key(s)       ControlMask       4
  Alt Keys             Mod1Mask          8

  Left Mouse Button    Button1Mask       0x100
  Middle Mouse Button  Button2Mask       0x200
  Right Mouse Button   Button3Mask       0x400

Those should be the same for all systems, but I can only speak as to Sun OS 9 and 10 and Windows XP, and usually the defaults in your Linux distro.

There are also four other keys (Mod2Mask..Mod5Mask) which are often used for customizations.

The thing about X systems is that these values can be changed via your ~/.xmodmap rc file. And there is no real convention for mapping your "Windows keys" (usually Super_X or Hyper_X), and the Alt-keys are usually called Meta_X, but the meta keys, on some systems, can be oddball stuff --like the Esc key. Here is something I found about using XModMap for you [L3 ].

If you find that the first four values are incorrect, then your system is either mis-configured or it has been abnormally configured by your Distro (barring, of course, explicit user configurations).

Hope this helps.

MG: Heh, OK. Apparantly, if the variable way is imperfect, the others which I thought might work better are downright useless, so I'll still with imperfect ;) Thanks for your help, guys. (I kinda figured I might be out of luck when I got 131080 for Alt on Windows, but thought it was worth trying;)

MG: just found the original snippet he was referring to after someone mentioned it on another page; it's on Portable keystate. Too tired to go over it all atm and try and work it in, but that's what I was referring to.


How to write a C program that uses Tcl?

I know that we typically refer people to the tclsh and wish source code as examples of writing C code that uses tcl as a library.

But are there wiki pages that we could add to compile that discuss the matter? It seems like a tutorial on writing such a critter, best practices, etc. would be useful.

Charlie: Indeed. A tutorial for beginners would be a great plus.


MPEG4 Video/Audio playing in a Tk widget?

So, are any students or hobbyists out there working on writing a Tk widget that plays back audio/video from MPEG4 files?

Lars H: Would QuickTimeTcl fill this request? (Probably not for all platforms, but it's a start.)

LV: Someone mentioned that one to me, but I don't know if that works for most Linux or Solaris, etc. systems.


Tcl-TK + SQL Database

2008-10-19: Hi Community. SQL lite seems to be the answer to various needs. Unfortunately the average users I target are not experts in SQL. Is there anything as user friendly as Access available or in the works written in Tcl-Tk? I am not enclined to make Microsoft even richer by buying a license for Access and I'd rather go with something in the public domain. I've downloaded Outline a few years ago. It is a marvellous software written by a gentleman named Theado from this very community. It is very user friendly and very useful. I'd love something of the sort but in the form of a database manager as user friendly as Access. Thank you Community for enlightening me with your excellent knowledge.

By the same token if I could find a spreadsheet written in Tcl-TK I'd have a Tcl-TK Office suite. That would be great. Thanks again Community.

MG: SQLiteTablelist and SQLiteStudio both may be of some use to you, as might ATKSqlBrowser. (Never used any of them myself, so can't offer any more info, just found them doing a search for 'Sql' in page titles on the wiki.)


Tk8.5.4 make fail on ubuntu 8.041 LTS

mrm0607 2008-10-11: Dear TCL/Tk user community, I am new to Tcl/Tk and new to LINUX as well. I need to install Tcl/Tk for another application (before its install). By mistake I uninstalled Tcl/Tk 8.5.4 from my UBUNTU machine. I installed TCL 8.5.4 from its TAR and it seems to working OK. But when I started installing Tk 8.5.4 from its TAR, make failed. I am listing first error it puts out.

mamta@requiem:~/Desktop/tk8.5.4/unix$ make
gcc -c -O2  -pipe  -Wall -Wno-implicit-int -fPIC -I/home/mamta/Desktop/tk8.5.4/unix/../unix -I/home/mamta/Desktop/tk8.5.4/unix/../generic -I/home/mamta/Desktop/tk8.5.4/unix/../bitmaps -I/home/mamta/Desktop/tcl8.5.4/generic -I/home/mamta/Desktop/tcl8.5.4/unix  -DPACKAGE_NAME=\"tk\" -DPACKAGE_TARNAME=\"tk\" -DPACKAGE_VERSION=\"8.5\" -DPACKAGE_STRING=\"tk\ 8.5\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_LIMITS_H=1 -DMODULE_SCOPE=extern\ __attribute__\(\(__visibility__\(\"hidden\"\)\)\) -DTCL_SHLIB_EXT=\".so\" -DTCL_CFG_OPTIMIZED=1 -DTCL_CFG_DEBUG=1 -D_LARGEFILE64_SOURCE=1 -DTCL_WIDE_INT_TYPE=long\ long -DHAVE_STRUCT_STAT64=1 -DHAVE_OPEN64=1 -DHAVE_LSEEK64=1 -DHAVE_TYPE_OFF64_T=1 -DHAVE_SYS_TIME_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_INTPTR_T=1 -DHAVE_UINTPTR_T=1 -DHAVE_PW_GECOS=1      -DTCL_NO_DEPRECATED  -DUSE_TCL_STUBS  /home/mamta/Desktop/tk8.5.4/unix/../generic/tk3d.c

In file included from /home/mamta/Desktop/tk8.5.4/unix/../generic/tkInt.h:21,
                 from /home/mamta/Desktop/tk8.5.4/unix/../generic/tk3d.c:16:
/home/mamta/Desktop/tk8.5.4/unix/../generic/tk.h:78:23: error: X11/Xlib.h: No such file or directory

after this there is along list of error.

I was wondering if somebody could help me to install Tk.

If this is not the right place to ask this question please let me know where I can post this question.

Thank you. mrm0607

Lars H: I'm no good at this, but since noone else has answered… The problem seems to be that the compiler doesn't find the X11 headers, which seems odd since configure should presumably check that kind of thing. You did run it, I hope? (Also: Read the README, followed the instructions therein, etc.?)

JM: I think you don't have to go through un-TAR, make, etc. ActiveState provides an installer for linux, which is pretty much click and run...

Duoas: For Ubuntu/flavors you can repair it with your package manager.

sudo apt-get update
sudo apt-get install tcl8.5 tk8.5

If you have sufficiently boogered your tk install, you may have to

sudo apt-get remove tk

before update and/or install.

I just installed tcl on my Kubuntu but I used the ActiveTcl tarball. After installing in the suggested /opt/Active*/ directory, make sure to add (hard)links to the files in the ActiveTcl bin directory from your /usr/bin directory:

cd /opt/Active*/bin/
sudo ln -f -t /usr/bin *
cd /usr/bin
sudo ln tclsh5.5 tclsh
sudo ln wish5.5 wish

However, if you really want to compile it yourself... Part of the design of Ubuntu is that most people are just regular "users", so by default it does not include a large number of development packages needed for systems/X11/library/etc programming. At a minimum you will need

sudo apt-get -y install build-essential make g++ x-dev libx11-dev manpages-dev glibc-doc

See here [L4 ] for more.

Whew. Hope this helps.


Data storage preferences

MG 2008-02-10: I'm thinking of writing a new (mostly toy) app, which will need a small database of some sort (and will probably be kept as a starpack when it's written). I know a reasonable amount of SQL, so SQLite is a possibility, as is just throwing the data into a textfile in a fairly basic format (possibly just a file of [array set] commands, or something a little neater that'd have to be parsed in). I've also been considering Metakit, though - I heard some good things said about it quite a while back, but have never really looked at it in much detail. My main reason for considering it now is that it's already available in a Tclkit, tbh. So, my question (after all that rambling) is: is it worth using? I don't need to do any particularly complex queries here (nothing that can't be done quite simply in pure Tcl with data stored in an array), and the data is only likely to get up to about 500 rows/10-15 fields. Are there any particular advantages to Metakit that'd make it worth learning (for this and future/more complex projects), over one of the alternatives I'm more familiar with already? Any input from someone who's used Metakit would be greatly appreciated :)

RS 2008-10-06: For the size you mention (and some orders of magnitude more), a plain text file seems most suitable for me, as it doesn't need sqlite or tclkit infrastructure for being inspected or edited with any plain editor, grepped, gawked etc.

Larry 2008-10-06: Somewhere down the line you'll be happy you have learned SQL. This project you're working on gives you a chance to explore and learn SQL Lite so go for it. You won't regret it. Anything you learn can be useful down the line.

MG: already knows SQL :) Though I've never really used SQLite before, the syntax differences between that and MySQL (which is what I'm most familiar with) are negligable. Metakit was the one I wasn't familiar with. Thanks for your replies, though - I've decided to skip Metakit, at least for the time being. I'm not too bothered about external dependencies (I'm writing the app mostly for myself, and then mostly for the fun of writing it, not to really use much), so will possibly go with SQLite just to save having to spend time on code for saving/loading the data.

Larry 2008-08-11: If you could provide us with a step by step tutorial on how to use a SQL Lite database, we'd be forever indebted to you. If you go to http://www.sqlite.org/ you'll be convinced that SQL Lite and Tcl-Tk go hand in hand for unless I'm mistaken it seems to me this is the only programming language they ever mention so this is really good publicity for us.


tcom and SAPI 5.1 error 0x80020011

I am attempting to change the default output sample rate / format at which the SAPI engine gives the soundcard I have a way to change the format now but have a problem when making a call to set a boolen value in the SpVoice object see code snippet:

package require tcom

set FALSE false
if {$FALSE} {} 

set out [::tcom::ref createobject Sapi.SpMMAudioOut]
set testform [$out Format]
$testform Type 30

set voice [::tcom::ref createobject Sapi.SpVoice]
tk_messageBox -message [$voice AllowAudioOutputFormatChangesOnNextSet]
$voice "AllowAudioOutputFormatChangesOnNextSet" $FALSE
$voice AudioOutputStream $out
$voice Speak "An application creates the SpVoice " 0

This line is the offending code:

$voice "AllowAudioOutputFormatChangesOnNextSet" $FALSE

Gives error 0x80020011 from tcom

It throws back a lovely error which upon goggling does not really mean anything to me. I have attempted to make sure as the documentation specifies that the value is a valid boolean false value but still the error. When reading the value i get 1 back.

TL

CJL: It won't be much consolation, but that works fine for me as is (XP sp3, ActiveState Tcl 8.5.1, tcom 3.9)

As an aside, the whole assigning of 'false' to FALSE, and testing $FALSE seems a little redundant. Why not just use 'true' and 'false, or 1 and 0?

Lars H: Probably an idiom to ensure $FALSE has a boolean Tcl_ObjType. tcom is infamous for violating EIAS by translating a value differently depending on the type of its internal representation.


Can starkits be digitally signed?

Java provides a tool called webstart that allows Swing applications to be deployed to a web server with a reference to a JNLP (Java Network Launch Protocol) file, which when accessed by a client browser will bring up the webstart environment, download identified jar files and launch the application. There is even provided a Java servlet that will allow the webstart environment to determine if a component of the application changed since the last time it was run and only download changed jars.

One of the features provided is the ability to digitally sign the jar files then place in the .jnlp file a request for extended permissions. If the signature is accepted, the webstart environment will open the sandbox the code is running in to allow for more access. For example, a Swing app that wanted to connect to a server other than the one it was loaded from needs to be digitally signed then ask for permission to do so.

Is there a way to also sign a .kit file and if that's possible, then what would be needed to modify the tclkit system to be able to verify a signature? If this works, then a .kit that was signed could have a permissions script that the tclkit would use to open up additional permissions in the interpreter that it creates.

Then, if the tclkit was deployed to a client and the .kit extension were registered such that the tclkit is the executable that opens the .kit, then you could deploy starkit's as direct links on a website and execute them directly, while providing solid sandbox security.

Lars H: I don't think there is anything like that in tclkits, i.e., they currently always operate with full permissions, and there's no mechanism for signing them. A sandbox environment for untrusted starkits is an interesting idea; a good start is probably a sandbox that asks the user for permission whenever the starkit wants to access anything outside it. There is probably no great technical obstacle to a digital signature system either, but that will probably come when someone feels the need for it (starts delivering a frequently updated starkit en masse over the web, or something like that).

NEM: A sandbox environment for starkits can be created easily enough:

set i [interp create -safe]
$i eval [list source [lindex $argv 0]]

Adding permissions (capabilities) to the safe interpreter can then be done using interp alias. Sockets are not covered by the safe base, so you'd have to come up with a permissions scheme here yourself (e.g. limiting based on IP address or hostname). You should be able to sign a starkit and then check the signature in your sandbox script. Regarding only fetching what is needed: starkits have an excellent solution to this in the form of starsync/sdx: it can not only fetch those starkits that have changed but can actually scan inside the starkit and only update those parts which need to be. This is all done within a Metakit database transaction too, so is safe from crashes etc.


Can't Get TK commands in TCL Script to Execute

I've installed Windows binay verions of TCL and WISH85 but can't seem to executed TCL scripts with TK commands. Here's my script, "button.tcl"...

#! "c:\Program Files\WinTclTk\bin\wish85"
button .b -text "press me" -command exit
pack .b
.b configure -background Red

I start tcl. Move to the directory where "button.tcl" is located and at the % prompt enter "source button.tcl"

Only result is that I get error message invalid command "button".

What am I doing wrong?

aricb: You are trying to use a Tk command without first loading Tk. Add this to the beginning of your script:

package require Tk

MG: Using wish on Windows, Tk should already be loaded, but if you were running tclsh you'd need the package require. Never hurts to include it, though, even if you are using wish. (If you're using wish, you'll have a blank grey window, and a white console window. tclsh will just give you a black Windows-command-prompt-style console.) There can also be other problems if you give your script the same name as a widget, by the way, so you might want to rename it to 'button-test.tcl' or something.

LV: Do the "bang" lines work on Windows? Is the above script being started via command line? If so, is that command.bat, powershell, mks, cygwin, UFS, MS posix or something else?

If the above script is not being started via command line, then perhaps you are not getting what you expect - there are at least two kinds of tclsh that I've seen around for Windows. One provides GUI support and one is intended to be used without GUI. Perhaps your system's binding is not set as you expect.


Some very obsfucated code in C

Larry: My apologies. This function is a function in C and not Tcl. I see a lot of mathematicians gravitating around this wiki. This code might be of interest. It has been circulating around the college since the beginning of the school year and no one seems to understand what this whole thing is about. There it is. The two unrelated parts. I am sure some of you will understand in no time. As for the rest of us we'd love to understand. Even the maths teacher doesn't get it!

void SN()  /* Starts at {^}; */

{Len=(Word[2]* 100 + Word[3] * 10 + Word[4] -5328);
Word[0]=224;
Word[2]=Len%256;

Word[1]=Len/256;

Word[3]=(Len = Word[6] * 100 + Word[7] * 10 + Word[8] -5328) %256;

Word[1]+=(Len/256) *4;

Word[4]=Word[10];

Word[5]=Word[11];

Word[6]=Word[12];

Word[7] = (Len = Word[13] *100 + Word[14] * 10 + Word[15] -5328) %256;

Word[1] += (Len/256) *16;Update:

Word[8] = NULL;

Len = 8;

}

And this one:

void ANB()

{

TSVar = getc(InFile) * 100 + getc(InFile) * 10 + getc(InFile) -5328;
DLWVar[0] = 128 + (TSVar/256) * 16;
DLWVar[1] = TSVar %256;

TSVar = getc(InFile) * 100 + getc(InFile) * 10 + getc(InFile) - 5328;
DLWVar[0] += (TSVar/256) * 4;
DLWVar[2]= TSVar % 256;

DLWVar[3] = getc(InFile);  
DLWVar[4] = getc(InFile);  
DLWVar[5] = getc(InFile);  

TSVar = getc (InFile)*100 + getc(InFile)*10 + getc(InFile) -5328;

DLWVar [0]+= TSVar/256;
DLWVar [6] = TSVar%256;    
TSVar=0;
}

Lars H: Looks like something parsing the header of some data structure. The mysterious constant 5328 is 48*(100+10+1), so it simply compensates for the ASCII code of 0 being 48, for all digits in a three-digit decimal number.

Larry: Interesting! So it's basically storing a set of numbers in a variable. The second variable being DLW. About the 3 digits decimal number, I believe you are on target Lars for a student also mentioned this set of 3 numbers.

About this code:

TSVar = getc(InFile) * 100 + getc(InFile) * 10 + getc(InFile) - 5328;
DLWVar[3] = getc(InFile);  
DLWVar[4] = getc(InFile);  
DLWVar[5] = getc(InFile);  

Another student mentioned that this line (TSVar = getc(InFile) * 100 + getc(InFile) * 10 + getc(InFile) - 5328;) means that the first number will be put in the thousands column, the second in the hundreds column and the third in the units. Ex: 345. I wonder. Why go through all that length and all those calculations to store 9 numbers in a variable is what noone has quite understood.

Precisely how is the data treated? Let's say the input is 123-456-789, what is precisely the transformation of these numbers and what is the end result, what is stored in the DLW variable.

Someone mentioned that the 9 numbers go from alphanumerical format to numbers and this number is converted to bits. I'd like to redo the process but in Tcl. How do I go about it?

In fact this might simply be a matter of converting a number into binary. Is there a specific TCL command I could use for that?

I'd like to redo this code in Tcl-Tk for let's say the beauty with Tcl-Tk code is that it is intuitive, precise, elegant and powerful and it never leads to situations where no one has a clue about what the code is about, a hieroglyph of sorts. Thanks for your greatly appreciated help!

Lars H: You are starting to sound rather clingy (sort of like a student posting his homework assignments in a forum, in the hope that someone will solve it for him), but it's all very simple:

  • To convert the numbers in something like 123-456-789 to native numbers in Tcl, use scan.
  • If you then need to convert these numbers to binary format (which is probably only necessary if the whole thing aims to do a text format to binary format conversion), then use binary format.

Those two shouldn't have been hard to find yourself…

Larry: Heydo Lars. Don't be hard on me. I did find out the page on binary format. I did my homework. But there is one thing that I was really uncapable of finding out is the Tcl command to read a binary file and to see the contents of a variable. Don't get me wrong. I am a beginner and I am a little well let's say very lost. Thanks again and heydo again. Do you say heydo in Swedish to say goodbye?


Scrollbar problem

I created a large one page application with lots of fields and buttons using the TK gui. Then I tried adding a vertical scrollbar but it doesn't scroll. Does anyone have any simple code that I could add to just scroll from top to bottom!

EE 2008-09-16: Perhaps you'd like to tell us HOW you tried to add a scrollbar? with absolutely no information about what you're trying to scroll, it's a bit harder to advise you.

MSH: It Sounds like he/she is trying to scroll frames. The TK scrollbars are associated with single 'scrollable' widgets not collections of entries/buttons/frames, the BWidget library has a ScrollableFrame] megawidget which builds a frame to contain other widgets which itself is scrollable. One quick note, applications with LOTS of fields/buttons are not very user friendly (especially with scrollbars) and there may be other methods (paned window/notebook...) to arrange these fields better.

This is an example of what I'm trying to do but on a smaller scale. This application has 3 columns 4 rows 3 buttons, 3 input fields, and a scrollbar widget spanning the 4 rows located in column 3. What code could I add to make it scroll as it doesn't do it?

# interface generated by SpecTcl version 1.1 from C:/SpecTcl/scroll_eg.ui
#   root     is the parent window for this user interface

proc scroll_eg_ui {root args} {
    if {$root eq "."} {
        set base ""
    } else {
        set base $root
    }

    button $base.button#1 \
            -text button1

    entry $base.entry#1 \
            -textvariable entry

    scrollbar $base.scrollbar#1

    button $base.button#2 \
            -text button2

    entry $base.entry#2 \
            -textvariable entry

    button $base.button#3 \
            -text button3

    entry $base.entry#3 \
            -textvariable entry


    # Geometry management

    grid $base.button#1 -in $root        -row 1 -column 1 
    grid $base.entry#1 -in $root        -row 1 -column 2 
    grid $base.scrollbar#1 -in $root        -row 1 -column 3  \
            -rowspan 4 \
            -sticky ns
    grid $base.button#2 -in $root        -row 2 -column 1 
    grid $base.entry#2 -in $root        -row 2 -column 2 
    grid $base.button#3 -in $root        -row 3 -column 1 
    grid $base.entry#3 -in $root        -row 3 -column 2 

    # Resize behavior management

    grid rowconfigure $root 1 -weight 1 -minsize 30
    grid rowconfigure $root 2 -weight 0 -minsize 30
    grid rowconfigure $root 3 -weight 0 -minsize 30
    grid rowconfigure $root 4 -weight 0 -minsize 30
    grid columnconfigure $root 1 -weight 0 -minsize 30
    grid columnconfigure $root 2 -weight 0 -minsize 30
    grid columnconfigure $root 3 -weight 0 -minsize 30
# additional interface code
# end additional interface code
}

CSV databases converted into binary files

Steve K: I am glad to see some people still use those very small and very handy CSV databases. Very interesting answers below. I have seen many a times csv databases converted into binary files for faster access. Is this a true fact -are they really faster?- or is it yet another urban computing legend?

How is the conversion into binary done in Tcl? What is the command? Also if I want to store values in one bit (256 characters), how is this done? I am a beginner in Tcl and any info I can get my hands on is useful. Thanks.

Larry: Read below re: the tcllib csv package) suggested by LV. It might help you greatly.

As for converting numbers into binary format, you're in luck. Try here: https://wiki.tcl-lang.org/1591

I know for a fact that retrieving numbers put into a binary format or even a database put in that format is a faster operation than retrieving regular numers or a txt database. What is the technical reason for that? It might have to do with the fact that the binary format is closer to the machine CPU language the same way C is closer to the machine CPU. This is the reason C is considered a low-level programming language (it is coded in Assembler and Assembler adresses itself straight to the machine). For info: Tcl, like most high level languages is coded in C. I'm no expert. But you might want to have a look at the article on Binary on Wikipedia.

This talk about binary, CSV files is not much in fashion today. I'm in my late twenties and my generation is not concerned with this problematic; an older programmer showed me around txt databases, binary conversions and I might say I was impressed.


Interactive syntax check (CSV data)

Larry: Hi, I have a comma-delimited database; stuff like field1,field2,field3. Pretty basic but cool enough. And it doesn't use a lot of space. I am working on some code to verify entries to make sure students are entering data correctly.

First I verify if there are 5 commas in each line in the database. If this isn't the case, the program stops and the student can make the changes. In the second field, there should be either a 0 or the following tag: CW000-aa000. CW has to be there. The other elements can vary from CW000-aa000 to CW999-zz999. If the syntax is not right, the program stops. The student verifies his entry. The fourth field works on the same principle but TLW has to be there instead of CW (we'll have 0 or from TLW000-aa000 to TLW999-zz999). The 5th field works also on the same principle but TS has to be there instead of CW (we'll have 0 or from TS000-aa000 to TS999-zz999).This is what I programmed so far and I seem to have not achieved what I wanted. I have checked and counter-checked but I must admit I'm stuck. Anyone has answers? Thanks!

I'd also like to highlight the error.

    set text [$::main_ht get 1.0 end-1c]
    set lines [split $text \n]
    foreach line $lines {
        if ![regexp {^([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*)$} $line whole source cw cat tlw ts dest] {
            if [regexp {^([^,]*),} $line source] {
                tk_messageBox -type ok -icon info -message  "Error! There should be exactly 6 fields at $source! Please correct!"
            }
            return 0
        } else {
            if {$cw != 0} {
                if ![regexp {cw[0-9][0-9][0-9]-[a-z][a-z][0-9][0-9][0-9]} $cw] {
                    tk_messageBox -type ok -icon info -message  "Error at $source in the CW field (field # 2)! The correct syntax is: 0 or cw000-aa000. Please correct!"
                    return 0
                }
            }
            if {$tlw != 0} {
                if ![regexp {tlw[0-9][0-9][0-9]-[a-z][a-z][0-9][0-9][0-9]} $tlw] {
                    tk_messageBox -type ok -icon info -message  "Error at $source in the TLW field (field # 4)! The correct syntax is: 0 or tlw000-aa000. Please correct!"
                    return 0
                }
            }Update:
           if {$ts != 0} {
               if ![regexp {ts[0-9][0-9][0-9]-[a-z][a-z][0-9][0-9][0-9]} $ts] {
                   tk_messageBox -type ok -icon info -message  "Error at $source in the TS field (field # 5)! The correct syntax is: 0 or ts000-aa000. Please correct!"
                   return 0
  
        }
    }
    return 1
}

Please provide one or two example lines from the data-base. So we can look at this issue right away. (<- line to remove)

MG: Without knowing exactly what's not working correctly or what data you're using... One possible problem is that regexp is case-sensitive, and you're matching against 'ts...', but you said the data was 'TS...'. You might need to use the -nocase flag for regexp, or some other alternative. For what it's worth, I'd probably do the whole thing something like this (untested):

set text [$::main_ht get 1.0 end-1c]
set i 0
set regexp {[0-9][0-9][0-9]-[a-z][a-z][0-9][0-9][0-9]}
foreach line [split $text \n] {
    incr i
    set list [split $line ,]
    if { [llength $list] != 6 } {
        tk_messageBox -message "Line $i contains [llength $list] elements instead of 6"
        return 0;
    }
    if { [lindex $list 2] == "Gym" } {
        foreach x {3 4 5} {
            if { [lindex $list $x] != 0 } {
                tk_messageBox -message "Line $i has Gym for field 3 but field [expr {$x+1}] has [lindex $list $x], not 0!"
                return 0;
            }
        }
    } else {
        foreach {x y} [list "CW" [lindex $list 1] "TLW" [lindex $list 3] "TS" [lindex $list 4]] {
            if { $y != 0 && ![regexp -nocase "^$x$regexp\$" $y] } {
                tk_messageBox "Error in the $x field on line $i (got $y, expected ${x}000-aa000 to ${x}999-zz999 or 0)"
                return 0;
            }
        }
    }
}
return 1;

Larry Thanks MG!

Interactive syntax check (CSV data) is indeed an excellent way to describe what I'm painfully trying to do.

Your code looks like code that will work. I can't wait to try it.

Now this is what the database will look like:

anthropology212,CW121-aa234,StockwellBldg,TLW476-ni609,TP012-fa098,Spring08

Fields 2, 4 and 5 are either:

  • CW000-aa000 tUpdate:o CW999-zz999 or 0
  • TLW000-aa000 to TLW999-zz999 or 0
  • TP000-aa000 to TP999-zz999 or 0

Hope this is clearer!

Say, how do I highlight the precise error?

A last thing. In field # 3, if I get the word Gym, the next 3 fields shoud all have a zero in them and nothing but a zero.

Ex: engineering123,CW111-aa121,Gym,0,0,0,

I have been trying to figure out how to do this for quite a while!

Thanks again!

MG: has updated the code above, hopefully it'll do that too now.

Larry: Many thanks again, MG! Now I get to understand better how things should be done.

I did manage to highlight the errors in yellow to my own surprise. It must probably have been my lucky day. A fluke as they call it. But I've been struggling with yet another problem: instead of having the program warn me of every error one by one I'd like it to highlight all the errors at once so that the student can do all the corrections in ons shot. I tried all kinds of solutions but none seems to work. Is there a quick way to go about this? Do you need my highlight code?

Thanks again for your excellent answers, MG.

MG: There are probably a few ways you could go about it. One would be to remove the returns, and instead of reporting the errors in a tk_messageBox, just lappend them into a variable. Then at the end,

llength $listOfErrors

will tell you how many errors there were, and you can always use something like

tk_messageBox -message [join $listOfErrors \n]

to report them (though you may want to insert them into a text widget or something like that, as more than 10-20 lines in a message box are often hard or impossible to read, on some platforms).

Larry: I'll try that. It sounds just right. Thanks again, Mike. I deeply appreciate.

LV: Just a side thought - would any of this be easier if you gathered the individual fields from the students, then created the records for them? I don't know enough of the background of the work being done. But it just seems to me that, since you are using tk anyways, providing a series of fields, then creating a csv record (using, perhaps, the tcllib csv package), might make some things easier. You could have different edits for each value, and not have to worry as much about the line as a whole...

Excellent idea, Larry. I'll try that. I wasn't aware the tcllib csv package) existed. It might ease things for me a little.

Thanks.

Here is the code: I'd also like to put a nice congratulatory window that will say: No errors! Congratulations!

proc verify.the.student.file.entry {} {
    $::main_ht see 1.0 
    $::main_ht mark set insert 1.0 
    set text [$::main_ht get 1.0 end-1c]
    set lines [split $text \n]
    set i 0
    set errors_count 0
    set errors_list [list]
    set regexp {[0-9][0-9][0-9]-[a-z][a-z][a-z][0-9][0-9][0-9]}
    foreach line $lines {
        incr i
        set list [split $line ,]
        if { [llength $list] != 6 } {
                incr errors_count
            lappend errors_list [list $i -1]
        } else {
            foreach {x y z} [list "CW" [lindex $list 1] 1 "TLW" [lindex $list 3] 3 "TS" [lindex $list 4] 4] {
                if { $y != 0 && ![regexp -nocase "^$x$regexp\$" $y] } {
                    incr errors_count
                    lappend errors_list [list $i $z]
                }
            }
        }
    }
    if {$errors_count == 0} {
        return 1
    } else {
        highlight.multiple.fields $errors_list
        tk_messageBox -message "$errors_count error(s) were found!\nPlease correct them and run Verify again."
        return 0
    }
}

Larry: I did run into a problem of sorts. Not to worry a small one. As soon as I click on a record to verify it, the highlight diseappears and this, even before I finish the line. It is not really good for I might have to do many corrections for a record. The simplest thing to do would be for me to keep the highlights on and afterwards to run a new Verify. Having the highlight on even for a record that has been verified doesn't really bother me. As usual I tried many different ways to keep the highlight and I can't seem to find a solution.

Any thoughts on this Mike?

In fact I must say having the highlight disappear when I correct the error is a pretty cool concept. But the problem is if I have two or more errors on the same line (hence two or more highlights) the highlight for all the errors on the same line disappear as soon as I correct the first error; this is not good since I am losing track of what is to be corrected. Is there a way to put some extra code so that only the highlight disappears only for the error corrected and not for the whole line? Thanks again.

Thanks again Mike and Larry. Your help is greatly appreciated in this hectic beginning of school year. Mind you they're all hectic but we'll survive.


Can code be copied freely?

I see here[L5 ] some useful code, can I copy it and use it, what is the copyright status?

See Who owns the content on this Wiki.


Are floats not Locale?

tb: Hi, I just did a little debugging with George, regarding TileGTK. George found out, that GTK sets the Locale and changes the format for floating point numbers to have a comma, where a period is expected. My Locale is de_DE and floats are really written like 0,234. It seems like the Gnome environment handles such floats regarding the Locale, when communicating with other modules, leaving Tcl behind.

Lars H: I believe the general opinion here would be that it is GTK/Gnome that is buggy, on the grounds that communication between software modules should be governed by a common protocol. If the format of (supposedly machine-readable) messages generated depends on something as flimsy as the locale, then there simply isn't a common protocol! It could of course happen that there is a well-defined protocol which allows both period and comma as decimal separator (in an attempt to be more tolerant to components that have a locale-dependency bug), in which case you need to handle both as well…

slebetman: note that the request for locale specific formatting does not imply local specific representation. When you write a C/C++ program using GTK you still write floats using dot as decimal point and save them to file with printf using dot as the decimal point but the UI accepts and displays the decimal point based on the locale. So no, GTK is not buggy in this regard.

Also note that it is usually impossible to accept both . and , as decimal points because they use , and . respectively as the thousand separator:

    1,000,000.75  ===  1.000.000,75

Lars H: From the "when communicating with other modules" part, I inferred that the problem was indeed that Gnome insisted on using a locale-dependent numerical format for IPC — a locale-specific representation. As I understand it, that the locale affects things like printf is a fairly commonly encountered misfeature of (some implementations of?) the standard C libraries. If this instead, as slebetman suggests, is just the UI matter of Tcl programs not taking the locale into account when formatting numbers to display to the user whereas "all" GTK programs do, then that's another matter — possibly the idea for a new tcllib module. Perhaps the original poster can clarify what the question was about?


Fitting rectangles on a page?

DB: Given a set of rectangles (representing images) of various sizes I'm trying to best fit them on a given canvas area. Allowing for rotation of the rectangles if desired. Not sure where to begin, and wondering if there's a known extension out there (or forumula) for doing it--it would seem something that would have been done before, but my searches are coming up empty.

Lars H: That's a packing problem (e.g. in the special case that all the rectangles are the same width, you end up with the bin-packing problem), which means it is probably rather hard (NP or so) to find an optimal solution.

I wrote a piece of code two years ago that addresses the incremental form of the problem (given images already positioned, where is the best place to put the next one?) by brute force, so it is at best a greedy heuristic, but it may be good enough. I'll put it at Packing rectangles.

After a night's sleep: Rectangle packing — given a list of rectangles to pack and a boundary rectangle within which to pack them, determine whether this can be done — is obviously in NP (the certificate is the positions of the rectangles). Checking the literature confirms that bin-packing [L6 ] is NP-hard, even in the case when there are only 2 bins.


Why does this have no effect?

tb: In a window creation procedure, which can create multiple instances of that window, I use:

wm protocol $w WM_DELETE_WINDOW "::destroyInstance $w"

to reset an array of window associated data, when the window gets deleted.

The destroyInstance procedure looks like:

proc destroyInstance {w args} {
    # tb - 2007-01-06 (02:16) Update:
    trace remove variable ::WINDATA($w) write "::selectData $w"
    array unset ::WINDATA $w
    destroy $w
}

I know this procedure gets called, but the unsetting has no effect. Is it a case of level nesting?

MG just ran

set w [toplevel .win]
set WINDATA($w) foo

Update:

followed by your code, then closed the window, and the variable was cleared without a problem. I can't see any obvious reason why it would ever fail, from what you've posted. Maybe there's something in the rest of your code causing the problem? (Incidently, if you don't ever want to stop the window being destroyed, but just do something when it happens, you can bind to <Destroy> for the window instead of using wm protocol, though you have to add an extra check for toplevels to make sure it's not being triggered for a child window.)

tb: Hi MG! Thanks for the hint on binding <Destroy> to the toplevel. I never knew about that. It works now as intended :)


Tk Console Issue With PuTTYcyg

FPX: I am using PuTTYcyg [L7 ] as my Windows console. This generally works much better than running Cygwin's bash in a Windows command-line window. However, it gets Tcl and Tk confused when started from within PuTTYcyg:

  • When running tclsh84.exe or wish84.exe, the "% " prompt does not show. Other output (e.g., from puts) is going to the terminal as expected.
  • When bringing up the Tk console ("console show"), the console prompt shows in the Tk console as expected. However, any output is going to the PuTTYcyg console rather than the Tk console.

The first issue I can live with. The second one is pretty irritating, though. Any idea how I can convince the Tk console to direct output to the Tk console rather than the PuTTYcyg console?

Lars H: Regarding the first issue: The % prompt is only output when tcl_interactive is 1. Is it perhaps 0 in your case?

Regarding the second issue: By "output", do you mean only results of [puts stdout] and the like, or also values returned by command typed in the PuTTYcyg console? The former seems logical to me (the process was given proper channels when started by the PuTTYcyg console, so wish wouldn't find it necessary to create mock-ups), the latter less so.

FPX: Indeed $tcl_interactive was 0. Setting it to 1 fixed the first issue. Thanks for the hint! (Although it is surprising why Tcl sets this variable differently when running in a PuTTYcyg console vs. running in a Windows command shell.)

As for the second issue, I mean both. The only text that I see in the Tk console is the very first prompt and the text that I type into it. All subsequent prompts, interpreter results, standard output and standard error go to the PuTTYcyg console. Again $tcl_interactive is zero, but setting it to 1 has no effect.

Lars H: Presumably the standard channels provided by PuTTYcyg are somehow different from the ones provided by the windows command-line. Different how? No idea, but apparently in some way that makes a difference for the startup code in tclsh/wish that wants to figure out whether it is connected to a TTY. File a bug at SF.

glennj 2008-10-22: Hey, nice find, I'm going to adopt PuTTYcyg too. Note in the FAQ that non-cygwin programs are not supported [L8 ]. I presume you're using the ActiveState tclsh and not cygwin's tclsh.


Is there a hook for an own error dialog?

tb: I'd like to replace Tk's error dialog. Is it possible?

Lars H: That's basically a matter of defining your own bgerror procedure. Does anyone have an example at hand? (Searching the wiki only turned up non-GUI definitions of bgerror.)

tb: Yeah! That's it! - I can navigate to ::bgerror using TclTalk's browser and inspect the source. I'd like to create a new dialog, showing the stack of called procs to browse their code, possibly with hilighted calling lines. I think it can be done by wrapping $::errorInfo.

tb: Here's my version, for further inspection at Replacing Tk's error dialog

peterc: There's also TclTalkback, which is another replacement for the standard bgerror proc.


What's the underlying data structure for a ::ttk::treeview ?

I can't get it working. How is the tree supposed to be setup? Is it a list of lists ?

LV: Did you read the treeview and ttk::treeview pages? The first one, treeview, in particular has sample code and a screen capture of the result.

tb: Hi Larry! Yes I read it, but it only shows how to fill the widget stepwise. Isn't there a way to set it up like a listbox with the -listvariable option?

LV: While I haven't used it myself, when I read the man page, I sure don't see any way to fill the widget other than stepwise.

tb: Ok, but it'd be nice to have a tcl list here at runtime, right now it is invisible for introspection.

MG: The best way to figure out what's displayed (that I know of) is using the $widget children and $widget item commands recursively:

proc printInfo {tree {parent ""} {level 0}} {
    puts "[string repeat {  } $level]Item \"[$tree item $parent -text]\" ([$tree item $parent -image])"
    foreach x [$tree children $parent] {
        printInfo $tree $x [incr level]
    }
}

printInfo .tree

Lars H: Did you really intend to increment the level at every iteration of the loop, MG? Looks as this would make a second child indented as much as a first grandchild…

lv: interestingly enough, I don't see a tip that discusses the treeview widget. I guess that any discussion about data structures, interface, etc. must have gone on within the Tile project work. Now that the widget is a part of the standard Tk distribution, a TIP would be needed to enhance or modify the interface. Perhaps the next step would be to post a note on comp.lang.tcl to see if you could find others who share your viewpoint and perhaps recruit someone who is passionate about the need to champion a TIP to enhance the interface. You might also try contacting the maintainer of the code itself, to see what their view on the matter is.

LV: When I looked over at http://www.tkdocs.com/ , at the ttk tutorials there, I don't see anything mentioned there about the functionality you are seeking .


A tcl interface for couchdb

Has anyone considered doing this? I am in the process of writing one and do not wish to duplicate effort.

If no-one responds I guess I should make a page?? I'm not sure of the process for doing this sort of thing...

nb couchdb is a document-oriented db written in erlang that has a RESTful interface.

chemuduguntar I am writing little library/wrapper that makes REST calls using curl. It is not very sophisticated, it uses the curl shell for e.g. it would be neater if it used the curl tcl interface. The JSON document is passed in as a string so you can use huddle's jsondump, but unfortunately there is no way to unserialise an json document without loosing type information (CMIAW).


Editing of pages on this wiki

I was reading https://wiki.tcl-lang.org/461 today and found some syntax on that page for which there is no evidence of any recent Tcl version supporting (either in execution or documentation). I asked on the Tclers Chat too and nobody there recognized it either. So I added a cautionary note to the top of the page, version 32. It seems the note was deleted three hours later in subsequent versions. Do I assume that there is a Wiki-war abrewing? Do we discuss this somewhere. Or, should I just forget it because it isn't worth the trouble? buchs

Lars H: I deleted it, because I found it unnecessary. The entries on those particular items (lookbehind constraints) already contained a note saying that they're not implemented in Tcl AREs, so what was your problem?


Cleaning up input data

Occasionally, users will paste, into a text entry field, data from some Microsoft product. This data looks, to the user, like legit characters, but contains things like Microsoft "smart quotes", elipse character, and so forth.

Does anyone have a regular expression/string map/whatever that could be used to translate this specialty characters into something that are not microsoft specific?

Thank you!

Lars H: There's nothing particularly Microsoft about the “nonsymmetric” »qoutes« or such — they were common under MacOS while PCs were still straggling with non-graphical user interfaces — although it would make sense that M$ now forces these characters onto unsuspecting users, when it has accepted that the characters exist…

Still, the characters are all perfectly legal Unicode, so the question is what you want, exactly. A way of ASCIIfying English text, perhaps? I'd suggest a string map is best for this; the work is mostly to compose the list of common problematic characters. Use scan %c to find out their codepoints, then write as \uXXXX-escapes in your code to prevent mangling by intolerant editors.


Tile Buttons

MG: Another one, I'm afraid :)

I'm trying to do toolbar buttons using Tile - something equivilent to Tk's

button .b -relief flat -overrelief raised

I tried using this (I know I'd want to use a custom style to do it right, but just to test):

ttk::button .b
ttk::style configure TButton -relief flat
ttk::style map TButton -relief {disabled flat pressed sunken active raised}

but got no joy; the button kept the defaults. Curiously, though, using a ttk::menubutton and replacing those TButtons with TMenubutton gave me a menubutton that did what I expected. Both the normal button and the menubutton looked fully native under Classic and XP themes, so I assume both are using Windows controls rather than having Tk draw them from scratch itself. Anyone know why it's working for the menubutton but not the button? Thanks in advance for your help.

Martyn Smith: There is a built in style called 'Toolbutton' (I suggest you reread clamTheme.tcl, These files are a MAJOR source of help) which defines this action for all themes. e.g.

ttk::button .b -style Toolbutton -text EUREKA

you might want to look at the 'TEntry' sections as well.

MG: Thanks again for your help, Martyn, that does exactly what I need (though I'm still curious why what I tried didn't work -- something similar to the problem I had before, I imagine?). I didn't realise that things in the clamTheme.tcl file would have any relevance while using other themes (and though there is a mention of Toolbutton in the xpnative.tcl theme, it's only to set the -padding option - is the Toolbutton style imported from somewhere else that I've not noticed, or provided in the Tcl source rather than at the scripting level?) Anyway, thanks again, that's gotten just about the last of my GUI converted to Tile now, so hopefully I won't have any more questions any time soon ;)

Martyn Smith: The clamTheme.tcl only initialises the attributes for the clam theme by modifying the default parameters. All my theme files create the Toolbutton style, I think that this is all that is necessary to add this functionality. The blue theme is only a blue.tcl file and a set of PNG files.


How does the Tile entry widget work?

MG: I'm trying to switch a lot of an app over to Tile, but I'm having trouble finding any docs/info that are both up-to-date and comprehensive; so far most of what I've gotten working has been largely through guesswork (and some of it's probably wrong, even though it seems to work).

  1. Does anyone know of a detailed tutorial?
  2. Or failing that, my current problem:

I'm trying to use an entry widget which keeps the same background colour even when it's disabled. I've tried just about everything I could think of; just using a -background option for the widget (seems to be ignored), trying to define a custom style (but I'm not really sure what I'm doing with that from the docs; it has no effect, but maybe I'm doing it wrong).. any help would be greatly appreciated.

(I have considered just using a regular Tk entry widget for it, which is what I'm doing currently - but when it's on a screen with a half-dozen other entry widgets that are from Ttk, it just looks out of place.)

3. slightly later - I'd also like to change the default cursor for all !disabled ttk::entry widgets to be xterm. That one, at least, does seem to work with

ttk::entry .foo -cursor xterm

but I'd prefer to change the default, instead of having to give it every time, if possible.

Martyn Smith: I use something like

style map TEntry -background [list {disabled} white]
style map TEntry -foreground [list {disabled} black]

something similar should work for -cursor or any other attributes see ttk::style and the 'xxxTheme.tcl' files in the tile directory for more details.

LV: With regards to 1, I presume you know about http://www.tkdocs.com/ ?

MG: Thanks for your answers. That's actually one of the things I tried, Martyn, and it didn't have any effect:

ttk::style map TEntry -background [list {disabled} red]
ttk::style configure TEntry -background red
ttk::entry .e
pack .e
.e state disabled;# shows an entry widget with a greyed out background

Same thing with -cursor, too. I'm using a Tclkit (8.5.1) on Win XP, btw. (I hadn't seen tkdocs.com before, but will take a look at it now, thanks.)

MG: Just read through most of the tutorial on tkdocs. It's very well done, but doesn't currently cover anything other than the basics of using the Ttk widgets (like the ttk::style command, for instance).

LV: You started out asking about more documentation on Tile. The developer at tkdocs is the one with whom you want to work. He has a Google group where questions and discussions can be held, and hopefully as you work out with him what info you are needing, his pages at the web site will improve.

MG: I'd love to work with the developer at the TkDocs site to document some of the more complex parts of Tile. Unfortunately, though, I just have no idea how they actually work (and read that he also has no knowledge of those parts, or the time to try and figure it out currently, though I forget where that was now). And there doesn't seem to be any place with clear, concise and up-to-date/working explainations of how any of the commands work/can be used to do these kinds of things. Some current documentation would be great (all I've really found so far is the man pages for ttk::style, which I haven't really found all that clear or helpful, and some stuff on this wiki which is unfortunately out of date now), but failing that someone who actually knows how they work (or has at least manage to fiddle with the commands and get the outcome I'm trying to, which is more than I have) who can explain it so I could document it somewhere would also be really helpful.

PT: With the XP theme (and the Aqua theme will likely be the same) the entry uses a 'field' element to draw the basic background and this is defined by the platform. To take control of the colours you have to create an element that you control and configure a style appropriately. The 'default' theme is a good source of Tk drawn elements or you could create an image element using the image element engine (see ttk::style element create).

Cursor handling for ttk widgets is as for normal widgets. You can set a 'class' configuration using the options database.

The following is a sample of an overridden Entry widget which has an alternative background element that may be set to a given colour. Note that the colour is part of the style - not part of the widget data so all Plain.Entry widgets with use the same background colours.

proc PlainEntryInit {} {
    catch {
        # Import the 'default' theme field element.
        ttk::style element create plain.field from default
    }
    
    # Create a new style using the imported element.
    ttk::style layout Plain.Entry {
        Plain.Entry.plain.field -sticky nswe -border 1 -children {
             Plain.Entry.padding -sticky nswe -children {
                 Plain.Entry.textarea -sticky nswe
             }
         }
     }
     
     # Configure the colour and padding for our new style.
     ttk::style configure Plain.Entry {*}[ttk::style configure TEntry] \
        -fieldbackground LightSteelBlue -cursor hand2
     ttk::style map Plain.Entry {*}[ttk::style map TEntry] \
        -fieldbackground {!focus SteelBlue}
     
     # Re-do if the user changes theme.
     if {[lsearch -exact [bind . <<ThemeChanged>>] PlainEntryInit] == -1} {
         bind . <<ThemeChanged>> +PlainEntryInit
     }
  }

MG: Thanks very much. :) I'm not entirely sure quite how it works (but it does, which is the main thing to start with;), but I'm slowly figuring at least some of it out. Thanks :) The binding on . for <<ThemeChanged>> is a good one to remember, too; most of the stuff I've set up myself in Ttk will probably break across themes without something similar. Thanks again :)


web app / Tcl plugin / source

How can I write a web app using the Tcl plugin and get it to source in code and package require other code?

crv 2008-05-12: I have been using Tcl for a couple of years and am now using the Tcl plugin for some interesting projects -- but there are limitations! I have overcome many of them but would like to source some code and include some packages on the fly. I primarily use the home policy and the user will not have Tcl packages installed to their machine. Is there a way to do this? I am a mechanical engineer by trade so am not as programming literate as many of you -- so keep it simple if possible. Thanks in advance. (NOTE: Tcl sure is a handy tool!)

GWM: try to understand Starkit and Starpack - once your script is packed into a starpack a single executable file will include the tcl script (or script files), wish interpreter and any packages that you specify. A starkit requires a separate wish interpreter Tclkit.

crv 2008-05-14: I didn't know that Starkits/packs worked as a tclet (within the Tcl plugin). Where can I find info on how that works?

Duoas: Just download the latest Starkit for your platform, then download SDX. Use SDX to wrap a single tcl file (with qwrap) and then unwrap it and you'll have a structure to begin with. You can unwrap SDX itself to find internal Wikikit documentation.

peterc 2008-06-10: Duoas and GWM, are you sure you're talking about the same thing as crv? He seems to be asking about the Tclets through the Tcl Plugin [L9 ]. The plugin is the Tcl interpreter in this situation.

I don't believe the default policy will allow you have your Tcl script source another one, but, this might be doable by changing the settings on the end-user side. Of course any end-users who would actually do that, on any site but their own, probably need their desktop PC reimaged daily ;-).

Another approach would be to develop your app as multiple files and then use Another Tcl module maker to turn that into a Tcl module. Then change the extension from .tm to .tcl.

FWIW, the current Tcl Plugin has some deal-breaker issues at the moment. Its TkTable package kills browsers on Windows and there's no Mac version. At the least, it needs to have those issues fixed, add Tile support (as part of its upgrade to Tcl 8.5) and preferably be installable into browsers in a similar way to other common plugins like Flash, Shockwave, etc. It's in desperate need of updating. I gather Jeff Hobbs is working on it though.


SOAP and packages

pcam: I wanted to play with SOAP, but did not get very far because of what I suspect is incompatible package versions. Please help.

% package require SOAP
attempt to provide package SOAP::Utils 1.0 failed: package SOAP::Utils 1.0.1 provided instead

I then corrected utils.tcl and changed the sub package utils version to 1.0 to load it and avoid the error message

% package require SOAP
1.6.7.1

When trying the examples from http://tclsoap.sourceforge.net/ I get the following error:

% SOAP::create c2f -uri http://www.soaplite.com/Temperatures \
     -proxy http://services.soaplite.com/temper.cgi \
     -params { "temp" "float" }
::c2f
::c2f
% c2f -40.0
invalid command name "newDocument"

I traced the error to the call ::SOAP::soap_request in soap.tcl (tclsoap 1.6.7.1) to that line

set doc [dom::DOMImplementation create]

I then tried to load the dom package which does not seem to be available on my system.

I have installed tdom 0.8.3 and TclXML 3.1 using teacup

LV: Here's what I just did:

$ /vol/tclsrcsol/ActiveTcl/bin/tclsh8.5
% package require SOAP                 
1.6.7.1
% SOAP::create c2f -uri http://www.soaplite.com/Temperatures \
      -proxy http://services.soaplite.com/temper.cgi \
      -params { "temp" "float" }
::c2f
% ::c2f -40.0
-40

So, I don't see the problem you are seeing. However, I typically run a teacup update on my system on a regular basis, so I have the latest versions of things installed. teacup tells me I have tclxml Version : 0.0.0.2007.11.22.23.08.18 .


ActionScript Interpreter for Tcl

Hello together, my aim is to write an interpreter for Tcl in ActionScript, so that you can manipulate large ActionScript programs with Tcl. I read that Tcl has no reasonable grammar because everything is a command. But I think every interpreter has a scanner/lexer and a parser which is based on the grammar of the language that should be interpreted. Furthermore Tcl syntax has some keywords that should be accounted for. Moreover I found an interpreter for Tcl in Java, called JACL whose source code looks like a grammar-based interpreter. It is a little bit confusing to me but I think that there is a little gap in my thoughts. So I hope that someone can shed light on the dark.

Thanks in advance! Stephan

Lars H: Well, one reason interpreters are traditionally divided in separate scanner and parser stages is that context-free grammars (as used in the parser stage) are really lousy at handling the type of rules (e.g. a longest sequence of alphanumeric characters is a token) that are used in the scanner stage; the proponents of parsing expression grammars (see grammar::peg) seldom miss a chance to point out that they can do it in one stage. As it happens, the standard interpreter for Tcl has separate scanner and parser stages, but this is probably not necessary; I think Tcl is one of the few languages for which it would actually be feasible to give a character-level context-free grammar. But this is probably a more theoretical answer than you wanted.

Technically, all the language syntax of Tcl is what you find in the dodekalogue. There are no keywords in the language (unless you count delimiter characters, escapes, and so on as keywords), just commands, even though there are plenty of commands (e.g. for, if, while, proc) which do things for which other languages reserve keywords. Analysing a Tcl script is therefore complicated — parsing gives a shallow analysis, but some commands have arguments that are themselves scripts, and you need to recognise these commands and reparse their arguments as scripts in order to determine the complete script structure. The good news is that evaluating a Tcl script is much easier — you only need to parse the "then" branch of an if as a script after you've evaluated the condition and found it to be true.

If you just want to have a small Tcl interpreter, then Picol might be a good place to start. This wiki also has Tcl in Javascript, and other reimplementations can be found in the Tcl implementations page.

 Update:

Enter/Return for Navigation

AK: I'm trying to figure out how I could bind the Return key to act as the Tab key for navigation purposes. Any suggestions would be appretiated!

MG: Something like

bind all <Return> [bind all <Tab>]

will copy the binding, but several widgets have existing bindings for <Return> that will take precedence. If you want yours to override that, you'll need to bind each widget, or set up a new bindtag and apply it to others:

bind ReturnToTab <Return> "[bind all <Tab>] ; break"
text .t
bindtags .t [linsert [bindtags .t] 0 ReturnToTab]