Ask, and it shall be given # 3

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.

Please do not edit this part, it is meant as a guide!



Questions


automate a windows application

ashish (8 April 2006): i want to automate a windows application i.e.i want to minimise user involvement in certain procedures and i want windows to perform certain steps automatically can u suggest me any thing related to this using tcl/tk

A: See dde, COM, Inventory of IPC methods, Techniques for 'driving' Windows applications, ...


example code snippets

LB 5/3/06

I am searching for simple example code snippets for a technique in Tk. I wish to display widgets (picklists, messages, etc) and assemblies of widgets in a separate window that overlays my main window without distorting the main window. Using frames I can embed my widgets, but depending on their content, the window they're inserted into may distort ( I use grid).

This is such a fundamental operation that I'm sure it must be supported and I've just not found an example of it. I suspect it entails using a frame or toplevel as a container, but have struck out on my experimentation.

I have most of the Tcl/Tk books, so pointing to an example therein would be a quick way to help (although I've been searching them).

TIA,

~Lan Barnes

LB Answering my own question:

 #!/usr/bin/wish

 proc close_tl {} {
        destroy .topl
 }

 proc call_tl {} {
        toplevel .topl
        button .topl.quitb -text Quit -command close_tl
        pack .topl.quitb -in .topl
 }

 button .callb -text Call -command call_tl
 pack .callb

This little stub does what I was looking for. Adding grab to make it modal and wm to simplify the top level frame are left out for simplicity.

Thanks to Clif Flynt for the hints that led me to this.


GUI

MG 05/04/2006

I am facing a problem with my GUI. In my GUI a window gets opened and that window has a browser button for selecting file. If user has clicked on the browse button and the browse window has been opened and user closes the parent window(window having browse burron) by clicking the cross. Both the windows disappear, but after that when I try to do something I get errors which are related to the same code used to open the browser. So I feel that the windows are destroyed but the flow has not returned from the function which was executing the browsing of file. So How can I make sure that the flow too returns back

 from there.

MG (not the one who asked the question, though, the one who uses the MG wiki page;) Which OS are you using? On Windows, tk_getOpenFile uses the native file selector. I assume you're using a Linux system (or MacOS?) which uses the pure-Tcl alternative?

MG

 Yes, I am using the Linux environment, Redhat 3 version.

MG Looking at the code which powers those dialogs briefly, it looks like you shouldn't be able to close the other window while the dialog is still open - it sets a grab. But I don't think your browser window should disappear too, though - unless the window with the button was '.', the main window, and by closing it they closed Tk? If not, could you show us what the actual errors you're getting are? (I'm a Windows user myself, so I'm not greatly familiar with the Linux dialogs - anyone who uses them seen an issue like this?)

MG -

I am providing a simple code which might show the problem after opening the wish, issue following commands -

   button .a 
   pack .a
   toplevel .b
   button .b.a
   pack .b.a
   tk_getOpenFile -parent .b

Now this will open up the browser window. If you click on cancel of browser, the flow immediately comes back to the shell, while if you click on the cross of "b", then the flow does not come back while b as well as browser window has gone.


Tcl shell

MK I want to create a shell in Tcl/Tk which will allow user to type Tcl Commands and see the result. Is there any enhanced text widget, or any package which can provide this feature. - RS Check the console - built-in for Windows and Mac, easily added on other platforms (see console for Unix). For more bells and whistles, see tkcon.


Kanotix

wdb (Feb 18, 2006) Question about Tk command raise on Linux distribution Kanotix. The Tk command raise has no effect -- solved, article moved to Problems with raising/lowering windows


SOAP

snichols I need help with generating the correct SOAP envelope (at least the SOAP request the web service understands). Please see this link: SOAP Complex Data. Thanks in Advance.


Find largest (and smallest) entry in a numerical array

Was wondering if there's a quick way to pick out the largest (and smallest) entry in a numberical array? For instance, if myArray = [-2 3 6 7] , the largest element is 7, the minimum is -2 . I know I can set up a for-loop to go through each element of the array, but I was just wondering if TCL provides a more sophisticated way of doing this. Thanks! --Arnie - RS:

 % set try {3 -2 7 6}
 3 -2 7 6
 % lindex [lsort -real $try] 0
 -2
 % lindex [lsort -real $try] end
 7

Lars H: That's a rather unTclish syntax and terminology, so I suspect you're a beginner, aren't you? Given a list of numbers

  set my_list {-2 3 6 7}

then you may indeed, as you observe, find the smallest using a loop, e.g. as follows (making use of the infinity trick):

  set min infinity
  foreach num $my_list {
     if {$num < $min} then {set min $num}
  }

A more compact alternative is however to sort the list and pick out the smallest or largest number using lindex:

  lindex [lsort -integer $my_list] 0 ; # Smallest element
  lindex [lsort -integer $my_list] end ; # Largest element

(This is an O(n log n) operation and thus asymptotically slower than the time-linear foreach loop, but in practice you'll probably need to have very large lists for this to make a difference.)

ECS Or, without infinity:

  set min [lindex $my_list 0]
  set max $min
  foreach num $my_list {
     if {$num < $min} then {set min $num}
     if {$num > $max} then {set max $num}
  }

wheel-mouse

MG Feb 12 2006 - I'm on Windows XP, and use a wheel-mouse. The drivers/software which came with the mouse include a feature where you can click the mouse wheel, and then move the mouse in any direction to scroll (clicking the button again turns this feature off). It works in the vast majority of applications on Windows - I can think of very few where it doesn't - but none of my Tk text widgets can be scrolled with it (or any other Tk widgets, I don't believe). Where it works, the feature knows whether the application in question can scroll horizontally/vertically/both, and displays a different cursor accordingly. Does anyone know why this doesn't work in Tk apps - is it that Tk isn't "registering" the fact that the window can be scrolled (a wild guess, but the most logical thing I can think of)? Anyone know how hard it might be to fix this? (I've seen this feature with many different (brands of) mice, with different software providing the feature, and it's never worked in Tcl/Tk apps.) Thanks for your help :)

Peter Newman 12 Feb 2006: Check out these two pages on MSDN Mike (especially the second one):-

 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformscontrolclassmousewheeltopic.asp
 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/mouseinput/mouseinputreference/mouseinputmessages/wm_mousewheel.asp

Gives you an idea of how Windows apps. handle the MouseWheel. Presumably, Tk doesn't. But you could probably add that support by looking for WinMain in the Tk sources, and adding support for the WM_MOUSEWHEEL message (or modifying the existing support so that it does the required). But, how the application knows that it's the window to be scrolled, rather than the mouse to be moved, I've no idea. The answer will be in those MSDN docs. But, you're probably in for a lot of reading and thinking. Good luck...

MG Hi Peter, thanks for the response. Tk does scroll when you roll the wheel, it's just the extra functionality provided by the mouse's software which doesn't work. I'll try and dig through the links you gave and their related pages later today and see if I can find anything that explains it/shows how it could be changed.

Peter Newman Yeah, I just read about it in the bind manpage. If by extra functionality, you mean changing the cursor, that would be easy enough to implement (I think). Just bind to the <MouseWheel> event. And, whenever you get one, switch the cursor accordingly. And bind to mouse movement events too. These should restore the default cursor. I think that would work (though I haven't tried it).

MG It's not actually something I'm trying to implement in Tcl/Tk, per se. In many other apps (Internet Explorer, for example), if I click (not scroll) the mousewheel, it changes the cursor, and I can then move the mouse in any direction and the window scrolls in that direction. Clicking the mousewheel again (or scrolling it/pressing another button) turns this feature off. It's not a part of Internet Explorer, though - it's a feature provided by my mouse driver, which works in more or less every application with a scrollable window. But not in Tk apps - when I press my mousewheel, it simply fires the Tk app's <Button-2> event. My best guess is that Tk isn't registering the fact that the window can be scrolled, in some way, and so the OS/mouse driver isn't intercepting the <Button-2> click and doing its own thing, but is simply sending the click through to Tk to handle (which is what seems to happen in apps where this feature does work, but the window in question can't be scrolled at the time).

Peter Newman 13 February 2006: As I read it, Tk/wish does support the MouseWheel event the way you want it too. In that its WinMain listens for the WM_MOUSEWHEEL message, and then raises a <MouseWheel> event via the bind mechanism when it receives it. But it's up to the individual Tcl app. to handle that message/event. If it doesn't, then MouseWheel scrolling is ignored. It seems to me that a Windows supported MoseWheel must work in two modes; 'Mouse' mode, where it emulates a mouse, and 'MouseWheel' mode, where it acts as a MouseWheel. Clicking the mousewheel obviously switches it into 'MouseWheel' mode. In 'Mouse' mode, Windows moves the mouse pointer automatically for the app, and sends the standard mouse messages (excluding WM_MOUSEWHEEL) to the focused app. And in 'MouseWheel' mode, it sends WM_MOUSEWHEEL. Obviously, the app. concerned has to handle WM_MOUSEWHEEL, and do the necessary scrolling and cursor changing, etc, as required. So, you can make a Tk app. handle the mousewheel the same as any other Windows app. that supports the mousewheel. But, you'll have to manually add a <MouseWheel> event handler to every (scrollable) widget that you want this MouseWheel support for. Ie; You have to add:-

 bind .someScrollableWidget <MouseWheel> ScrollTheWidget_AndSwitchMouseWheelCursorOn_AndSetMouseWheelModeFlagTrue
 bind .someScrollableWidget <Button-1> IfMouseWheelModeFlagTrue_SetItFalse_AndRestoreNormalCursor
 bind .someScrollableWidget <Button-2> ditto

(or something like that,) to every widget you want to support the MouseWheel. See description of the <MouseWheel> event, in the bind manpage.


console

2006-02-08 CSW I don't have the console command. I did get spawn -console to get control of the console, however I don't know where the information is going. It's not on the console or the terminal. How do I grab that info?

2006-02-02 CSW I have written a terminal that runs on SunOS. I need to redirect control of the console to the terminal. I tried the -console from Expect but the OS doesn't support this command. Any suggestions?

RJ 2006/02/05 SunOS (at least mine) has a console command - try spawning that - spawn console -s <server name>


create wikit

2006-02-03 LB -- Again I am convinced I have seen the answer somewhere but cannot find it now.

I want to create a wikit wiki instance with a different name than "My Wiki" which seems to default no matter what I do. There must be either a command line flag or a way to edit the title once the .tkd is formed.

TIA,

- Yep - the text entry field at the top of the Home page will do that.


wikit

2006-02-02 LB I am replacing an internal wiki (inside the company firewall) with Wikit. The formatting page and Help page are enough for the basic operation, but the hint about URLs that end in .jpg and .png/.gif hasn't come clear in my experimentation. I want to display photos and graphics. Is there a more detailed instruction document or tutorial for Wikit?

MG I believe that, if you type a link in directly (without enclosing in square brackets), the link is displayed normally. If you enclose in square brackets, the picture itself is shown. For instance (first is not in square brackets, second is; pictures stolen from the Graffiti page) http://www.websmileys.com/sm/aliens/monsterwink.gif and http://www.websmileys.com/sm/aliens/monsterwink.gif

LB -- Thank you, that worked perfectly. I'm forced to conclude that my references to local pictures are being munged somehow, brobably through a rewrite dictated by the internal web server's understanding of the data root. I'll experiment more and should be able to resolve it.


string match

2006-17-10 Hi! Does anybody know why the following code prints 0, but not 1 ?

  set s \[test\]
  puts [string match \[*\] $s]

Thanks. Anton.

MG As well as being special to the Tcl parser, the [ ] characters also have special meaning to string match. You can use a range of characters in brackets to match. For instance:

  string match \[a-z\] c

matches, because 'c' is in the range 'a-z'. To make your match work how you intend, you need to escape the brackets twice: once from the Tcl parser, and once from string match's little language:

  % set s \[test\]
  [test]
  % puts [string match \\\[*\\\] $s]
  1
  % puts [string match {\[*\]} $s]
  1

encryption and decryption

2006-01-25 Hello! I have a question about safe encryption and decryption. Assume we have the following: 1) encrypted data; 2) a TCL program that is able to decrypt this data using TCL libraries.

Question: is it possible to make this data nondecryptable by any program except of that specific TCL program?

Thanks. Anton.

ECS: No. One could write another program in another language to decrypt the data.

Security of data should the a function of the algorithm to encrypt it (known to attacker) and a secret key.


color of a pixel

HJG 2006-01-24: I have some problems to Get the color of the pixel under the pointer.


OO / ParentClass

01-09-06 I was wondering what would be the advantages/disadvantages of option 1 Vs option 2. Option 1 inherits the ParentClass and adds custom functionality to the sMethod. Option 2 has an option called "command" in the ParentClass that an allows simply to set the "command" option by the derived MyObject with the custom lines of code. Both yield the same effect. I would appreciate the input. Thanks

Sarnold : Please tell us what OO system you are using ; I cannot see whether it is [Incr Tcl] or XOTcl. Thanks.

I am using Incr Tcl......

OPTION 1:

 class ParentClass {
    public {
        method sMethod {}
    }
 }
 body ParentClass::sMethod {} {
    some lines......
    some lines......
    some lines......
 }

 class MyClass {
     inherit ParentClass

    public {
        method sMethod {}
    }
 }
 body MyClass::sMethod {} {

    ParentClass::sMethod

    some custom lines.......
    some custom lines.......
    some custom lines.......
 }

OPTION 2:

 class ParentClass {
    public {
        variable command
        method sMethod {}
    }
 }
 body ParentClass::sMethod {} {
    some lines......
    some lines......
    some lines......

    uplevel #0 command
 }

 ParentClass MyObject

 Myobject configure -command {some custom lines.......; some custom lines.......; some custom lines.......}

Sarnold Well, when working with buttons you really need a callback (the -command parameter). But best practices are, often expressed, to keep a callback simple so that it fits in one or two lines.

At that point, it seems to me that using inheritance - with all its drawbacks - is better in this case.


mail / sybase.log

12-29-05 I want to mail a message to me if the size of sybase.log = 0. This script does not finish and I have to logout from the server and then log in again. I would appreciate any help. This is the script:

 if {[string match [file size /home/oracle/dba/logs/sybase.log] "0"]} {
     exec mailx -s "Sybase log is 0 bytes" [email protected]}
 } else {
     puts <oramessage>NO</oramessage>
     puts <oraresult>2</oraresult>
 }

escargo - What happens when you do your mailx command from a command line? (What's your platform, what's your Tcl version, etc.?)

The script do nothing and do not exit. The Platform is Sun Sparc Solaris version 5.8 and the TCL that I'am using is Oacle TCL.

ECS: mailx reads from standard input. Try to redirect stdin to /dev/null.

escargo - I think that probably the right answer. The mailx command is trying to get command line input for the body of the message, which it isn't getting. (I didn't ask what the script did; I asked what mailx did if you ran it outside the script.)

LCO I tried also redirecting to dev null but also it takes forever. The script does not finish. Maybe is the syntax that I'am using:

 oratclsh[1]-
 if {[string match [file size /home/oracle/dba/logs/sybase.log] "0"]} {
     exec mailx -s >/dev/null 2>&1 "Sybase log is 0 bytes" [email protected]}
 } else {
     puts <oramessage>NO</oramessage>
     puts <oraresult>2</oraresult>
 }

escargo 11 Jan 2006 - Note that the advice was to redirect stdin to /dev/null. You redirected stdout to /dev/null. Also note that as long as you are in Tcl to start with, why not use what's in tcllib? See smtp for examples and other possible solutions.

LCO Thank you very much escargo, the script below, using the stdin to /dev/null was the answer. As you can see it is obvious I know the basics of Unix only. Thank you again for your help. The smpt suggestion told me that the package of smtp was missing.

 if {[string match [file size /home/oracle/dba/logs/sybase_tables.log] "0"]} {
     exec mailx -s </dev/null 2>&1 "Sybase log is 0 bytes" [email protected]
 } else {
     puts <oramessage>NO</oramessage>
     puts <oraresult>2</oraresult>}

escargo - You could do this instead:

 if {[file size /home/oracle/dba/logs/sybase_tables.log] == 0} {
     ...
 } else {
     ...
 }

That will do a more direct comparison.

You could even take advantage of the fact that 0 is false, and do this:

 if {[file size /home/oracle/dba/logs/sybase_tables.log]} {
     puts <oramessage>NO</oramessage>
     puts <oraresult>2</oraresult>
 } else {
     exec mailx -s </dev/null 2>&1 "Sybase log is 0 bytes" [email protected]
 }

Unix "script" command

HP 28 Nov 2005 Is there a script which immitates the Unix "script" command in Tcl. I need to record an interactive Tcl session on Windows, and need exactly what the "script" command does on Unix.

LES Tkcon. File > Save...

HP This works, but I need this functionality in a real shell as well, such as when using tclsh. (This is what we're actually using in the meantime)

RJ OR - Expect for Windows.

     package require Expect
     spawn -noecho <command to get to DOS shell>    ;#start a session with shell
     log_file filename  
     interact                 ;#give session to user
     #..<interaction with shell - everything scripted to "filename">
     log_file
     #..<terminates scripted session to "filename" and saves the file

Remember to thank Don Libes in your prayers.

HP RJ - "interact" is not available on the windows version of expect. Supposedly it is difficult to implement in Windows.

RJ Clearly, I am Windows-challenged. I stand corrected.


TCL on Solaris

Ron 8 NOV 2005 I just installed TCL on Solaris system. When I type tclsh the message "ld.so.1: tclsh: fatal: libgcc_s.so.1: open failed: No such file or directory c/r Killed"

It looks like it compiled, but something else is wrong. Any ideas?

RJ Try checking setenv for LD_LIBRARY_PATH - if it isn't there or doesn't contain the path to your tcl libraries this is what you'll see.


build tkimg

Escaladix:2005/11/04

Does somebody know where is described the good procedure, for a beginner like me, to build correctly "tkimg" on windows with cygwin?

When I use the following procedure:

configure

make -mno-cygwin all

in the top build directory and

make install (or make -mno-cygwin install)

in the top build directory or in the sub directories of the build directory, errors are produced and any format specific directories and dll libraries aren't built.

If you have any knowledge of the subject, please, help me.

Thank you in advance.


compile TCL code into bytecode

2005/10/20

Is it possible to compile a TCL code into bytecode (or binary exe)? The goal is to speed up a TCL application.

aricb The short answer is no.

The long answer is: the Tcl interpreter bytecode-compiles procs by default; there are some things you can do to make that compilation more efficient, notably putting braces around [expr] expressions (e.g. [expr {$a * $b}] rather than [expr $a * $b]). Code that is not inside procs is not bytecode compiled.

It's possible to make an executable out of a Tcl program. People do this for convenience of deployment (starpack and freewrap) or to protect closed-source intellectual property (Tcl Dev Kit); the end result is bytecode-compiled, but it's no faster than the original Tcl script (which is also bytecode-compiled by the interpreter).

KJN 2005/11/05: Would bytecode compilation into .tbc files at least speed up loading, which would no longer need a compilation step? Python seems to use this trick for its libraries.


Daylight Saving Time

2005/10/20

jpt When Windows adjusts the DST "Daylight Saving Time" back to normal (Normal Eastern Standard Time or whatever), all after commands that are pending are delayed by one hour. In my script, all the loops that are scheduled to run after a few seconds won't run until an hour! Do someone know a way to circumvent that problem? Is this happening also under Unix/Linux or is it just another Windows bug?


column in file

2005/10/12

I would appreciate some help with the following:

I have a file (from a simulation) containing lots of data. The first column is the frame number. The seventh column contains data the data of interest (z coordinate). So i would like to bin the z coordinate for each frame so i would end up with a 3d data set. column 1 would be frame, column 2 would be z coordinate and column 3 would be occurrences of that z coordinate within the frame.

Is this possible with tcl and if so, please can someone help me get started?

Thank you in advance.

Syma Khalid

University of Oxford

Peter Newman 13 October 2005: Are you wanting to graph the data? Or are you wanting to enter the data into a program, and do further computation/analysis of it? Or both?

Syma 13 Oct 2005: I would like to graph the data using Xfarbe- thank you!

Peter Newman 13 October 2005: So, what is it that you want Tcl to do? I assume, from looking at the Xfarbe site, it would be to convert the data you have, to the Xfarbe format (and then possibly, to run Xfarbe). Tcl can do that quite easily. But I'm not sure if that's what you wanted.

Syma 13 Oct 2005: I'd like to create the input file for Xfarbe with my data. So i have a file containing data for a number of frames, where the first column is the frame no and the seventh column is the z coordinate. I want to end up with a file with 3 columns, the first the frame number, the second being z coordinate and the third being the number of occurrences of that z coordinate in that frame. So the script will go through and bin the z coordinate values for the first frame, then start over for the second frame etc etc.

So something like this:

Frame no: Z coordinate Occurrence

1 10-20 2

1 21-30 0

1 31-40 4

1 41-50 1

2 10-20 0

2 21-30 1

2 31-40 4

2 41-50 3

I hope this is clearer!

MG offers this (untested) suggestion:

 proc parseData {originalFile {outputFile "./data.txt"}} {

  set allFrames [list]
  set allZs [list]
  set highest 1
  set fin [open $originalFile r]
  while {[gets $fin line] >= 0} {
         set data [split $line " "]
         set frame [lindex $data 0]
         set z [lindex $data 6]
         if { [catch {zRange $z 10 highest} z] } {continue; #some error occurred, so ignore this line}
         if { [lsearch -exact $allFrames $frame] < 0 } {
              lappend allFrames $frame
            }
         #if { [lsearch -exact $allZs $z] < 0 } {
         #     lappend allZs $z
         #   }
         if { ![info exists count($frame,$z)] } {
              set count($frame,$z) 1
            } else {
              incr count($frame,$z)
            }
    };# while
  close $fin
  for {set i 1} {$i <= $highest} {incr i 10} {
       if { [lsearch -exact $allZs [set range [zRange $i 10]]] } {
            lappend allZs $range
          }
      }
  set fout [open $outputFile w+]
  foreach frame [lsort $allFrames] {
    foreach z [lsort $allZs] {
             set howMany [expr {[info exists count($frame,$z)]?$count($frame,$z):0}]
             puts $fout "$frame $z $howMany"
      };# foreach z
    };# foreach frame
  close $fout
 };# parseData

 proc zRange {num {steps 10} {var ""}} {
  set base [expr {floor($num / $steps)}]
  if { $base < 1 } {
       set base 0 ; set num 1
     }
  set start [expr {int(($base * $steps)+1)}]
  if { $num < $start } {
       incr start -$steps
     }
  set end [expr { int($start + $steps - 1) }]

  if { $var != "" } {
       upvar 1 $var high
       if { $high < $num } {
            set high $num
          }
     }

  return "$start-$end";
 };# zRange

Which should take a file like this:

  1 some other data not used 14.6
  1 some other data not used 18.2
  2 some other data not used 25.7

And output one that looks like this:

  1 10-20 2
  1 21-30 0
  2 10-20 0
  2 21-30 1

This works on the assumption that all columns are separated by a single space (and all single spaces separate columns). If that's incorrect, it'd need some altering.

Syma 14 October 2005: Hi- thanks for this MG. This is working so far, but teh probelm is the data of interest is not already in groups. So i (inadvertently) misled you in teh info i gave. So the data of interest is in real number format ie 54.35627 rather than 50-60. So i would like to build in something that would allow the user to define teh bin widths and then assign data to it. Please can you help. Thank you for your patience.

MG Modified the above so that it should put it into ranges for you. The only "problem" is that numbers such as 20.001 don't fit into either 11-20 or 21-30. (Currently it puts them into the lower range, so 20.001 up to 20.999 will go into 11-20, and so on.)

Syma When attempting to run the above script i get the error message: invalid command name "zRange"- any help would be appreciated.

MG Added in a missing bracket, which I very stupidly missed out. I've now lightly tested this (using the test data above) and it seems to work fine, outputing exactly what it says it will above. I didn't get the error about missing 'zRange' at all, Syma - the zRange command is also provided above (I added it in when I made the previous modification). Make sure you have all of the code above saved, and try running it again?

Syma before testing again, i'd like to ask an embarrassingly simple question:

to run this do i only have to change the originalFile and outputFile bits then run this from tclsh? again thanks for your patience.

MG You'll need to run the code above (which defines two new commands). Then, you'll need to run this line of code, too (which runs the new commands):

  parseData "c:/orignal/file.txt"   "c:/results/of/code.txt"

It's that line where you'll need to edit the paths, to reflect where your original file is, and where you'd like the file with the results in to end up. (If you have any other questions about running it, please put which operating system you're using, as the best/exact way to run the code differs between Windows and Linux. Thanks.)

Syma Ok so I'm running on linux (fedora core)

This is exactly what i did:

tclsh

source ask.tcl

parseData "./data.dat" "./out.dat"

where data.dat was just copied and pasted from the example above, ie 1 some other data not used 14.6 etc

The message i get is: can't use non-numeric string as operand of "/"

Trying my original data file gave me:

can't use empty string as operand of "/"

Sorry again.

MG I imagine that with your original data file, the problem is that there are "extra" spaces - if the colums are separated by anything but a single space, the code above won't work. If you want to email me it ([email protected]) I can tailor the code a little to work with the exact layout. As for it not working with the test data above - I altered the test data earlier today (it shoed 10-20 before) to reflect the fact that your real data has floating-point numbers, and not ranges (10-20). Did you use the updated one for your test? If so, it should have worked correctly (or at least did for me). Using the older one, with the ranges, produces the error you mentioned.

MG Updated the code above to work as required, after talking w/Syma via email and getting it working as needed. The last "can't use non-numeric string as operand of /" error was because some lines didn't have 7 'columns', so the lindex returned an empty string - it now catches the error, and ignores any lines where that happens. If someone wants to move all of this to a more appropriate page, if there is one somewhere, please feel free to do so now.


Tk_Canvas in a Tcl-Extension

2005/10/10

Does someone know how I do create and show a canvas-object (Tk_Canvas) in a Tcl-Extension or where I can get DETAILED information about this? (Unfortunately, manpage of tk-library-functions only said that some functions exists, but not really how to use...)

aricb The easiest way to do this would be to call Tcl_Eval with a little script that creates and displays the canvas.


close window

ABU 2005-10-07

There are a lot of advices in this wiki about how intercept/handle window manager closing my tcl ; all these advices are based on the wm protocol command. Something like:

 wm protocol . WM_DELETE_WINDOW {
    ...do something before closing ..
    exit
 }

I always used this technique for saving the application status, so that when user restart the application, he can magically resume his working.

Unfortunately, at least on Windows, there are cases this technique does not work: When user does a shut-down, or simply log-off the current session, all applications are closed (of course), but this is not done by the window-manager; this is done by the O.S.

  • In this latter case, the application does not receive the WM_DELETE_WINDOW, then the 'status' is not saved !

This is a real pity !

On the other hand, we can see some simple standard applications (such as notepad.exe) that are able to prompt the user for saving the current document (if necessary), even if a "shutdown" is started. My curiosity is:

  • How can a simple application (notepad) be informed that it is being to be killed ?
  • How could I implement a similar behaviour in Tcl (for Windows, and maybe for *unix and Mac) ?

Peter Newman 8 October 2005: AFAIK, it's all handled by the Windows messaging system. See here [L1 ]. Presumably, 'tclsh' and 'wish' grab the Windows messages, but ignore the 'shutdown' ones (assuming there are such messages). Presumably then, the Tcl app. has to intercept/hook these messages, so that it can detect/process them. But how one does this, I've no idea.

MG One solution to (half of) your problem is to bind to <Destroy> instead, for saving your prefs. For instance...

  wm protocol . WM_DELETE_WINDOW chk_exit
  bind . <Destroy> {savePrefs . %W}
  proc chk_exit {} {
    set ans [tk_messageBox -message "Really quit?" -type yesno
    if { $ans != "no" } {
         exit;
       }
  }
  proc savePrefs {top this} {
   if { $top != [winfo toplevel $this] } {
        return; # stop us saving prefs every time a widget under $top is destroyed
      }
   # do stuff to save prefs
  }

That still wouldn't get the user prompted, on shutdown, but it should still save the prefs, at least.

ABU Thanks, but half solution is not enough. Does anybody know how a simple Windows application like notepad.exe can intercept the kill/shutdown messages (?) for saving the current document ?

Do you think it could be enough to provide a library (dll) or does it require a tcl-core extension ?

Peter Newman Like I said above, it's all handled by the Windows message handling system. You've no choice but to spend time at the link I gave above, understanding it. Consider this quote (from there):-

 Since Windows is a message-oriented operating system, a large portion of programming for the Windows
 environment involves message handling. Each time an event such as a keystroke or mouse click occurs,
 a message is sent to the application, which must then handle the event.

In other words, Windows messages are much the same as Tk events. When someone clicks "Quit" or "File Save" (or whatever,) in Notepad, Windows sends a message to Notepad, telling it about this. Notepad then invokes its "File Save" or whatever handling code. A Windows app. like 'wish' or 'tclsh' can intercept another Windows app. (like Notepad)'s messages. Which is what you want to do.

Then, I think you'll find you can create the necessary code (to call the necessary Windows API functions,) with ffidl or Yet another DLL caller.

Cheers (and good luck).


window size

Evgeny Sep 29 2005:

is there a way to determine how much space in pixels a Tk widget wants to take "naturally"? (below i explain why i want it, but i'd like to know the answer regardles of possible workaraund)

i want several widgets of different size be placed in a lined-up fashion - i.e. have extra space appear padded so that i could add a second lined up column on the right etc. i understand i can use grid, but what if i want to have several instances of such table (with different content) each enclosed into its own label frame (just want to design a nice looking entry form) Thanks!

Peter Newman 30 September 2005: I can't see that it's a problem; just a case of using pack and/or grid appropriately. But I'm not 100% sure exactly what you're after. Perhaps if you start a new page, with some ASCII (or whatever,) pictures of what you're after. Then, we can make some suggestions...

aricb If your goal is to create nice-looking forms, you might have a look at Adrian Davis' GRIDPLUS package.

TR You cannot tell how much space a widget will take naturally until it is managed/displayed using pack, grid or place. After that, use winfo height and winfo width to see how much space in pixels they really took.

aricb [winfo reqwidth] and [winfo reqheight] will tell you how much space a widget "wants" to take, before they are geometry-managed.

Peter Newman winfo height and winfo width are kinda buggy. In that it typically takes 10 to 100 milliseconds (sometimes longer,) till they return the correct values.

Evgeny 30 Sep 2005: Thanks guys! GRIDPLUS looks nice, and winfo reqwidth works in Tcl and solves the problem. winfo width only works after something is packed which serves a different purpose of course.

P.S. I am actually doing that in Python/Tkinter and there winfo_width is of no use at all - always returns 1 however winfo_reqwidth works well. http://blogigo.de/hydrocodone/

I am not sure (tell me if I am wrong) that Tcl is a proper language to deal with complex data structures and their manipulations ;) but seems to suit great for building gui's

aricb Glad to hear that you found some things that work for you. You are right that Tcl is not the best language for all situations, but it is good for a lot of things and, when properly coupled with some strategic C code, it's even better. When you say "complex data structures and their manipulations," what do you have in mind?

Evgeny thanks, Aric, i posted my answer on my wiki feel free to edit

Evgeny Apparently in Tkinter winfo_width works fine after calling update_idletasks(), something that has to do with the way Tkinter works.

aricb Right; this is documented on the [winfo] man page. When you geometry-manage a new widget, Tk arranges for the event loop to display your widget. The event loop always waits for any currently running code before processing scheduled tasks, which is why you have the delay Peter mentions above. When you call [update idletasks], you force Tk to process some of the event loop tasks immediately rather than when Tk would normally process them, including the task of displaying your widget. After your widget is displayed, [winfo width] and [winfo height] give you the answers you'd expect.

ABR update idletasks (or just update) doesn't seem to achieve this effect in 8.5a6.


ogg stream player/icecast

Navin Hi, I am new to TCL, I wanted to make a very light, small ogg stream player, which can play icecast2 stream. I need to develop something very simillar to https://wiki.tcl-lang.org/14032 . The code on this page plays shoucast stream whereas I wanted to play icecast2 stream. Please Help

Peter Newman 3 October 2005: You might have to be a bit more specific about what you want help with.


escargo 26 Sep 2005

I have added to my personal page (escargo), a problem I am currently having trying to develop something like source that does logging.

It seems to handle single-line Tcl correctly, but falls down with commands spanning multiple lines.

I've tried to keep the example input and the sample code small, but I didn't want to clutter up this page too much, so I request your attention there.


chr(), ord()

LES: Does Tcl have something like PHP's chr() [L2 ] and ord() [L3 ] functions? I can make my own if it doesn't. I just want to know if Tcl already has them.

MG The scan and format commands do that:

  % set num [scan A %c]
  65
  % format %c $num
  A

LES Yes, your method works, but some results don't match the ASCII table I have here. I will check that later.

MG I have no idea whether this actually is the problem, but it's something that may be worth trying. Do

  encoding system ascii

before you run the scan/format.

Lars H: No, encoding system shouldn't make a difference for format or scan (things would actually get rather hairy if they did). More likely causes are:

  • If the differences are for chars with codes >127, then it's not an ASCII table you've got, because ASCII is a 7 bit encoding. Rather, you probably have an "extended ASCII" table. Use encoding convertfrom to convert foreign chars to Tcl's native unicode before you scan them, or fconfigure the channel you're reading them from with the proper encoding.
  • If the differences are for chars with codes <= 127, then you may have encountered some of the chars where people tend to divert from strict ASCII. Most notable is the "backquote" `, which according to strict ASCII is really a grave accent (why that was considered a useful character is however beyond me).

Changing encoding system may however look as it fixes things, as it changes what encoding Tcl uses when sending data to other software (e.g. file system, possibly the terminal, etc.).

LES: I am sorry. I was in such a hurry yesterday and must have made a mistake. I just ran new tests and everything seems to be OK. The test:

 foreach i [exec seq -s " " 300] {
     rw a c:/windows/desktop/ascii2.txt "$i: [format %c $i] : [scan [format %c $i] %c]\n"
 }

rw is a file reading/writing/appending proc.

The only problem I still seem to have is that neither Tkcon nor pure Tcl in Cygwin can display any chars from 0127 to 0159. Although my text editor can display most of them. It fails on 0129, 0141, 0142, 0143, 0144, 0157 and 0158. MS Word and Wordpad display a few more chars, like 0142 and 0158. I am on Windows 98 right now and will run more tests on Linux later.

Neither Tkcon nor pure Tcl in Cygwin can display some characters, but the test above proves that they are still intact internally.


MG Sep 21 2005 - I'm trying to compile a Tcl app on Windows which uses Iwidgets, with freewrap. I basically just wrapped the contents of the itcl3.3, itk3.3 and iwidgets4.0.2 folders from my /tcl/lib folder into the .exe, then copied them all into a folder (all files in the same folder - I combined the 3 pkgIndex.tcl files into one single pkgIndex.tcl) when the app runs. It loads Iwidgets fine, but when the app runs an iwidgets::panedwindow it throws this error:

 cannot inherit from "itk::Widget" (class "itk::Widget" not found in context "::iwidgets")

Anyone have any idea what the problem might be? Any help would be greatly appreciated. Thanks!


ping

Ashish on 2005-09-19 @ 1204 PM EST

I am trying to ping a ip address in tcl, can some one please give me some pointers ?

Thank you Ashish

RJ See solution to the question below. Same way. Or see Expect extension doc. Just spawn a ping command and expect on the ping response.


GUI-wrapper to a console application

MRS on 2005-09-14

I am trying to make a graphical wrapper to a console application. This application has many parameters that can be set in the command line, so the idea is to make a GUI for this and then invoke the command. I want to have the output (also text) of this command in a text widget. I know that

 set out [exec program]

will store in out the output. The problem in this case is that the software being wrapped takes a long time to finish and from time to time it will output some progress.

My question is, there is a way to update the text widget during the run of the console-based program to be wrapped? - [I think not. exec has only the eof callback. Would you be able to set prghandle [open "|program" r+] and use fileevent to update your text widget?] RJ

MRS Yes, it works. Thanks!


ns

08 Sept, 2005. Gurpreet Singh

I am running a tcl file in ns2. I wish to call a tk window from that file, but seem to be getting too many errors. Basically, I cant run the tcl script using the standard "ns" command, because the tk commands such as canvas are not recognized. And i cant use "wish" to run the tcl script because some variables are being read in using the "source" command, and these cause errors to tk.

Someone, help pls!

Peter Newman 9 September 2005: I think we need some more info. 1) What is "ns2"? 2) What is "the standard "ns" command"? 3) I don't think we could answer the question without seeing the script. Is it available on the Net somewhere?

RJ same day: This should be interesting. Answer to 1) ns2 appears to be a network simulator written in (at least partially) Tcl/Tk. See [L4 ] for a start on that. Gurpreet, you're in the right place now - go ahead and supply info on 2) and 3) above. But please create a new page to move this to once your problem is resolved. It may become a valuable source of information.


incr tcl

skm 2005/07/28

I am interested in mapping incr tcl objects to a relational database. I am just beginning to learn about O/R mapping, and I've gathered some essays to read about it in general. There's a tcl conference paper from 2003 about this [L5 ], and I was wondering if there is yet a standard O/R object mapping solution for incr tcl or for any of the other OO packages for tcl? If I end up writing my own, it won't be elegant enough to release into the wild right away (assuming I get permission to do so). Seems like it would be a nice thing to have.


Iwidgets::scrolledtext

MK I am using Iwidgets::scrolledtext for writing and editing text. Is there any "real" text editor in TCL with different colors for comments, keywords,.. such as a gvim or emacs .

MG The ctext package in tklib provides a syntax-highlighting-enabled text-widget. It's a relatively simple matter, then, to add scrollbars and save/open file functionality to it. Any other features you might deem necessary for a '"real" text editor' can probably handled, too, depending on what you want.

The Tcl Editors lists some programs, too, but I haven't studied the list in detail. It points out though that many are for editing Tcl in, and aren't actually written in Tcl. So I'm not sure how much use they might be...


download

Angel Sosa 2005.06.29

          Is there a way to down load this website?

          From [email protected]

escargo - See the bottom item on About this site.


configure network

rdt 2005.06.27 Here is the problem. A tcl script is running on a system with network down. The script configures the network and brings it up. If the script attempts to open a socket to an outside machine using the IP address it succeeds. If it attempts to open a socket to that machine name, it fails. If it spawns a separate process to open the socket by name, it succeeds. So it appears as if the socket code in the running script, does not get correctly configured for dns when the network "comes up", whereas when it starts up on a configured network, it does. What command needs to be given to the socket code to "configure" it after bringing up the network?

rdt 2005.09.29 No response for this. Guess no-one has an answer or just doesn't care.

KJN 2005-11-05: I've reproduced your problem (on a Linux system). If I switch off networking, and then start a tcl process that restarts networking, I get the problem that you describe:

  exec /sbin/service network start
  package require http 2.5
  http::geturl http://www.google.com/

fails with the error message "couldn't open socket: host is unreachable". However, I only get the problem if both (a) I delete /etc/resolv.conf, which contains the IP addresses of the nameservers, when I stop networking - it is rewritten by DHCP when networking is restarted; and (b) I attempt a DNS lookup before switching networking back on. In fact, it is not necessary to stop and start networking - simply move /etc/resolv.conf before launching Tcl, and move it back after doing the first lookup. The Tcl process remembers that it doesn't know where to find nameservers, and doesn't try again. It is very likely that this is not a bug in Tcl but in the resolver library: man resolv.conf says "The config file is read the first time the DNS client is invoked by a process" - which is why a new process launched by exec has no trouble. If your network uses DHCP, you need to make sure that /etc/resolv.conf does not get deleted when networking is stopped. If you are using DHCP on Windows, try setting the DNS server IP addresses in the TCP/IP properties, instead of obtaining them from DHCP. If all else fails, call an external process (e.g. dig) to do your name resolution - or at least to check that name resolution is working before using it directly from your Tcl process.

rdt 2005.11.05: Thanks, for your work. I believe that you are absolutely correct in your analysis.


podcast

LV 2005-June-27

Anyone written any Podcast related software in Tcl? Right now, I'm looking at some crudely written bash code, but would have preferred to find some neat Tcl software that would work cross platform, from command line (for cron type executions) and perhaps with a tk gui for interactive use.

I understand that it's not that hard to write; I'd just as soon not go through the life cycle of the effort if not necessary.

Henry Flower 2009-08-24

Googling for "tcl podcast" gives [L6 ].


wish-reaper crashes tclkit

Sarnold 2005-06-26

The following code taken from wish-reaper crashes tclkit (8.4.9 and 8.5a2) but not ActiveTcl :

 wm title . "Wish Reaper"
 set font {Helvetica 14}
 frame .reaper
 pack .reaper -expand 1 -fill both -side left

 tk_messageBox -icon info -message "Reaping complete." -type ok\
                -parent .reaper

The operating system tested is Windows ME.

escargo 27 Jun 2005 - I copied this code out and ran it on my Windows XP Pro system with ActiveState ActiveTcl 8.4.9.0 and with tclkit 8.4.9. Both crashed immediately. (The message box never came up.) The failure on Windows XP Pro is accompanied by a message box of a kind that asks if you want to send an error report. One of the controls on the box is "To see what data this error report contains, click here." If you click, you get a more detailed box (including an "Error signature") and another control that says, "To view technical information about the error report, click here." If you click, a window labeled "Error Report COntents" appears with "Exception Information", "System Information", a module list, a thread list, and a stack.

This error appears to be highly repeatable; perhaps knowledgeable people could use the provided information to determine the underlying cause. I'll have to check to see where else this info should go.

Peter Newman 28 June 2005: I've come across what looks like a similar thing, at 2 or 3 places in my own app. It happens (in my app.,) when I pop-up a message box whose parent is a toplevel that's just been destroyed. Doing this generates a Windows page fault error, and wish exits. I call it the "half-disappeared toplevel" problem. In your case, it looks like wish-reaper is just starting. So maybe it can happen when the toplevel's half-open too. Put a few seconds delay between the pack and the tk_messageBox, and see if that solves the problem.

Generally speaking, if you ask Tk to do something on a nonexistent window, it will complain that the window doesn't exist. But quite obviously, there's definitely a bug in wish, in that it doesn't always catch the situation where the window is in a transitory state.

In my case, I solve the problem by making the tk_messageBox's -parent the main window (.). But whether that will work in this case, I don't know. http://blogigo.at/lipitor/

escargo 27 Jun 2005 - When I changed the test code above to use "-parent ." explicitly, it no longer crashed. When I updated my local copy of wish-reaper to change all the uses of -parent, it no longer blew up. I'll update the wiki copy when I have the time.

Peter Newman 28 June 2005: There's obviously a bug with the tk_messageBox -parent option, then. tk_messageBox should really be able to detect that the specified -parent is dodgy.

escargo 28 Jun 2005 - This has now been filed on SourceForge as bug 1229263.

escargo 22 Jul 2005 - There's been a new release of ActiveTcl, but my bug seems to have disappeared. I can't find it through the bug tracker. Where did it go? Was the problem fixed?

Lars H: Sometimes bug reports are "fixed" by being recategorised as feature requests--perhaps that is what happened to your report?

escargo - As a long-time software maintainer, removing the cause of a crash is not a feature. It's not like I'm demanding a fix; I just want to know how to determine the status of my bug report.


BLT

jpt 2005-06-24

What should I do to get BLT load in tclkit under Windows (tk_version=8.4; tcl_patchLevel=8.4.9) ?

I always get: couldn't load library "BLT24.dll": this library or a dependent library could not be found in library path

   1) I've downloaded BLT v2.4z for tcl8.4 and installed it in my "lib" dir 
      ''(I used a directory tree like the one presented at [http://www.equi4.com/191]''
   2) I opened tclkit and used "lappend auto_path" to add the "lib" dir where BLT is installed
   3) then I type "package require BLT"

Note that other binary extensions (like dll10.dll) load normally without error.

Peter Newman 25 June 2005: I've also got ActiveState 8.4, and in this BLT24.dll is in Tcl/bin; not Tcl/lib. There's also a BLTlite24.dll in Tcl/bin - and a few other dll's which may or may not be part of BLT. Try putting BLT24.dll in Tcl/bin. And if that doesn't fix it, let me know and I'll list the other dlls for you (and email them to you if you want). Also, there are PE (Portable Executable) Viewer type programs downloadable from the Web that tell you what a given dll's dependencies are. So, inspecting BLT24.dll with one of those should tell you what's missing.

However, whether those solutions will work with BLT in a TclKit, I don't know (isn't Tcl/bin in the kit?). I think you have to get a TclKit with BLT burnt into it. Two such kits are; bikit.exe and; dqkit-win32-i386-all.exe. You can Google for them.

jpt Thanks Peter. Bikit solved my problem for now. However, i've tried a "dependency walker" software, and it seems that there is something wrong with blt84.dll. The software reports this error: "Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module."" I may investigate this later.


icursor

June 18, 2005 [J on Linux} I'm having difficulity getting icursor to work in the chosen field. I can use delete, insert, get for a specific field but icursor either won't work or after rebuilding the field the cursor will end up in the wrong field. Any suggestion will help.


fmod

Muthu June 15th 2005:

    I see weird result from fmod function in tcl. 

For below example, i expect the result to be 0.0 but it returns 6.44.

 %  expr fmod(19.32,6.44)
  6.44

  However, in below example expression, i get 0.0.

  % expr {fmod(25.76,6.44)}
   0.0


  Any help in deciphering this conundrum is appreciated.

Peter Newman 16 June 2005: I get the same results as you. And can't explain it. Looks like fmod is buggy and unreliable to me.

ABU 16 Jun 2005 : I'm not an expert of the "fmod" semantic, so my reasoning is by analogy with the "modulus" operator semantic. Following this analogy, your strange results are not errors, but simply an approximation due to floating-point number imprecision.

The fmod(x,6.44) function should always return a value within the interval [0 ..6.44) . Be careful that in a modulus-6.44 arithmetic (!) the distance between 0.0 and 6.44 is ZERO, i.e. 0.0 and 6.44 are equal !

Maybe the result was "6.44-epsilon" and this was printed as "6.44".

For the modulus-6.44 arithmetic the difference between "6.44-epsilon" and "0.0" is just "epsilon" ! Therefore your result was not an error, but simply a floating-point negligible approximation.

Lars H: Quite right. Subjecting the result of fmod to some more arithmetic verifies this suspicion:

 % expr fmod(19.32,6.44)
 6.44
 % expr fmod(19.32,6.44)<6.44
 1
 % expr 6.44-fmod(19.32,6.44)
 8.881784197e-16

See also a Real problem.

If you want serious results, you should forget floating-point numbers and use integer arithmetic.

If your operands are simply decimal numbers (with limited decimals), you could multiply both operands for 10^N ( so that they become integer numbers) and then use the integer-modulus operator

  fmod(x,6.44)  
    is equivalent to 
  (int(x*100) % 644) / 100.0

Muthu June 17th 2005 - Thanks a lot for all who clarified floating point calculation. MG June 14th 2005 - Does anyone know of a way on MS Windows to find out exactly what version you're using? I know you can use $tcl_platform(osVersion) to get some info, but that's the same (5.1) across all versions of XP, Home and Professional, SP 1 and 2, etc. Searching through the registry, I managed to find a couple of keys in

  My Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion

ProductName and CSDVersion, which are (on my XP Home SP2 machine) Microsoft Windows XP and Service Pack 2, respectively - couldn't find anything to differentiate between Home and Pro versions, though. I don't know if those can be relied upon, either (to exist on all NT machines, or to be correct). Anyone know the best way to get a "clean" textual representation of the Windows OS that works for all versions? I usually just check for $tcl_platform(platform) == "windows" and then work off $tcl_platform(osVersion), but it can come up a little short at times. Thanks in advance for your help.

AET download psInfo.exe free from Sysinternals [L7 ].

Sample output:

 . . . [ SNIP ] . . . 
 Kernel version:            Microsoft Windows XP, Multiprocessor Free
 Product type:              Professional
 Product version:           5.1
 Service pack:              2
 Kernel build number:       2600
 . . . [ SNIP ] . . . 
 Processors:                2
 Processor speed:           2.7 GHz
 Processor type:            x86 Family 15 Model 3 Stepping 4, GenuineIntel
 Physical memory:           1016 MB
 HotFixes:
   KB834707: Windows XP Hotfix - KB834707
   KB867282: Windows XP Hotfix - KB867282
 . . . [ SNIP ] . . . 

Peter Newman 16 June 2005: The official Microsoft solution is on the "Operating System Version" and "Getting the System Version" pages on MSDN; [L8 ] and [L9 ] respectively. They're in C, so you'll need Yet another DLL caller or something.

I think AutoIt can do it too, perhaps writing the info. to a text file (of your own design,) that you can parse; like "psInfo.exe", above.

APN On NT 4.0 and up, you can also use TWAPI. See get_os_version http:://twapi.sf.net/osinfo.html#get_os_version, get_os_infohttp:://twapi.sf.net/osinfo.html#get_os_info, and get_os_description http:://twapi.sf.net/osinfo.html#get_os_description.

MG will look into all of those later tonight. Thanks for your help, guys!


bug in the Text widget

MG June 8th 2005 - A friend of mine thinks he's found a bug in the Text widget. There are a couple of large screenshots with it, so I've put it up at Text Widget Bug. Any help/ideas would be greatly appreciated. Thanks :)


sockspy

Lars H, 7 June 2005: I'm experimenting with the proxy functionality in sockspy, using this wiki at experiment subject, but it seems to be a bit ... shaky. I have managed to view normal pages, but get errors for e.g. references pages. Here's an excerpt showing what I mean:

Sockspy:

 16:58:06 connect from 127.0.0.1 localhost 8091 54200
 16:58:06 fowarding to wiki.tcl.tk:80

Client:

 16:58:06 GET http://mini.net/tcl/references/2740! HTTP/1.1
 16:58:06 Accept: */*
 16:58:06 Accept-Language: sv-se, ja;q=0.55, en-us;q=0.93, en;q=0.90, no-no;q=0.86, no;q=0.83, da-dk;q=0.79, da;q=0.76, de-de;q=0.72, de;q=0.69, fr-fr;q=0.66, fr;q=0.62, ja-jp;q=0.59, sv;q=0.97, es-es;q=0.52, es;q=0.48, it-it;q=0.45, it;q=0.41, nl-nl;q=0.38
 16:58:06 Accept-Encoding: gzip, deflate;q=1.0, identity;q=0.5, *;q=0
 16:58:06 Referer: http://mini.net/tcl/2740
 16:58:06 User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; sv-se) AppleWebKit/125.5.5 (KHTML, like Gecko) Safari/125.12
 16:58:06 Connection: close
 16:58:06 Host: wiki.tcl.tk
 16:58:06 
 16:58:06 

Server:

 16:58:08 HTTP/1.0 400 Bad request
 16:58:08 Content-type: text/plain
 16:58:08 
 16:58:08 This is not a valid URL for this site
 16:58:08 

Sockspy:

 16:58:08 ----- closed connection -----
 16:58:08 waiting for new connection...

The strange thing is that the exact same URL -- issued from the same browser after changing the proxy settings there, or copied from the GET line and entered into a browser that ignores proxy settings -- does work when not going through sockspy. So what is going wrong?

Peter Newman 9 June 2005: I don't know if this is relevant or not - but for the last month or so - and just on the Wiki - my browser sometimes (maybe 1 out of every 10 times,) pops up its "Open or Save" dialog, when I click on a link??? I just click "Open" of course. I've never experienced this before, on any other web site, in many years of browsing. So there seems to be something strange going on with the Wiki.

Lars H, 10 August 2005: For some reason, LES in between versions 141 and 142 of this page changed the above URLs from having server wiki.tcl.tk to mini.net. Why did you do that, LES? Or is has the wiki suddenly got magic link-rewriting built in?

In any case, I have since used sockspy as a proxy when communicating with several other servers, and it has worked fine. (Very handy when you're away from campus and need to browse some subscriber-IP-only web sites.) Why there should be something in this wiki which it chokes on is still a mystery, however.


LAME / pipe

dzach 2005-6-3

I am looking for a way to use the LAME mp3 encoder in tcl. Running on a win98 laptop, I get errors using a pipe with the LAME executable. So, now, I'm trying to use the lame_enc.dll instead. The problem is described in LAME. Any help please?


format-date / xslt

skm 2005/06/02

I am having trouble using format-date (http://www.w3.org/TR/xslt20/#format-date ) with tdom's xslt command. Here's the troublesome part of the XSL document.

 <xsl:value-of select="format-date($datetime, '[Y]/[M]/[D]')"/>

The xml being processed has this node:

 <note datetime="2005-06-02T17:32:17">is this thing on?</note>

Here is the result

 % $datedoc xslt $formatdoc formathtml
 Unknown XPath function: "format-date"!

skm 2005/06/03 -- it turns out that format-date is new in XSLT 2, and tDOM only supports XSLT 1 for now.


unperson Some mods have been made to my homemade editor in order to run it with the new TCL Kit, the beta version (9,0?). Unfortunately I get all sorts of error messages when I run it with the new TCL Kit. What is wrong? Is it because I still run Windows 98? Anyone has a clue?


join 2 points

Gurpreet -- 2005/05/31

I'm using tk to allow a user to join two points using a line created by moving the mouse. After drawing the line, however, unless the user clicks the mouse somewhere in the canvas, the line is not fixed to the point it was made. It floats to another point marked on the canvas if th emouse happens to hover over it. I have used bind to allow me to create lines with a starting point inside specified points, but cant seem to bind them to lock in place at the specified end point. Help, pls!

MG See A minimal doodler explained for some help on how to do it. But you can either bind to ButtonPress and ButtonRelease (to start and stop the line, respectively, with a Motion that configures the line to follow the mouse), or you can bind to ButtonPress so that it records the coordinates of the click, then changes the ButtonPress binding so that the next one just draws the line from the coordinates you recorded to the coordinates of the second click. Hopefully that makes some sense ;)


many menubuttons

DK -- 2005/05/24

I'm trying to create a large number of menubuttons using loops, and I'm having trouble using -command {} with the dynamic variables. Shortened example:

  for {set i 0} {$i < [llength $i_count]} {incr i} {
    # length of i_count = 3
    # some code
    # problem code:
    for {set m 0} {$m < [llength $m_count]} {incr m} {
      # lenght of m_count = 4
      set a [menubutton $sf1.b${i}${m} -text "choose one" -menu $sf1.b${i}${m}.menu]
      set foo [menu $sf1.b${i}${m}.menu]
      $sf1.b${i}${m}.menu add command -label "1" -command {set A_GLOBAL_ARRAY(atomchoice,${i},${m}) 1} 
      $sf1.b${i}${m}.menu add command -label "2" -command {set A_GLOBAL_ARRAY(atomchoice,${i},${m}) 2} 
      $sf1.b${i}${m}.menu add command -label "3" -command {set A_GLOBAL_ARRAY(atomchoice,${i},${m}) 3} 
      $sf1.b${i}${m}.menu add command -label "4" -command {set A_GLOBAL_ARRAY(atomchoice,${i},${m}) 4} 
      $sf1.b${i}${m}.menu add command -label "5" -command {set A_GLOBAL_ARRAY(atomchoice,${i},${m}) 5} 
      $sf1.b${i}${m}.menu add command -label "6" -command {set A_GLOBAL_ARRAY(atomchoice,${i},${m}) 6}
      grid $a
    }
  }

The error I'm seeing is a 'no such variable' on ${m}, and I think it is because it's a dynamic variable that is called in a -command {}. Is there a way to use such an assignment? - RS: The -commands are executed in global scope, so the uplevel in the first is not necessary. Also, you have redundant braces around variable names - not needed if a non-varname character follows. But most of all, braces around the -command scripts prevent variable substitution at definition time. Try

      $sf1.b$i$m.menu add command -label "1" -command "set A_GLOBAL_ARRAY(atomchoice,$i,$m) 1" 
      $sf1.b$i$m.menu add command -label "2" -command "set A_GLOBAL_ARRAY(atomchoice,$i,$m) 2" 
      $sf1.b$i$m.menu add command -label "3" -command "set A_GLOBAL_ARRAY(atomchoice,$i,$m) 3" 
      $sf1.b$i$m.menu add command -label "4" -command "set A_GLOBAL_ARRAY(atomchoice,$i,$m) 4" 
      $sf1.b$i$m.menu add command -label "5" -command "set A_GLOBAL_ARRAY(atomchoice,$i,$m) 5" 
      $sf1.b$i$m.menu add command -label "6" -command "set A_GLOBAL_ARRAY(atomchoice,$i,$m) 6"

DK: a great many thanks for your help -- the substituting " for { and } solved my problem (i left the uplevel in the above on accident; i was just playing with the code trying to figure it out)


IWidgets::scrolledtext

MK I am using IWidgets::scrolledtext. I want to bind "MouseWheel" sequence to this widget. All other bindings seem to work except this. I am trying the following code: set scrolltext iwidgets::scrolledtext .a bind $scrolltext component text <MouseWheel> {puts "called"}

I have tried this binding to various children of scrolledtext. But none works. Please tell me the correct way to do so.

KJN There is some discussion of problems with binding to MouseWheel at Text Widget Bug.


bugs in tcllib smtpd's gmtoffset

FEB on 2005-05-17: I'm new to Tcl. I believe I've found a couple of bugs in tcllib smtpd's gmtoffset function. A tclsh session follows. (I added the unindented debugging lines to the function.) gmtoffset should always return -0500 for CDT, my local time zone. The result of the first call is +0500 and the result of the second call is -1900. In other words, as far as I can tell, the function will return either +0500 or -1900 for CDT, neither of which is correct.

     C:\>tclsh
     % proc gmtoffset-test {} {
             puts [gmtoffset 1116355370] ;# A little after 2005-05-17T1340, 1:40 p.m., CDT, my local time zone
             puts [gmtoffset 1116389544] ;# A little after 2005-05-17T2300, 11:00 p.m., CDT, my local time zone
     }
     %
     % proc gmtoffset {time_} {
         set now [clock seconds]
     set now $time_
         set lh [string trimleft [clock format $now -format "%H" -gmt false] 0]
     puts "lh = $lh"
         set zh [string trimleft [clock format $now -format "%H" -gmt true] 0]
     puts "zh = $zh"
         if {$lh == "" || $zh == ""} {
             set off 0
         } else {
             set off [expr {$zh - $lh}]
         }
         if {$off > 0} {
             set off [format "+%02d00" $off]
         } else {
             set off [format "-%02d00" [expr {abs($off)}]]
         }
         return $off
     }
     % gmtoffset-test
     lh = 13
     zh = 18
     +0500
     lh = 23
     zh = 4
     -1900
     %

Lars H, 19 May 2005: If you think you've found a bug in some tcllib module, then you should report it. The tcllib bug database is at [L10 ].


date arithmetic

FEB: I also have a question about Tcl. Are date arithmetic functions available for Tcl?

Peter Newman 18 May 2005: Search for date on this Wiki and you'll get a whole load of stuff. Then there's the nstcl nstcl-time module.


scrolledframe

MK I am making a scrolledframe. Inside this I am adding items row by row. Each row will contains a label , then three checkbuttons. Every time I add a row , I make these widgets and pack them. Now suppose I need to add 2000 or more of such rows at one go. My display then hangs. I am not able to create so many widgets and pack them . Is there any way to do this efficiently ?? Can I find any package which allow me to add rows containg a label and checkbuttons efficiently ???

Peter Newman Yes, I've experienced that with scrolledframe and similar widgets. But I think with text, canvas or tablelist, for example, you should be OK. But 2000 rows? Hmmm... My gut feeling is that canvas would be your best shot.

Chris L - Would it be appropriate to fake the scrolling? By that I mean that you could have a small number of real rows (maybe even just 1) displaying a sub-set of the full set, and moving the scrollbar would change the starting offset. Obviously you've got slightly more work to do when responding to button presses, taking into account the current starting offset, and moving the scrollbar will have to apply the correct state/data to the visible widgets, but it might be a better solution than scrolling around a canvas whose area is measured in acres!

Peter Newman 18 May 2005: Chris L, your idea sounds a bit like jcw's Virtual grid widget.

Chris L - Along the same lines, yes, but Virtual grid widget (which I'm glad you've brought to my attention!) appears to be a lot smarter about scroll-induced upates.


SQLite vs Metakit

LES on May 03 2005: I am having a hard time trying to find information on comparison/benchmarking between SQLite and Metakit. Can anyone point me to a good source?

BTW: Maybe it's about time to start an "Ask, and it shall be given # 3" page...


LES on May 02 2005

 $ set foo {Quoting "one" or "two words" is {tough}.}
 $ set foo
 Quoting "one" or "two words" is {tough}.

Great. However...

 $ proc p> {args} {puts "<p>$args</p>"}
 $ p> Quoting "one" or "two words" is {tough}
 <p>Quoting one or {two words} is tough</p>

 $ p> Quoting "one" or "two words" is {tough}.
 extra characters after close-brace

Ouch! Using the proc, one is not quoted, tough is not braced and the quotes became braces in two words. And if the phrase ends in a period, it generates an error. Why does it only happen when attempted with a proc and how can I clean ALL that mess?

RS: Arguments to a command are early parsed as a list. That will remove grouping markup, i.e. quotes and braces around grouped words. The quotesw around "one" disappear as they're redundant in Tcl syntax. "two words" are grouped, but at Tcl's discretion with braces, not quotes. And in this syntax, the period after the close-brace is considered an error. If you don't want the parsing to occur, add another layer of braces around strings you don't want to be parsed further:

 % p> {Quoting "one" or "two words" is {tough}.}
 <p>{Quoting "one" or "two words" is {tough}.}</p>

LES But that does not produce the desired effect. Those braces should not be there. I suppose you left that as an exercise for me? OK, this proc seems to work:

 proc p> {args} {puts <p>[lindex $args 0]</p>}

GWM I suggest using JOIN as it uses less arguments.

 proc p> {args} {puts <p>[join $args]</p>}

What I want to do hwoever is construct a set of arguments for a button and use the list:

 pack [button .btn -text fred -command "puts {Dont do that}"]

creates a button which works.

 destroy .btn
 lappend args -text fred -command "puts {Dont do that}"
  button .btn $args 

returns: unknown option "-text fred -command {puts {Dont do that}}". I have tried some 'clever' tricks such as:

 button .btn [eval concat $args]
 button .btn [join $args]

but no joy.

How do I use the args which I have built up other than to get RSI from:

  button .btn [lindex $args 0] [lindex $args 1] [lindex $args 2] [lindex $args 3] 

Thanks! Any suggestion of a wikit page where this topic should be moved to? Shall we try Argument to a Command?


background processes

Stephen Tjemkes: 2005-04-29 Hi can somebody help me with background processes? I want to spawn off a limited number (say 30) of parallel background processes within the expect modules but do not understand how this can work. I've seen a brief description in the expect book using fork but this allowed me to fork off only one process. At least i didnot see that there were more than one. Is there somebody who can share his experience on this

Thanks Stephen


Iwidgets::combobox

MK I have made a Iwidgets::combobox. In order to test it , I am creating it through a *.do file in my application.On creating it the mouse is grabbed to this combobox. I want to select different entry from the list of combobox. How can I perform this behaviour of mouse from a *.do file ??


console for UNIX

Derek Peschel 2005-04-23 I'm new to Tcl and Tk and the console for UNIX script is still not clear to me. I have Mac OS X. I've tested the console under X a little with A minimal editor, but I want to use the console as a part of TkOutline [L11 ] under Aqua. Note my terms "loader script" (what's on console for UNIX) and "library script". Also see my comments on the console page.

If someone can answer these questions about the loader, I'll be ready to send in some changes from TkOutline:

  1. Are the two blocks that call tk::unsupported::ExposePrivateCommand in the most logical place? Obviously they have to come after $consoleInterp is created. But a binding that uses tkConsoleExit comes before the code that makes tkConsoleExit available.
  2. Should the "work around bug in first draft..." block logically go closer to the reading of the library file?

Incidentally, I would promote the "work around bug..." comment to the outer level (whole line with frame around it).

Other harder questions:

After loading console.tcl, the window opens but no prompt appears. I don't know if the library script has to be fixed or if the loader script can contain the fix. I tried putting in a call to ConsolePrompt but got errors because of the redefined puts.

Brian Theado - I see in tkoutline on windows that the console comes up without the prompt. If you hit enter, then a prompt is displayed. It's possible this is a tkoutline problem

TkOutline has a Help menu. Creating a second Help menu (in the library script) doesn't make the newly-added commands appear, but it does make the original ones disappear -- the menu appears as a blank box. This is undoubtedly Macintosh-specific. The Mac interface puts the menu bar outside of all windows. The OS also may treat any menu called Help specially.

Posting a snippet of your code would be useful in helping figure this out

And can someone explain the relationship between the interpreters, the relationship between the two main windows, etc.? I want to be able to affect TkOutline's widgets from the console but I also want to be able to affect the console window from itself. But . in the console window still refers to the TkOutline window. Later I may want to affect the console (window and interpreter) from TkOutline.

Will add a description of my understanding to console


regexp *

MK 1. When I am using the command "regexp" and supppose my pattern is "*". This gives a Tcl error . I am not able to catch this error using the catch command. How can I do this ?

2. Where can I find the new features added for tcl commands (for example in case of list commands many new options have been added) for new versions ??

LV 1. Here's what I see:

 $ tclsh
 % catch { regexp {*} abc a b c}
 1

Seems like I can catch it. Can you show us specifically what you believe is a failure to catch? P.S. See regexp for an explanation of why your pattern is wrong. P.P.S. be certain to actually check the results of the catch, because ignoring the error is just begging for trouble.

MK Its working .. Thanks.

GV Don't you want:

% regexp {.*} abc a b c

. means any single character, * means 0+ occurrences (of . in this case)

2. New features to Tcl commands are supposedly only added after proposal, discussion, and approval of an appropriate TIP. If you check out Changes in Tcl/Tk, there are attempts to summarize the changes there. There are also short notes in the ChangeLog files that are a part of the source distribution.


Simple Launch Pad

HJH May 18, 2005; I posted two questions on the page Simple Launch Pad. This are really beginners questions and I would be please if somebody could spend 5 minutes on it.

Some hours later .... Thank you! The answer is fine.


CPU utilization

i need to find system CPU utilization from tcl/tk. if system CPU utilization is low means,i should display a warning message. please help me to find this.

DKF: On Linux:

  set f [open /proc/loadavg]
  set loadinfo [split [gets $f]]
  close $f

parent/child

EK: 2005-05-25 Hi, I have been getting the error

parent: sync byte read: bad file number child: sync byte write: bad file number

after 1015 loops on the code below:

  set counter 1
  while {1} {
    echo $counter
    spawn ftp -n
    close
    wait
    incr counter
  }

I read on the Expect FAQ that it is due to calling 'spawn' in a loop and neglecting to call close and wait. I have done both of that in the above code, so what can the problem be? Thanks in advance for your help...

EK: I found out what's the problem. I'm using Tclx and Expect together, thus the 'wait' command is actually a Tclx command instead of the Expect command. To use Expect commands, prepend them with 'exp_'.


install tkZinc3.3.0 on winXP

Does anyone know how to install tkZinc3.3.0 on winXP?? I already have tcl/tk8.4.9 but am still basically lost on installing tkZinc on my desktop. I'm very new to tcl/tk though. Hope anyone can help me. Thank ye all.

AB balbuena (25.5.2005)

MG I've never used it, personally, but it looks like if you download the "Starkit for Windows/Linux" from the downloads page on the TkZinc website [L12 ], then "source $fileYouDownloaded" in your code, that should work.


BLT for Mac

I used to use BLT in the last century, and was happy to see it was available in the Batteries Included 8.4 distribution for Mac OS-X 10.3.9 However, there's some disconnect when I try to actually use it in the wish shell:

 (() 1 % package require BLT
 3.0
 () 2 % blt::graph .g -title "xxx"
 invalid command name "blt::graph"
 () 3 % 

I've tried to make sense of the problem using info commands, etc. but no luck.

Apologies in advance if this is common knowledge, because I've never used a Wiki before...

RBN (11.6.2005)

TR (2005-09-19) - The BI distribution of Tcl for MacOS X does not include the complete BLT. Although it may seen so, the pkgIndex.tcl file tells us, that only BLTlite is loaded (this version 3.0 was never officially released yet by the author of BLT) which has some commands of the complete BLT but not any from the graphing engine.

But there is a way out. If you can content yourself with using X11 on the Mac, try the port by Fink [L13 ]. It has BLT for MacOS X in the current version 2.4z which runs fine with the X11 version of wish provided by Fink (that's version 8.4.1 and 8.4.7). Be aware, that this BLT will not run with the BI wish ...


iwidgets::scrolledhtml

aviad I'm trying to use iwidgets::scrolledhtml in my aplication for viewing html documents, the problem is when i try following links my links are totaly internal in th document but yet I get exception when I click on the link. How to solve this?

package require Iwidgets 4.0 option add *textBackground white iwidgets::scrolledhtml .sh -linkcommand ".sh import -link" pack .sh -fill both -expand yes puts .sh configure .sh import lindex $argv 0


TCL / VB6

There was an written TCL procedure. Now I want to run that existing TCL procedure from VB6 and display the result of that TCL procedure in VB6. How can i do this.Please Guide me.

Thankyou.

EKB It depends on the kind of output from the Tcl procedure. Is it plain text? If it is (and maybe even if it isn't), you can run the Tcl or Tcl/Tk program (tclsh or wish) as an external process. The VB6 API function to call is called CreateProcess.

If you want to run, then wait for the output from tclsh (especially if it's plain text), also call WaitForSingleObject to make sure tclsh is done running. See the following URL for more info on the VB6 code:

 http://vbnet.mvps.org/index.html?code/faq/

toplevel

I'm trying to write a Tcl/Tk app that places my toplevel window on the display and then does not allow the user to resize or move the window. I've managed the fixed size part, but does anyone know how to "lock" a window in place?

EKB The wm overrideredirect will prevent the user from moving the window (there's no frame for the window for them to grab, for example). (But are you sure you don't want the user to have that control?)

Thank you, EKB. That should work. Perhaps a little more background on my situation is in order. I have a system that is polling a server via socket twice a second and showing results on one of four displays attached to the client PC. Each display is assigned a Tk form and should constantly show that form and only that form for ever (or as long as Windows will let it run). I will probably have to add another label to the top of each form to simulate the title bar, but that's fine with me. Your help is most appreciated.

EKB - Makes sense. And you're welcome!


exit status

I'm trying to access the exit status variable in the separate TCL script file. Here bgexec is not supported so i want to know how to get exit status variable using exec command.

EKB Take a look at exec and error information.


Euro symbol

ctasada I'm working in a project that needs to work with the Euro symbol (EUR). Tcl seems to handle that correctly in cp1252, but working in utf-8 I cannot type the euro symbol in any entry widget, not even in a wish console

  (bin) 5 % encoding system cp1252
  (bin) 6 % EUR
  invalid command name "EUR"
  (bin) 7 % encoding system utf-8
  (bin) 8 % ?

Any help is welcome. Thank you very much in advance.

WJP You should be able to enter it using a \u escape. Try \u20AC.

BR 2005-10-01: Tcl/Tk only uses one representation (Unicode) internally. It converts to that encoding on input and from that encoding on output to whatever it thinks that the outside world wants.

So "working in utf-8": You always "work" in Unicode inside Tcl.

"% encoding system cp1252": You have proven that everything works if Tcl treats the outside world (input and output) as CP1252.

"% encoding system utf-8": You tell Tcl that the world has changed to UTF-8. That's not true, so communication doesn't work anymore.


LJF 20october

I am only learning TCL, to understand some drivers on our M&C, who uses TCL to implement the comunication to the hardware, mostly modems and satelite equipments. My knowledge is basic, I am asking if anyone nows how to "create" a channel to an ethernet card to send a ping to another one in the network. I have read on a manual that a channel could be created to a file, a pipe or a device. Does this device could mean ports or eth cards? How to do that? tcl manuals are poor on sutch area tks luismy mail addres is [email protected]

EKB I think you're looking for the socket command. From the man page:

"This command opens a network socket and returns a channel identifier that may be used in future invocations of commands like read, puts and flush. At present only the TCP network protocol is supported; future releases may include support for additional protocols. The socket command may be used to open either the client or server side of a connection, depending on whether the -server switch is specified."


sockets

DIRLIK Thibaut Hello (this my first post in this fabulous wiki), i'm a french TCL Coder and i'd don't understand how I can use sockets in a Tclet (Using Tcl plugin) ! I'd like to make a IRC TCL Applet (in order to tchat from the web) ! Can you help me please ?


TML / puts

Ruffy How come my TML's simple code:

Doc_Dynamic puts "The time now is: [clock format [clock seconds]"

...shows up as: puts "The time now is: Tue Nov 29 12:09:31 PM Eastern Standard Time 2005"

...Why is the tcl command "puts" ignored?

Grateful.

aa - TclHttpd's template support doesn't [source] the .tml files as scripts, so you can't expect them to work that way. The content of a .tml file is essentially run through [subst]. Even if you enclosed the [puts] in brackets to get it to be evaluated as a command, you'd end up with its output appearing on the TclHttpd console instead of the page. If you need full scripting with stdout going to the page, you should use TclHttpd's Direct_Url support instead of templates.


SSH

SJK 11 December 2005

I've just started using ActiveTcl 8.4.11.2. I have written an Expect script to automate an SSH session and this works successfully on XP Pro when run with tclsh. However, when I run it on Windows Server 2003 then the first expect command after the exp_spawn exits with eof. The command used in the exp_spawn works fine when entered at the command line. Can anyone help?

Thanks.

SJK 12 December 2005

Oops, sorry to have bothered you - solution is just to disable Data Execution Prevention for tclsh.exe via Control Panel->System->(Advanced Tab)Performance Settings.


vwait

Ken: I am wondering whether how to transfer control back to a procedure using 'vwait' concept? Let say, I have a proc A below. It transfer control to another procedure B which is running a while loop executing all sorts of commands. But inside proc B , there are commands that require transfer back to the proc A. And after executing proc A, it continues where it lefts off in proc B? Is there a way using vwait command to implement this or is there other ways? Really need help! Thanks in advance

proc A {} {

  while {1} {
  #commands to execute
  call proc B
  #continue
   } 

}

proc B {} {

   while {1} {
      #process certain things
      #sleep
     #vwait (need to transfer control to b)
     #when call proc b from proc a resumes here
    #continuye to process things
   }

}

EKB Ken, what problem are you trying to solve? This looks like a complicated solution, and I'm wondering if the logic can be simplified.

Ken EKB, what do u mean by "logic can be simplified"? The problem i'm trying to solve is transfering of control from one procedure to the next. Like i have a main proc that calls proc a which inside has a vwait command to suspend operation until been activated and continue from where it left off and transfer control back to the main program which continue processing till it calls proc a again and runs where it was suspend previously.

EKB Ken, I actually meant, what's the larger problem you're trying to solve? (What does the program do?) At any rate, from my understanding of the code, it doesn't seem to matter that there's a vwait. Here is my understanding:

  A calls B
  B returns (after a vwait, but that's incidental - right?)
  A calls B again, but control starts where B last returned

Is that right?

Ken EKB, oh i get what you meant? The above code is what i wanted to express earlier. That's is the problem i trying to resolve. But the larger problem i was trying to solve was that i am suppose to create a Wireless sensor nodes simulator. I use the discrete events simulator concept to program my simulator. Thus for example my event queue contains node N1 which is suppose to be awake, and then execute a set of code but then goes to sleep so the simulator should just 'suspend' the node N1 and grap the next event which may be node N2 is to be processed and afte r it is processed grap node N1 which is suppose to be awake now, and then continue to process where it left off. I thought of using after and vwait to suspend the node N1 but i just don't know how to transfer the control back to the simulator to grap the next event. I did consider to use return but it may prove cumbersome as it would have to reexecute all the previous code which node 1 has already processed? Do you get what i meant? Thanks in advance

EKB Ken, I think the page Keep a GUI alive during a long calculation is about solving a similar problem. Looking at that page may help. (The basic idea is to schedule an event using after, and keep track of state using namespace variables.) But people more knowledgable than me might have other ideas...

EKB, Can you kindly state a simple algorithm cause i can't seem to link that site with the case i stated?

EKB Ken, what I have in mind is something like this (and if this isn't what you're looking for, then I apologize, but I'll need some further clarification - or maybe someone else has a better solution?):

 proc A {} {
    while {1} {
        #commands to execute

        events::B

        #more commands
    }
 }

 namespace eval events {
    variable state "start"

    proc B {} {
        variable state

        switch -exact -- $state {
            start {
                #process certain things
                set state "1"
                after ... ::A
            }
            1 {
                #process certain things
                set state "2"
                after ... ::A
            }
            2 {
                #process certain things
                set state "3"
                after ... ::A
            }
            # ...
            default {
                # This is an error
            }
        }
        #continue to process things
        return
    }
 }

Ken: EKB I really appreciate your effort in helping a newbie like me really thanks, but just to wonder what is the "after...::A" does it just rerun proc A again. Cause my idea was like using vwait or tkwait and then transfer control back to proc B and back to proc A, can it be done since vwait just suspend that till it is updated.

EKB Ken, I haven't forgotten about you. But I haven't had time to sit down and think this through yet.

Ken EKB, for the past few days, I been rethinking of the problem I think i am nearly there with this approach listed below. I probably nearly there with this approach. I manage to get the 2 procs to wait on each other. But the problem i don't understand, i am encountering is that once proc ::SuspendAndUnSuspendTest::ProcBSimulateAlgoProc has set UnSuspendFlagA before it suspends and wait for the variable UnSuspendFlagB to be set it suspends in proc ::SuspendAndUnSuspendTest::ProcBSimulateAlgoProc even though it sets variable UnSuspendFlagA which should gets ::::SuspendAndUnSuspendTest::ProcASimulateMainProc to contine running. Is it cause there must a return statement to get ::SuspendAndUnSuspendTest::ProcBSimulateAlgoProc to return control to ::SuspendAndUnSuspendTest::ProcASimulateMainProc before it can continue. If not how i can get it to move control back to ::SuspendAndUnSuspendTest::ProcASimulateMainProc before it continue to process ::SuspendAndUnSuspendTest::ProcBSimulateAlgoProc

Lars H: Well, you can't. A tkwait or vwait doesn't suspend a proc and gives control back to some global event loop, but starts a new event loop. Quoting the vwait page:

Multiple vwaits nest, they do not happen in parallel. The outermost vwait cannot complete until all others return.

It's slightly uncool that things are that way, but it's rather deeply built into the way that the Tcl library is written (calling Tcl commands translate into calling C functions, so the C stack grows rather than shrinks when you tkwait below).

EKB Lars, thanks for adding that comment. I was thinking that just using an "after" without a vwait or tkwait would be the way to go to simulate asynchronous message passing. Does that sound reasonable? I was also thinking that it seems like threads would be a solution, but I have mostly avoided the discussions on threads in Tcl, and am not up to date. Is it true that they're available in Tcl 8.5? And would that be a good alternative?

Ken Lars and EKB, thanks for all these advice, i can't proceed with the method i did previously but i thought of another way to solve the issue but stuck at the solution of referencing the right procedure. I have a main proc A that calls proc B with an argument like "nodeid " for that particular node. Thus if i had 2 nodes thus proc B would be running "asynchronously" while proc A would just be running by issuing the calls to see which proc B needs to be unsuspended for that moment. Thus Proc B 1 with node Id 1 and Proc B 2 with node id 2 would be suspended on the tkwait variable and proc A would call the proc B to continue base on its updates on tkwait variable. But i have a question as to whether how am i going to reference the right Proc B since Proc B procedure is generic and is called by different node ids?

EKB I think the main thing to remember is that you can't use tkwait or vwait to pass control back to another procedure. You can't use those to emulate asynchronous communication. What you're trying to emulate, if I understand correctly, is two processes running in parallel. You could either create parallel processes (either by spawning a whole new process or using threads) or you can emulate it by having a proc that does nothing for a while, passes control back to the calling proc, but schedules an interrupt for later (using after). So, briefly, I'd say, forget about tkwait or vwait, and see what else you might use.

{ namespace eval ::SuspendAndUnSuspendTest:: {

        namespace export -clear ProcASimulateMainProc, ProcBSimulateAlgoProc,ToggleUnSuspendProcA,Debugger,UnSuspendProcB
        variable ProcASuspendVar 0 ProcBSuspendVar 0 UnSuspendFlagB 0 UnSuspendFlagA 0

}

proc ::SuspendAndUnSuspendTest::CheckB {} {

        variable ProcBSuspendVar
        variable UnSuspendFlagB
        if {$UnSuspendFlagB} {
                puts "UnSuspendFlag is $UnSuspendFlagB and Proc is Run"
                set ProcBSuspendVar 1
        }
        puts "CheckB fail"
        #puts "UnSuspendFlag is $UnSuspendFlag in UnSuspendProcB"
        after 5000 [list ::SuspendAndUnSuspendTest::CheckB]

}

proc ::SuspendAndUnSuspendTest::ProcASimulateMainProc {} {

        variable ProcASuspendVar
        variable ProcBSuspendVar
        variable UnSuspendFlagA
        variable UnSuspendFlagBss
        puts "Execute Command 1"
        puts "Execute Command 2"
        puts "Execute Command 3"

## ::SuspendAndUnSuspendTest::Debugger

        #here need to unset to continue to Run Proc B
        #here need to unset to continue to Run Proc B
        #check whether UnSuspendFlagA for Proc A has been toggled to unsuspend the below function
        after 10000 { set ProcASuspendVar [::SuspendAndUnSuspendTest::CheckA]; puts "MainProc $ProcASuspendVar"}
        after 1000 [list ::SuspendAndUnSuspendTest::ProcBSimulateAlgoProc]
        #after 10000 { set UnSuspendFlagB 1 }
        tkwait variable ProcASuspendVar
        #tkwait variable ProcASuspendVar
        puts "Execute Command 4"
        puts "Execute Command 5"
        puts "Execute Command 6"
        set UnSuspendFlag 0

}

proc ::SuspendAndUnSuspendTest::Debugger {} {

        variable ProcBSuspendVar
        variable UnSuspendFlag
        variable ProcASuspendVar
        puts "ProcBSuspendVar is $ProcBSuspendVar"
        puts "ProcASuspendVar is $ProcASuspendVar"
        puts "UnSuspendFlag is $UnSuspendFlag"
        after 5000 [list ::SuspendAndUnSuspendTest::Debugger]

}

proc ::SuspendAndUnSuspendTest::CheckA {} {

        variable UnSuspendFlagA 
        variable ProcASuspendVar
        if {$UnSuspendFlagA } {
                set ProcASuspendVar 1
                puts "Value of ProcASuspendVar in UnSuspendProcA is $UnSuspendFlagA"
        }
        after 1000 [list ::SuspendAndUnSuspendTest::CheckA]
        return $ProcASuspendVar
        return $ProcASuspendVar

}

proc ::SuspendAndUnSuspendTest::ProcBSimulateAlgoProc {} {

        variable UnSuspendFlagA
        puts "Execute Command - ProcB 1"
        puts "Execute Command - ProcB 2"
        puts "Execute Command - ProcB 3"
        puts "Suspend"
        set UnSuspendFlagA 1 
        after 1000 { set ProcBSuspendVar [::SuspendAndUnSuspendTest::CheckB] }
        tkwait variable ProcBSuspendVar 
        puts "Execute Command - ProcB 4"
        puts "Execute Command - ProcB 5"
        puts "Execute Command - ProcB 6"
        puts "Execute Command - ProcB 6"

}

 ::SuspendAndUnSuspendTest::ProcASimulateMainProc 

}


string is digit

huck. According to the man page, string is digit string will return 1 if string is composed of "Any Unicode digit character." Then it goes on to say that "this includes characters outside of the [0-9] range." What other characters, aside from [0-9], are members of the digit character class? Thanks!

(Answer moved to string is)


extracting elements from list

ken: I am wondering is there any efficient and fast way of extracting a fixed number of elements from a list variable instead of using the normal of using lsearch and then lrange and lreplace?

ken: Is there any way to edit the flow of events that are about to execute in the after info results. For example, i would like to edit the event lists in the results obtained from after info like delay the execution fo the events or resume the continuation of some events?

MG March 25 2006 - I believe the only way is to cancel the event with [after cancel], and then either run it immediately or use another after call to have it execute later at a different time.

ken: I have a problem with after cancel cause i have an event that reschedules itself periodically but even i use an after cancel, and when i check the event loop again it stills there. Is there a way to cancel all this event?


array to list

ken: Just a question, is there any efficient way to transfer information from a array set variables to a list besides using a foreach loop and [array names (array variable name)]?

Sarnold: It seems like you need array get, like this:

 % set myarray(0) a
 % set myarray(1) b
 % puts [array get myarray]
 0 a 1 b

Tk canvas 'closest'

Ken: How do i use the options for 'closest' in the Tk canvas widget?

Ken: Just a question again? how come when i set an array set variable using this notation below . I can't seem to be able to add a varible in place of a value, it always prompt me an error?

 set FullStrength 100
 array set myarray { Power $FullStrength D1 $FullStrength }

NEM: Because braces prevent substitution, as explained in the main Tcl manual page [L14 ]. You want to use either double quotes:

 array set myarray "Power $FullStrength D1 $FullStrength"

or else construct a list:

 array set myarray [list Power $FullStrength D1 $FullStrength]

Query objects on canvas

Ken: I have another query. I have an object in a canvas. And everytime i need to click on the object to access its information.
Is there a way of letting the canvas know that i am going to click on the object, so that it shows the information whenever i am near it ?
Earlier i read up on the tag 'closest' can it be used?

MiHa Maybe have a look at Enter and Leave Event Bindings .