| Frequently Asked Questions |
---|
|
General
Tcl/Tk resources
Tcl/Tk extensions with vtcl
Vtcl questions
Tcl/Tk questions
What is Vtcl?
Visual Tcl is a freely-available, high-quality application
development environment for UNIX, Windows, Macintosh and AS400 platforms,
says Stewart Allen, its developer.
With vTcl you can design not only the graphical view of your application,
using visual tools and "What You See Is What You Get", but also write and
test the Tcl procedures and TK events bindings that drive it.
You even have a "Test" button hat runs your application from within vTcl. When you
are satisfied, you just save your work and it is ready to run.
The saved work contains no vTcl specific code, and if you find the need to edit it
outside vTcl, you can do it and yet read it gain in vTcl.
If you have already a running application using pure Tcl/Tk code you
can read it from within vTcl and continue developing it.
What do I need to run vTcl? What OS are supported?
You need Tcl/Tk installed. Tcl/Tk is available
for most UNI*X, and for Windows and Mac also.
How can I reorganize the order of appearance of already
created widgets, or specify the place where a new widget s
to be inserted? I am using the packer.
Say that you have a frame with four buttons, A, B,
C, D, packed in that order, and want to change the packing order to A,D,B,C.
-
You should have the "widget tree" window opened. Press the reload button
before start.
-
Press the right mouse button on widget B, and choose "Hide". The button
should disappear.
-
Repeat the procedure for button C
- On the "widget tree" window, click on the button corresponding to widget
B. It should appear now after widget D.
- Repeat for widget D.
- You should now have the widgets in the order A,D,B,C
The new order will be the order of the reappearance, so if you exchange
points 2 and 3 above, you will end up with the buttons in the order A,D,C,B
This also applies to the insertion place order of new widgets. Hide
all widgets after the one where you want to insert the new one, create
it, and then click on the "widget tree" to unhide the previously hidden
ones.
A much simpler approach, contributed by Grzegorz Popiela <gpopiela@fortech.krakow.pl>
is as follow:
- Select widget D
- Press the Up arrow twice
- You should now have the widgets in the order A,D,B,C
The Down arrow of course moves the widget down, and the Left and
Right arrows sideways, if they are packed side by side.
This above applies also to menu entries.
How can I rapidly assign a scrollable widget with a
scrollbar?
Right click on the scrollbar. From the menu select "Widget". Next select "Attach to Widget". Then select the widget you wish to attach the scrollbar to.
Can I use vtcl with tix or blt or itcl?
Yes. Support for them is already built-in in vtcl.
At startup, vtcl tries to identify the tk interpreter that is driving it.
If it is tix, vtcl will add some tix specific widgets to the widget window;
the same for blt and itcl. The only think that you need to do is setting
the PATH_TO_WISH variable in vtcl main script, usually found at /usr/local/bin/vtcl,
e.g.,
----------------- vtcl -----------------------
#!/bin/sh
PATH_TO_WISH=/usr/local/bin/wish8.0
#PATH_TO_WISH=/usr/local/bin/tixwish
or whatever name
#PATH_TO_WISH=/usr/local/bin/bltwish
or whatever name
...
-------------------- end of vtcl --------------
Grzegorz Popiela is working on a patch to vtcl to enable it working
with iwidgets 3.0.
I have the tixwish interpreter and have tried setting
the PATH_TO_WISH variable in the vtcl script (as above), but I've
run into problems. Vtcl seems to find the megawidgets well enough and
adds them to
the widget toolbar . Unfortunately, although the environment
inserts a notebook widget (for example), I can't resize it graphically
or delete it.
I think you will find that the notebook has already
been placed in a frame of some sort. To move/resize the notebook, first
select the notebook by clicking on it's icon in the widget tree window.
This will put the 8 move/resize blocks on the enclosing frame. Then
use the middle mouse button to move the whole note book and the left button
to resize by click/drag on the 8 blocks, Peter Onion <ponion@srd.bt.co.uk>
says.
OK, but then I only can use one of them. And what if
I want to use widgets from two of them?
You have to build (dream) your own wish. For an example,
search for the file tkAppInit.c in the source distribution of tix, blt
or itcl and create your own wish. That's very simple if they are compatible...
[Please confirm this one, I have not tried it]
FAQ co-maintainer by appointment, Grzegorz Popiela :-), says:
You can use another script file instead of vtcl, lets call it `dream'.
Create it according to the following recipe and make it executable:
---------------- start of dream ------------------------
#!/bin/sh
# the next line restarts using wish
\
exec wish "$0" "$@"
package require Iwidgets
package require Tix
package require BLT
# etc...
source ${VTCL_HOME}/vt.tcl
# where VTCL_HOME should be defined
as in the standard `vtcl' file
----------------- end of dream -----------------------
Of course these extensions have to be compiled as loadable libraries
(they usually are).
No, no, I want support for xxx.
Write it and submit your changes. Start by looking
in the vtcl source distribution for lib_blt.tcl lib_core.tcl lib_itcl.tcl
and lib_tix.tcl.
OK, you convinced me, how can I add support for new
widgets?
Start looking in lib_blt.tcl lib_core.tcl lib_itcl.tcl
and lib_tix.tcl.
What is the purpose of the menu entry "Set Insert"?
If you choose "Set Insert" from the menu, next widget
you insert will be a sibling of the currently selected widget. Perhaps
you've noticed that if you select a button or label, inserting point is
parent of the widget (usually a frame or toplevel). "Set Insert" entry
overrides this, e.g. if you want to put a button on top of another button.
Probably this is the only use, Grzegorz Popiela <gpopiela@fortech.krakow.pl>
says.
[ I find this of dubious utility... Any other use? ]
How can I create compound objects? I appreciate the
system compound "Label and Entry" and I would like to add my own ones.
Grzegorz Popiela <gpopiela@fortech.krakow.pl>
again advises:
Just select a frame with some widgets in it and choose Compound->Create.
You will be asked for the compound name. Lets call it "myCompound". To
reuse that compound widget again, just select the place where you want
to insert it, and choose menu->Compound->Insert->user->myCompound.
If you want to use "myCompound" in other projects, just choose Menu->Compound->Save
Compounds, and specify a file name. Later, on other projects, just choose
Menu->Compound->Load Compounds. Voila, code reusability!
Additionally, there are functions associated with compound widgets:
If procedure "myCompound:init" is defined before the compound is created,
the next time you insert it the procedure will be executed before the compound
widget is created. You may e.g. create images there.
If procedure "myCompound:main" was defined, it will be executed after
the widgets are created. It may be used to insert some data into newly
created widgets of compound, or set up links between them.
Other procedures (myCompound:*) will also become a part of the compound.
[ Is there a standard interface to them, as with "main" and "init" ?
]
Is there a work around for this error? I am using the
placer geometry
manager:
Error in startup script: can't use placer on top-level
window "."; use wm command instead
Greg Anderson <Nifft@FutureRealms.com> says:
When you get this error, replace the sections "CREATING WIDGETS" and
"SETTING GEOMETRY" in the proc vTclWindow with the template below, and
the error will disappear.
-
Delete the "place command" from the "SETTING GEOMETRY" section.
-
Add wm code to the "CREATING WIDGETS" section to create and then hide the
top window. Keep a template file, like the one below, to copy into
the "CREATING WIDGETS" section.
The vTclWindow proc creates and then hides the main window,
so I don't think the definitions for geometry, maxsize, minsize, etc. are
that important.
When the error occurs, you will notice that in the proc vTclWindow,
the "CREATING WIDGETS" section is missing the wm code and the "SETTING
GEOMETRY" section has a "place" command in it.
Here's a template you can use to quickly fix this error:
proc vTclWindow. {base} {
if {$base == ""}
{
set base .
}
###################
# CREATING WIDGETS
###################
wm focusmodel $base
passive
wm geometry $base
1x1+0+0
wm maxsize $base
1265 994
wm minsize $base
1 1
wm overrideredirect
$base 0
wm resizable $base
1 1
wm withdraw $base
wm title $base
"Whatever"
###################
# SETTING GEOMETRY
###################
}
Why, after finishing my application and running it on
another Xserver, all fonts are wrong, destroying my carefully designed
layout?
A possible answer: If you specify fonts only partially,
such as Helvetica-*-12-*-*..., the Xserver picks the first one that fits.
Another Xserver may have a different set of fonts, and the one that first
fits the specification is different, with unpredictable results.
On the other side, if you specify a font completely, and the Xserver
can't find it, Tk may die, or the nearest font matched is really very different
than the one that you intend.
Another frequent error is to specify fonts with pixel size, not point
size, and of course if you change from a 70 dpi to a 100 dpi monitor, than
your application will be shrinked.
Another frequent error is related with an improper setup of the font
path for the Xserver (run `xset q'). If you specify your font with an "*"
in the x or y dpi sizes, again the Xserver will pick the first one it found.
If you are using a 100dpi monitor, but the font path for the xserver list
first the directories of the 75dpi fonts, you are in trouble.
With tk, fonts can, and should be, specified in a different way: use
"Helvetica 12" to specify a 12 points helvetica font, and "Helvetica -
12" to specify 12 pixel--discouraged (run `man font n')
Can I use the placer only with relative positions? I
find annoying not to be able to resize my windows and keep the geometry.
[ Who knows? Is this a contest? :)]
How could I build a scrollable window like the attribute
editor of Vtvl ? (I can't move widgets as buttons or labels with scrollbars)
I took the following approach using the packer:
-
a frame
-
a checkbutton inside and on top of it ("-side top -fill x")
-
another frame bellow ("-fill x -side bottom")
-
all other widgets inside that second frame.
-
bind the following procedure to the checkbutton ("-command shrink_expand"):
proc {shrink_expand} {} {
set but_path [winfo containing [winfo pointerx .] [winfo pointery .]]
set parent_name [winfo parent $but_path]
set children_name [winfo children $parent_name]
if {[lsearch $children_name $but_path] == "0" } {
set fra [lindex $children_name 1]} else { set fra [lindex $children_name
0]}
upvar [$but_path cget -variable] var
if { $var } {
pack forget $fra} else {
pack $fra -fill x}
}
I am wanting to know how to have a place to put functions
that I might want to include in several apps. but I do not know what to
do in tcl and then how to do it as well in vtcl?
Rick Macdonald <rickm@vsl.com> has a solution:
you should create a Tcl library with your functions (see a Tcl FAQ), then
run the "auto_mkindex" command and then add your library directory to the
auto_path:
lappend
auto_path /usr/local/lib/MyTcl
where /usr/local/lib/MyTcl is
the directory where your Tcl library is.
The problem is that when you load the application into vTcl, it will
save these functions into the application, and you don't want that. To
avoid it, just add
append vTcl(proc,ignore)
"|mylib_*"
This assumes that all the procs that you source in start with the string
"mylib_". You could add the above line at the bottom of your "init" function.
However, each time that vTcl runs your init function the vTcl(proc,ignore)
value will get longer and longer.
Mitchell Roe <mroe@mail.arc.nasa.gov>, for example, adds the following
lines at the bottom of it's init function, and although vTcl(proc,ignore)
really grows it causes no problems to him:
global vTcl
set id [open [file join $mylib tclIndex] r]
foreach line [split [read $id] \n] {
if {[regexp {set auto_index\(([^)]*)} $line match proc]} {
append vTcl(proc,ignore) "|$proc"
}
}
close id
Alternatively, you could add the following line into the vTcl "globals.tcl"
source file. The vTcl default is to ignore procedures matching "tcl.*|tk.*|auto_.*|bgerror|\\..*":
set
vTcl(proc,ignore) "tcl.*|tk.*|auto_.*|bgerror|\\..*"
The simplest solution however will be to always call your functions
starting with the string "tcl". Then you don't even have to modify the
vTcl ignore list.
How can I hide a frame and all widget on it? I would
like to have multiple frames in one window and hide or reveal them
(and all the objects in the frame) when a user presses a button.
Rick Macdonald <rickm@vsl.com> says: `pack forget
<frame>' to hide and `pack <frame>' to reveal (if using the packer
geometry manager). If it doesn't resize properly by itself try this before
and/or after the various pack commands until it does:
# Clear the
geometry settings so the window resizes
wm geometry
$widget(your_toplevel) ""
If the packing order is important, i.e., you are hidding/revealing several
frames, you may need
pack $frame -after $other_frame
Otherwise, it's tricky to make sure the frame gets repacked in the right
location.
With the grid geometry manager, use
grid conf ....
grid forget ...
Other possibility is to use the vTcl builtin procedure "Window":
Window hide $windowname
Window show $windowname
The advantage is that the "Window" proc will create the toplevel if
it doesn't exist or deiconify it if it does. You don't need to keep track
or worry about it.
How can I recursively disable all widgets inside a given
frame? I don't want to just hide it, as the window geometry changes.
Rick Macdonald <rickm@vsl.com> answers: Call the
following function with the containing frame and everything is greyed out,
disabled, etc. The only non-general thing I've done is that if a widget
(such as entry) has a
green background, I leave it disabled.
Actually, I think this is really cool. I'm using it more and more.
proc {toggleDisabled} {state wtop disabledfg}
{
if {[winfo class
$wtop] == "Frame"} {
set children [winfo children $wtop]
} {
set children $wtop
}
foreach w $children
{
if {[winfo class $w] == "Frame"} {
toggleDisabled $state $w $disabledfg
continue
}
if {[lsearch -exact "Entry Label Message" [winfo class $w]] >= 0}
{
if {$state == "disabled"} {
$w config -foreground $disabledfg
} {
$w config -foreground black
}
}
if {[lsearch -exact "Button Checkbutton Entry Radiobutton" [winfo
class $w]] >= 0} {
if {$state == "disabled"} {
$w config -state disabled
} {
if {[$w cget -background] != "green"} {
$w config -state normal
}
}
}
}
}
Get the disabled foreground from any handy button widget:
set disabledcolour
[$widget(auto_button) cget -disabledforeground]
"state" is disabled or normal, "wtop" is the containing frame.
Then disable and enable with these calls:
toggleDisabled disabled $widget(start_frame)
$disabledcolour
toggleDisabled normal
$widget(start_frame) $disabledcolour
I am really new to this Tcl/Tk stuff in order to use
vTcl properly. Where can I find a Tcl FAQ?
This one is really easy. The only problem is the
amount of information... Try
I want to put an image on a button. How can I do that
in vtcl?
In the "attribute editor" window there is a field
named "image" where you should type the name of the image to put on the
button. But you should create the image first. A good place is in the "init"
function. Open the "function window" and double click on the function named
"init"; then type in the function body:
image create photo nameoftheimage -file
/directoryoftheimage/yourimage.gif
To put it in a label or button, etc. just insert "yourimage" in the
image entry of the attribute editor, Guillaume Laisney <laisney@lepsi.in2p3.fr>
said.
I can't understand the basic working of vtcl. Is a working
demo available?
You should check vTcl WEB home page. There is an
Introduction
tcl-intro.html
and a Tutorial tutorial.html>there.
In the source distribution that you downloaded you will find also the tutorial
at <distribution_home>/doc/tutorial.txt>
[Of course an animated or interactive demo would be the best--and it
would
demonstrate also the WEB capabilities of Tcl. Any volunteers? Another
nice
demo would be one like the one found in the xf GUI designer]
And online free books on Tcl/Tk?
You can find an old free book for personal use,
Brent Welch's "Practical Programming in Tcl and Tk", which covers
tcl/tk version 7.4/4.0 at http://www.beedub.com/book/tkbook.ps.gz.
The book has been meanwhile published by Prentice Hall (1st edition: ISBN
0-13-182007-9, 2nd edition: ISBN 0-13-616830-2).
You can also find another old book by John Ousterhout's, "Tcl and
the Tk Toolkit", which has been meanwhile published by Addison-Wesley,
ISBN 0-201-63337-X. The free book only cover tcl/tk version 7.3/3.6.
I'd like to...
Sorry, no such entry on the FAQ. Please send the
query to the list, and I will collect the answers. You could help if, after
solving your problem, send me the solution.
Besides this "FAQ", is there a mailing list? Is it archived
somewhere?
The mailing list is currently archived at http://www.mail-archive.com/vtcl@neuron.com.
You can subscribe it at Tcl homepage. See next question.
Has vTcl a homepage? what is it's address? Where can
I find vTcl sources for download?
The vTcl homepage is at http://vtcl.sourceforge.net/.
You can find there all the relevant information such as download and install
information, Tcl/Tk links, etc.
Besides vTcl are other free Tcl/Tk GUI development environments?
Yes. The most known are:
What is the difference between vtcl functions main and
init?
The init() function is called before the creation
of your widgets, immediately after the script starts and the creation of
global variables. main() is called after the widgets creation.
Thus, when your script start, the order of execution is:
-
creation and setting of global variables
-
init() is called
-
the *visible* widgets are created (not the ones that are hidden)
-
main() is called
When you press the "Test" button the above sequence is also executed.
In vtcl where is the best place to put bindings? init?
main? or my own functions?
The best way is to do it with the Options/Bindings
(alt-b) menu option.
|