package require Tk
But the interpreter cannot find package Tk. Did I miss some initial
paths?
Where does the tclsh gets its packages?
Thanks for any help.
Edmund Lai
el...@iinet.net.au
Currently the standard distribution doesn't support this, but
the plus-patches do. See:
http://home.wxs.nl/~nijtmans/plus.html
A full binary distribution for Windows 95/98/NT is available at:
ftp://ftp.neosoft.com/pub/tcl/sorted/packages-8.0/devel/tcl811plus.exe
Most fixes needed to accomplish this are already contributed to
Scriptics, but didn't appear in the source yet. Hopefully soon.
Regards,
--
Jan Nijtmans, CMG Arnhem B.V.
email: Jan.Ni...@wxs.nl (private)
Jan.Ni...@cmg.nl (work)
url: http://home.wxs.nl/~nijtmans/
I need to explain a bit of background first. Jan has done
superb work for the plus-patches, and I hope more of his en-
hancements make their way into the Tcl core swiftly.
I'm catching on, though, that some users might find plus-patch
most conveniently usable in its TclKit manifestation, as Jean-
Claude Wippler has packaged it. TclKit plus-patches and a
shocking amount of other functionality in a single-file
executable. It's available at no charge for Win*, several
Unixes, and I believe more Unixes and MacOS are on the way.
The choice, then, is between the more conventional installation
design of plus-patches, and TclKit's single-file executable.
Both have a place. I think beginners, in particular, might
find the latter convenient.
--
Cameron Laird http://starbase.neosoft.com/~claird/home.html
cla...@NeoSoft.com +1 281 996 8546 FAX
Jan, I am curious about something. What patches are required in Tcl just
to find the Tk package - which is the problem the original poster
mentioned. I understand that the package might not _work_ with some
patches - I am more interested initially in what bugs remain in the
package require aspect of things.
--
<URL: mailto:lvi...@cas.org> Quote: Saving the world before bedtime.
<*> O- <URL: http://www.purl.org/NET/lvirden/>
Unless explicitly stated to the contrary, nothing in this posting
should be construed as representing my employer's opinions.
Compared to Tk8.1.1, 2 additional things are absolutely needed:
- Bug fix (2121), assuring that libtk is always built with
"-lX11". In 8.1.2 this will be fully corrected (finally :), if
I can beleave the current CVS code.
- Missing pkgIndex.tcl file for Tk, which is rather trivial.
Further on, three more things are needed to make the event handling
of tclsh81.exe+tk81.dll work identical to wish81.exe:
- Implementation of Tcl_MainLoop () (BugID 1525)
- Adaptation of Tk to use the above function (BugID 1540)
- Rewrite of the Tcl_Main() function, adding support for non-blocking
stdin/stdout channels. Not submitted to the Scriptics BUG database
yet because it requires the above two fixes first.
Let's hope that Scriptics takes a little time to evaluate at least
BugID's 1525 and 1540 soon (8.1.2 ?????), then I will submit the final
fixes to make Tk a fully compliant Tcl package to the Bug database.
Oops, The event fix for Tk is BugID 2074, not 1540!!!!!!
^^^^
Sorry, but as stated before, this flashes all my red
modularity-breaking-alert lights. It is none of Tcl's (nor tclsh's)
business to know that certain executables (wish) using certain
extensions (Tk) happen to branch to a [tkwait window .] after the EOF of
the script.
In other words, I do *not* want to sacrifice modularity so that
#! /bin/sh
#\
exec tclsh $0
package require Tk
works like
#! /bin/sh
#\
exec wish $0
Instead, I am ready to enforce and document the two following
alternatives:
1) Provide the small *script* "wish" that does basically
[package require Tk] and [tkwait window .], PLUS the
fileevent on stdin/console-widget to handle interactive use.
2) Just require the programmer to say [tkwait window .] at the
end of a script of the first form above, if he wants a
wishlike semantics.
-Alex
Isn't there a way to do this semi-automatically?
Supposed "package require Tk" invokes something like the following?
after idle {tkwait window .}
(in the Tk init, or in the pkgIndex.tcl file for Tk, even)
I know the above is not good enough, but it would mean we can simply
slap "package require Tk" at the front of a script, and voila... the
script enters an event loop at the end. Another difference I think, is
that "package require Tk" needs to source "~/.wishrc", since again Tcl
itself should not be bothered with its drivers "wishes", so to speak...
-- Jean-Claude
Yes, but just why ? There is absolutely no backward compatibility issue
here, since by definition no scripts exist that say [package require Tk]
(apart from those using Jan's patches of course).
To sum it up:
- I find wish's behavior (vwait at EOF) useful in its domain
- I find tclsh's behavior (exit at EOF) useful in its domain
- We all realize that wish can now be rewritten in terms of tclsh
- I do not want a [package require] to affect tclsh so that it
behaves like wish. This BTW doesn't scale up. What if a second
package wants to start its own loop at the end ? While clearly
they can perfectly coexist in peace (each with its own event
callbacks) if the vwait is done by the programmer !
- I even believe it will be a bonus from a pedagogic standpoint to
make the vwait explicit (I say this from experience on clt !) in
scripts starting with [exec tclsh ... package require Tk].
-Alex
Well, I want it. And I know a lot of other people who agree with me.
Maybe it's time for a new Ouster-vote on this subject..... ;-)
Anyway, I never received a bug-report which told me there was anything
wrong with my approach. On the other hand, there appear regular
postings on comp.lang.tcl asking why Tk isn't a regular package.
Those postings only are talking about a "package require Tk" in
the beginning, not about adding an event loop. In my opionion,
an event loop doesn't belong in an application, but should be
taken care of by the library.
> This BTW doesn't scale up. What if a second
> package wants to start its own loop at the end ? While clearly
> they can perfectly coexist in peace (each with its own event
> callbacks) if the vwait is done by the programmer !
Well, actually the Tcl_MainLoop() function adds a mechanism for other
applications (or extensions) to interfere with the event loop. I
didn't document that yet because currently there are no other
extensions than Tk which provide their own event loop. The
code is small enough to be understandable.
Yes, and I'd remove the smiley. When we talk about 'historical baggage'
(in the negative sense) for a language, it often amounts to a series of
questionable design choices made hastily like the one you're about to
make.
> Anyway, I never received a bug-report which told me there was anything
> wrong with my approach.
So what ? Had you ever noticed that [concat] was not list-aware before I
posted the report ? Enormous things can stay unnoticed forever, because
not everybody has the time to stick his nose into the internals. The
same applies to more 'philosophical' issues like the one we're talking
about. Your user population is primarily focussed on Tk. No suprise they
don't care about modularity concerns in (the purer thing some of us are
trying to abstract from) Tcl.
> On the other hand, there appear regular
> postings on comp.lang.tcl asking why Tk isn't a regular package.
> Those postings only are talking about a "package require Tk" in
> the beginning, not about adding an event loop.
They don't mention it, they don't say "I don't want it".
See the focus remark above: most of these posts come from people who
scarcely know what 'update' does.
> In my opionion,
> an event loop doesn't belong in an application, but should be
> taken care of by the library.
I beg to differ strongly. In all C-level GUI toolkit the final call to
the event loop is done explicitly by the client. To follow your advice,
the event loop would be called by atexit()...
More generally, the very statement above is the basis for all the
misconceptions about event-driven programming at least in the Tcl
community: people think it's just plain magical, because they've never
seen the true vwait that's hidden in wish. I'm not saying wish should be
changed or removed, for obvious compat reasons. Instead I'm saying wish
should be a pure-Tcl script that does [package require Tk] *and* [vwait
forever] (I mean [tkwait window .]). It would first serve as such (the
one true wish), and also as an important idiom; hence people wanting to
[package require Tk] would naturally add the vwait, just like in wish !
Another - so far unmentioned - point is that an explicit vwait allows
more intuitive cleanup code: the code after the vwait !
> > This BTW doesn't scale up. What if a second
> > package wants to start its own loop at the end ? While clearly
> > they can perfectly coexist in peace (each with its own event
> > callbacks) if the vwait is done by the programmer !
>
> Well, actually the Tcl_MainLoop() function adds a mechanism for other
> applications (or extensions) to interfere with the event loop. I
> didn't document that yet because currently there are no other
> extensions than Tk which provide their own event loop. The
> code is small enough to be understandable.
Yet all this is unneeded complexity: it simply doesn't pass the Occam
test.
-Alex
Well I'd liked to see this argument resolved because I'd like to see the
plus (and dash) patches in the core a.s.a.p. so that I can count on their
features in scripts and tclets.
> Another - so far unmentioned - point is that an explicit vwait allows
> more intuitive cleanup code: the code after the vwait !
This sounds like it might have some validity, but so far I've never needed
to write tcl code after the "vwait forever". Can you give a more concrete
example? (Any C cleanup code can be written either way, so that doesn't count.)
> > > This BTW doesn't scale up. What if a second
> > > package wants to start its own loop at the end ? While clearly
> > > they can perfectly coexist in peace (each with its own event
> > > callbacks) if the vwait is done by the programmer !
> >
> > Well, actually the Tcl_MainLoop() function adds a mechanism for other
> > applications (or extensions) to interfere with the event loop. I
> > didn't document that yet because currently there are no other
> > extensions than Tk which provide their own event loop. The
> > code is small enough to be understandable.
>
> Yet all this is unneeded complexity: it simply doesn't pass the Occam
> test.
Why is it unneeded? If I have a package that extends the event loop
then I would want to extend it with the same mechanism for both wish and tclsh.
You don't want to modify wish, so doesn't tclsh need to be modified to
recognize event loop registrants? (BTW. In Lucent. we have developed
a package that extended the event loop, so I can vouch for the real need for
packages to be able to do this.)
John Ellson
FWIW, I'll chime in for Alex's view: [package require Tk] should NOT alter the
behaviour of the invoking interpreter, it should just make new functionality
available to it.
Chris
--
Rens-se-LEER is a county. RENS-se-ler is a city. R-P-I is a school!
For example, removal of temporary files (eg locks). Of course you can
bind <Destroy> among other things. But doing the cleanup in flat
toplevel code after the vwait has some aesthetic appeal:
set tmp /tmp/mystuff.[pid]
...
vwait forever
puts stderr "Cleanup"
file delete $tmp
> > > > This BTW doesn't scale up. What if a second
> > > > package wants to start its own loop at the end ? While clearly
> > > > they can perfectly coexist in peace (each with its own event
> > > > callbacks) if the vwait is done by the programmer !
> > >
> > > Well, actually the Tcl_MainLoop() function adds a mechanism for other
> > > applications (or extensions) to interfere with the event loop. I
> > > didn't document that yet because currently there are no other
> > > extensions than Tk which provide their own event loop. The
> > > code is small enough to be understandable.
> >
> > Yet all this is unneeded complexity: it simply doesn't pass the Occam
> > test.
>
> Why is it unneeded? If I have a package that extends the event loop
> then I would want to extend it with the same mechanism for both wish and tclsh.
There is a semantic drift here: it's not about *extending* the event
loop (for which there are already complete APIs, like
Tcl_CreateEventSource), but about just *starting* it (ie calling vwait)
on EOF of tclsh's input stream. Please read the previous messages of
this thread.
> You don't want to modify wish, so doesn't tclsh need to be modified to
> recognize event loop registrants?
??? Nonsense - I *do* want to modify the implementation of wish (rewrite
it in vanilla Tcl), within the bounds of backward compatibility. I also
find it perfectly acceptable to extend it in whatever Tk-dependent way
you see fit. I just can't accept to resort to tinkering with
Tcl_MainLoop just to avoid one line of Tcl ([vwait forever]).
>(BTW. In Lucent. we have developed
> a package that extended the event loop, so I can vouch for the real need for
> packages to be able to do this.)
Please give details: in what way is the Tcl_CreateEventSource API
insufficient for your case ?
-Alex
Maybe, but bind <destroy> works in an unmodified wish as well, where this
"aeshetic" code approach is unavailable.
So what "cleabup" can't I do in a bind <destroy>, or in the C code of the extension?
> > Why is it unneeded? If I have a package that extends the event loop
> > then I would want to extend it with the same mechanism for both wish and tclsh.
>
> There is a semantic drift here: it's not about *extending* the event
> loop (for which there are already complete APIs, like
> Tcl_CreateEventSource), but about just *starting* it (ie calling vwait)
> on EOF of tclsh's input stream. Please read the previous messages of
> this thread.
OK, so as I understand it, the issue is, should any package that extends
the event loop be able to flag that the event loop should be started
at the end of initialization of all packages. Possibly multiple packages
would want to set this flag. In fact, interactive tclsh might be one example.
> > You don't want to modify wish, so doesn't tclsh need to be modified to
> > recognize event loop registrants?
>
> ??? Nonsense - I *do* want to modify the implementation of wish (rewrite
> it in vanilla Tcl), within the bounds of backward compatibility.
Fine, but you said that you didn't want to modify -this aspect- of wish. In particular
I believe that you were -not- proposing to require users to add "vwait forever"
to the end of existing wish scripts?
> I also find it perfectly acceptable to extend it in whatever
> Tk-dependent way you see fit.
Thanks ;-) But we were talking about subtracting the feature of
automatically starting the event loop, so it would be a backwards
compatibility issue.
But you were -not- proposing it, so we agree on this point.
> I just can't accept to resort to tinkering with
> Tcl_MainLoop just to avoid one line of Tcl ([vwait forever]).
I'm still struggling to understand why this should be a big deal? I'm
looking for a real technical reason to go one way or the other.
I know Jan's code worked nicely in tcl7.6, and I know that I always
forget to add "vwait forwever" in tcl8.1.1plus (although its easy to
recognize the symptom and fix it). So I'm in favor of Jan's
approach unless you can show me something that I can't do with it.
> >(BTW. In Lucent. we have developed
> > a package that extended the event loop, so I can vouch for the
> > real need for packages to be able to do this.)
>
> Please give details: in what way is the Tcl_CreateEventSource API
> insufficient for your case ?
The application was a distributed computing framework which
we extended to allow components to be programmed in Tcl.
The code is old, now broken, and it was written prior to the
Tcl_CreateEventSource API, but I would think that the API
would be fine. My point was only that there are real needs for
such an extension mechanism to the event loop other than just
for Tk.
John
??? Are you having fun runnning full circle like this ?
The example shown above is obviously meant for a tclsh. It shows that
the minimalistic approach that I'm advocating ([package require Tk] +
*explicit* vwait) allows a more intuitive coding style, in tclsh. Now we
all agree that the alternative in wish so far is the bind-destroy. So
what ?
> So what "cleabup" can't I do in a bind <destroy>, or in the C code of the extension?
I'll only repeat the words 'intuitive' and 'aesthetic appeal'.
Please reread the thread, in chronological order :)
> > > Why is it unneeded? If I have a package that extends the event loop
> > > then I would want to extend it with the same mechanism for both wish and tclsh.
> >
> > There is a semantic drift here: it's not about *extending* the event
> > loop (for which there are already complete APIs, like
> > Tcl_CreateEventSource), but about just *starting* it (ie calling vwait)
> > on EOF of tclsh's input stream. Please read the previous messages of
> > this thread.
>
> OK, so as I understand it, the issue is, should any package that extends
> the event loop be able to flag that the event loop should be started
> at the end of initialization of all packages.
Yes, this description is accurate.
> Possibly multiple packages
> would want to set this flag. In fact, interactive tclsh might be one example.
My point is, why this special handling of the event loop ??? Obvious
generalization leads to also add a flag to:
- switch off the backyard light on exit
- verify our stock of pet food on exit
- brew coffee on exit
> > > You don't want to modify wish, so doesn't tclsh need to be modified to
> > > recognize event loop registrants?
> >
> > ??? Nonsense - I *do* want to modify the implementation of wish (rewrite
> > it in vanilla Tcl), within the bounds of backward compatibility.
>
> Fine, but you said that you didn't want to modify -this aspect- of wish. In particular
> I believe that you were -not- proposing to require users to add "vwait forever"
> to the end of existing wish scripts?
Are you again playing your full-circle song ? Of course I'm not
proposing to require users to add "vwait forever" to the end of existing
wish scripts, for obvious backward compatibility. Instead I want to
require them to do so (if they want an event loop!) at the end (or
earlier!) of a *tclsh* script even if it calls [package require Tk].
> > I also find it perfectly acceptable to extend it in whatever
> > Tk-dependent way you see fit.
>
> Thanks ;-) But we were talking about subtracting the feature of
> automatically starting the event loop, so it would be a backwards
> compatibility issue.
>
> But you were -not- proposing it, so we agree on this point.
At last !!! Frankly I fail to follow the exact shape of your full-circle
trajectory, but the final position is okay :)
> > I just can't accept to resort to tinkering with
> > Tcl_MainLoop just to avoid one line of Tcl ([vwait forever]).
>
> I'm still struggling to understand why this should be a big deal? I'm
> looking for a real technical reason to go one way or the other.
Here is what I consider the strongest technical reason of all: Occam's
razor. Minimality. KISS.
If you cannot be touched by that, then I give up. Build whatever heap of
crap you want with whatever arbitrary subdvisions and special cases you
like. Make Tcl another Perl. Go ahead.
> > Please give details: in what way is the Tcl_CreateEventSource API
> > insufficient for your case ?
>
> The code is old, now broken, and it was written prior to the
> Tcl_CreateEventSource API, but I would think that the API
> would be fine.
So what ???
> My point was only that there are real needs for
> such an extension mechanism to the event loop other than just
> for Tk.
Again, this "extension mechanism to the event loop" exists, is *not*
restricted to Tk, and is called Tcl_CreateEventSource. Now can you get
back to the subject please ?
-Alex
Let me join the chorus. One thing I would like to do with a truly
loadable Tk is write some image format conversion filter scripts
for tclsh. Read in an image in one format from stdin and write
out the image converted to another format (or otherwise processed)
to stdout. Tk's [image] command, possibly combined with the Img
extension, provides the powerful guts needed for this task.
However with no loadable Tk, you must use wish, and on MS Windows,
this means no usable stdin and stdout channels.
I don't want tclsh converting itself into wish when it loads Tk.
tclsh has features I need. If I want wish, it's there for me to use.
Some other issues with a loadable Tk:
1. Tk insists on connecting to an X display at initialization. Image
format conversion filter scripts need the [image] command, but
don't necessarily need a display. Perhaps connection to a display
by Tk should be programmable, or commands like [image] which can
be useful without a display should be factored out into another
extension? (I know, there's always the Xvfb workaround).
2. Tk consumes options from $::argv. When Tk is exclusively part of
wish, this is not a problem, but when a [package require Tk]
can cause a Tk initialization at an arbitrary place in a
program, the programmer needs to be warned that $::argv better be
in acceptable shape before the call, and it may be modified by
the call. (For example, a "-h" in $::argv will bring the
program to a halt with a Tk help message written to stderr.)
--
| Don Porter, D.Sc. Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/mcsd/Staff/DPorter/ NIST |
|______________________________________________________________________|
> > OK, so as I understand it, the issue is, should any package that extends
> > the event loop be able to flag that the event loop should be started
> > at the end of initialization of all packages.
>
> Yes, this description is accurate.
>
> > Possibly multiple packages
> > would want to set this flag. In fact, interactive tclsh might be one example.
>
> My point is, why this special handling of the event loop ??? Obvious
> generalization leads to also add a flag to:
>
> - switch off the backyard light on exit
> - verify our stock of pet food on exit
> - brew coffee on exit
Now who is getting off topic?
Why do you consider this to be special handling? It seems completely
general to me. Any extension that needs an event loop also needs the
event loop to be started after all packages have been initialized.
Included in this category are wish, and the interactive "extension" to tcl
that provides tclsh.
John Ellson
Here's one case where I think such a thing might be useful:
If you have a package that starts an event loop at the end (say, a new
version of Expect or something) and you want to source that (unmodified)
to use parts of it or perhaps invoke it later, a [tkwait window .] at
the end will make [source] hang up. Setting a flag will not, especially
if there's a mechanism to unset the flag as well.
I've never done this, but it might be something to consider.
--
Darren New / Senior Software Architect / MessageMedia, Inc.
San Diego, CA, USA (PST). Cryptokeys on demand.
There is no "best" programming language. Only "least worst."
Let me give some example why I think that it is very useful to have
an implicit start of the event loop at the end of the script (which
is different from the end of the application)
Some simple minimal code:
# hello.tcl variant
package require Tk
button .b -text "button"
pack .b
vwait forever ;# This line causes the problems described below
# end
- This code hangs forever if the window is closed manually.
Nothing is visible, but the process still runs in the background.
- This code cannot be "source"'d from the console, neither the one
from tclsh, neither the one from wish. The script would be stuk
in the "vwait". This makes debugging GUI applications almost
impossible.
- If other functions call vwait in turn, we have multiple
vwait's running inside each other. We already know what
unexpected bugs that programming style can cause.
"event-driven" programming is fundamentally different from
"procedural" programming. The traditional approach of procedural
languages is indeed that the end of the application is where the
code ends. It has been shown that this appoach is not practical
for GUI's, because of the event loop. Making the loop
implicit, as is currently the case in wish, is soooo
useful!!!!!! It has nothing to do with good or bad programming
style, it's just a different style. Further on, "procedural"
programming can be seen as a subset of "event-driven"
programming: If there are no events to be processed,
the application will still finish at the end of the code.
I really don't see what's the big deal!!!!!!
If the main point is programming style, then the "vwait"
command should be totally forbidden. Much better is
to use "after", which can do exactly the same things
but depends on the event loop. In my opinion, using
"after" shows a much better programming style than
using "vwait" or "tkwait". How many unexpected infinite
loops did the "vwait" command already cause in applications?
If the author would have used "after" instead, those
bugs would not have occured.
So far. we seem to have 2 votes in favor and 3 against:
In Favor:
Jan Nijtmans
John Ellson
Against:
Alexandre Ferrieux
Christopher Nelson
Don Porter
Anyone else who wants to join one of the groups, (preferably mine)......... ;-)?
Do more people have problems with the plus-patch approach? I suggest
anyone who has a strong opinion about this to email me.
In one week (say july 1st) I'll publish the results on
comp.lang.tcl together with the names of the voters.
That's the only way to find out how the Tcl community
really feels about this subject.
I am building applications by incorporating my C++ code into a custom
tclsh using SWIG 1.1p5. I have been building against the plus patches
(8.0.4+, at the moment) specifically because I wanted to exploit
[package require Tk] to add a GUI to a (normally) batch program.
When I run the GUI code through my custom tclsh, I *must* include a
[tkwait] at the end. I assumed that it was because the plus patches'
tclAppInit.c was different than the code included by SWIG. But now that
I've looked at the code, I don't see exactly where the difference lies.
Is it because the default console is (was) TkCon, which includes Tk and
the event loop already?
I would vote for an explicit call to the event loop from tclsh. That
makes good intuitive sense to me.
Bob
--
Bob Techentin techenti...@mayo.edu
Mayo Foundation (507) 284-2702
Rochester MN, 55905 USA http://www.mayo.edu/sppdg/sppdg_home_page.html
> Let me give some example why I think that it is very useful to have
> an implicit start of the event loop at the end of the script (which
> is different from the end of the application)
>
> Some simple minimal code:
> # hello.tcl variant
> package require Tk
> button .b -text "button"
> pack .b
> vwait forever ;# This line causes the problems described below
> # end
>
I do not like the 'vwait forever' to be added into the Tk code.
You will have two versions of Tk code. It is not necessary to
maintain two versions.
I think 'vwait' and 'after' are two different commands.
Can you use 'after' replace 'vwait'?
> So far. we seem to have 2 votes in favor and 3 against:
>
I prefer the implicit event loop.
> In Favor:
> Jan Nijtmans
> John Ellson
> Against:
> Alexandre Ferrieux
> Christopher Nelson
> Don Porter
>
> Anyone else who wants to join one of the groups, (preferably mine)......... ;-)?
> Do more people have problems with the plus-patch approach? I suggest
> anyone who has a strong opinion about this to email me.
> In one week (say july 1st) I'll publish the results on
> comp.lang.tcl together with the names of the voters.
> That's the only way to find out how the Tcl community
> really feels about this subject.
>
> Regards,
> --
> Jan Nijtmans, CMG Arnhem B.V.
> email: Jan.Ni...@wxs.nl (private)
> Jan.Ni...@cmg.nl (work)
> url: http://home.wxs.nl/~nijtmans/
--
--------------------------------------------------------------
Chang LI, Neatware
email: cha...@neatware.com
web: http://www.neatware.com
--------------------------------------------------------------
On windows there are two kinds of applications: console and windows.
In the console application there is no event loop from the windows
OS. In the windows application Windows itself includes an event loop.
Tclsh is just a console application. When add Tk it became a
windows applicaion. So I did not clear why you need the vwait in the
Tk script if you let tclsh as a windows application.
In other words, why you need a console tclsh? The console in windows
has very limited functions. For example, you can not embed the
console window to a normal window. MS had fundamental trouble to
integrate the console into the normal window loop.
> Christopher Nelson <ch...@pinebush.com> wrote:
> > FWIW, I'll chime in for Alex's view: [package require Tk] should NOT
> > alter the behaviour of the invoking interpreter, it should just make
> > new functionality available to it.
>
> Let me join the chorus. One thing I would like to do with a truly
> loadable Tk is write some image format conversion filter scripts
> for tclsh. Read in an image in one format from stdin and write
> out the image converted to another format (or otherwise processed)
> to stdout. Tk's [image] command, possibly combined with the Img
> extension, provides the powerful guts needed for this task.
> However with no loadable Tk, you must use wish, and on MS Windows,
> this means no usable stdin and stdout channels.
>
You need to create a console window to get stdin and stdout.
> I don't want tclsh converting itself into wish when it loads Tk.
> tclsh has features I need. If I want wish, it's there for me to use.
>
> Some other issues with a loadable Tk:
>
> 1. Tk insists on connecting to an X display at initialization. Image
> format conversion filter scripts need the [image] command, but
> don't necessarily need a display. Perhaps connection to a display
> by Tk should be programmable, or commands like [image] which can
> be useful without a display should be factored out into another
> extension? (I know, there's always the Xvfb workaround).
>
> 2. Tk consumes options from $::argv. When Tk is exclusively part of
> wish, this is not a problem, but when a [package require Tk]
> can cause a Tk initialization at an arbitrary place in a
> program, the programmer needs to be warned that $::argv better be
> in acceptable shape before the call, and it may be modified by
> the call. (For example, a "-h" in $::argv will bring the
> program to a halt with a Tk help message written to stderr.)
>
> --
> | Don Porter, D.Sc. Mathematical and Computational Sciences Division |
> | donald...@nist.gov Information Technology Laboratory |
> | http://math.nist.gov/mcsd/Staff/DPorter/ NIST |
> |______________________________________________________________________|
--
It seems to me there may be a more general issue lurking here. How
should scripts control the interpreter which evaluates them? Should
they explicitly select a shell which is known to support their commands?
Or should they take whatever shell they get, and load whatever missing
packages they need? Or some combination?
A script -- a file containing Tcl commands -- needs a shell for its
evaluation. Unix systems -- the original home of Tcl -- let you enable
the executable bit of the script, and start the script with a "#!"
indication of what evaluating shell should be used to interpret the
script. If a script includes Tk commands, the "#!" must select "wish"
or some other shell which provides Tk.
On Windows, the evaluating shell gets selected according to an
association with the file extension of the script. That association is
stored in the Windows registry. The script doesn't get a direct say
in what shell evaluates it.
Since loadable extensions and the [package] command appeared in Tcl 7.5,
scripts have the power to modify the interpreter in which they are being
evaluated by adding any missing packages they require, so long as those
packages are loadable and installed where they can be loaded into
whatever interpreter is evaluating the script.
Loadable extensions hold out the promise that the days of having
a separate "big shell" for every extension combination can be driven
into the past. Instead, there could be only one shell which is
supplied with whatever capabilities are required by loading more
extensions. That is nearly true now, but since Tk is not loadable
(out of the box), there are still two "big shells" left, tclsh and
wish.
Since Windows doesn't (easily) support selection of the evaluating
shell by a script, and because package loading appears to scale
more reasonably than having multiple shells available with different
package combinations, it looks like having scripts control their
interpreters entirely with [package require] is the way to go.
For Tk, this means doing away with wish, and having tclsh as the
sole remaining shell, and [package require Tk] as the means to
access the Tk commands.
Sadly, the two remaining "big shells" -- tclsh and wish -- differ in
more than the packages they include. They also differ in the logic of
their main loop, their support for standard channels on Windows, and
whether their interactive command loop is event driven or not.
So, any scripts written for wish probably won't quite work in tclsh +
[package require Tk] unless [package require Tk] has the side effects
proposed by Jan.
Of course, scripts written for wish likely don't have
[package require Tk] in them anyway since Tk doesn't have to be loaded
into wish. Since script writers have to add that to their scripts
anyway to join the new "one shell" world, how much more would be
reasonable to ask of them? Adding an explicit [tkwait window .]
at the end of their scripts doesn't seem to be popular.
Perhaps the "side-effect" portion of [package require Tk] proposed by
Jan could be provided by another extension named "wish"? Then those
with wish scripts would have to add both [package require Tk] and
[package require wish] to their scripts to be compatible with the new
"one shell" world. Those of us who want the Tk commands but not the
wish-style main loop and channel handling could [package require Tk]
alone.
#----------------------------------------------------------------------#
Regarding some issues that Jan brought up in favor of an implicit
event loop started by the initialization of the Tk package...
Jan Nijtmans <Jan.Ni...@wxs.nl> wrote:
> - This code hangs forever if the window is closed manually.
> Nothing is visible, but the process still runs in the background.
Isn't that why Alex suggested [tkwait window .] rather than
[vwait forever] ?
> - This code cannot be "source"'d from the console, neither the one
> from tclsh, neither the one from wish. The script would be stuk
> in the "vwait". This makes debugging GUI applications almost
> impossible.
Making a script "sourceable" from an interactive console always requires
some special programming styles, doesn't it? F.e., if a window is going
to be created, you must check that it doesn't already exist, if you want
your script to be "sourceable" again and again while debugging.
Likewise, you could check whether $::argv0 and [info script] are the
same and call or not call [tkwait window .] accordingly.
> - If other functions call vwait in turn, we have multiple
> vwait's running inside each other. We already know what
> unexpected bugs that programming style can cause.
But those bugs always come out of a misunderstanding about how [vwait]
works. The [vwait forever] idiom can only cause trouble if you
actually set a global variable named 'forever' and expect the script to
exit. That expectation could be frustrated by a nested [vwait]. An
explicit [exit] is probably preferred anyway. Other than that,
[vwait forever] just means "start the event loop".
> Do more people have problems with the plus-patch approach?
I confess I've never used the plus patches, so maybe my opinion
shouldn't count for much. I hope it's enough to get other people
thinking and commenting though.
1. Enter event loop via tkwait .someWindow and not "."
2. Allow essentially command-line applications, i.e. applications using Tcl
as an imbeded interpreter to pop up a window. For example I have a number of
data processing and simulation applications all of which use Tcl, it would be
really nice to be able to be able to "pop up" a visualisation window even
from an initially non-X application started in an Xterm. This would be easy
to do if I have control of when the event loop is started.
3. If screenless Tk is ever implemented you would be able to do say canvas
rendering to provide (again for non-windows applications) graphics output
behind the scenes. This again needs control over starting/stopping the event
loop.
There are of course ways round these in other schemes, but having a clean
implementation with an explicit tkwait seems to me to be the best option.
--
Dr. Paul Alexander
Mullard Radio Astronomy Observatory,
Department of Physics, Cavendish Laboratory,
University of Cambridge, Cambridge, UK.
FAX: 44 1223 354 599
Tel: 44 1223 337 308
I believe that Alexandre was proposing to reimplement wish as a Tcl
script which performs [package require Tk], argument processing,
starting the event loop, and all those other nice side effects. The new
wish would behave exactly as before, and no scripts would break.
On the other hand, scripts that *may* choose to load Tk with an explicit
[package require] would have to also start the event loop. These
scripts would also have to handle colormaps, geometries, and other
whatnots that are presently taken care of by wish. This extra effort
would be required whether the Tcl interpreter is tclsh or embedded in
some other application.
This approach seems consistent.
>
> Christopher Nelson <ch...@pinebush.com> wrote:
> > FWIW, I'll chime in for Alex's view: [package require Tk] should NOT
> > alter the behaviour of the invoking interpreter, it should just make
> > new functionality available to it.
>
> Let me join the chorus. One thing I would like to do with a truly
> loadable Tk is write some image format conversion filter scripts
> for tclsh. Read in an image in one format from stdin and write
> out the image converted to another format (or otherwise processed)
> to stdout. Tk's [image] command, possibly combined with the Img
> extension, provides the powerful guts needed for this task.
> However with no loadable Tk, you must use wish, and on MS Windows,
> this means no usable stdin and stdout channels.
>
> I don't want tclsh converting itself into wish when it loads Tk.
> tclsh has features I need. If I want wish, it's there for me to use.
>
> Some other issues with a loadable Tk:
>
> 1. Tk insists on connecting to an X display at initialization. Image
> format conversion filter scripts need the [image] command, but
> don't necessarily need a display. Perhaps connection to a display
> by Tk should be programmable, or commands like [image] which can
> be useful without a display should be factored out into another
> extension? (I know, there's always the Xvfb workaround).
>
> 2. Tk consumes options from $::argv. When Tk is exclusively part of
> wish, this is not a problem, but when a [package require Tk]
> can cause a Tk initialization at an arbitrary place in a
> program, the programmer needs to be warned that $::argv better be
> in acceptable shape before the call, and it may be modified by
> the call. (For example, a "-h" in $::argv will bring the
> program to a halt with a Tk help message written to stderr.)
>
Maybe it is worth to take a look on the perl solution of loading Tk. A
minimal perl/Tk program looks like:
use Tk;
$top = new MainWindow;
MainLoop;
which would translate to Tcl/Tk:
package require Tk
mainwindow .
tk_mainloop
Command line processing is done in the package Tk::CmdLine, which is
called when the mainwindow is created. The event loop is explicitely
started with MainLoop.
Regards,
Slaven
--
use Tk;$c=tkinit->Canvas->pack;$x=5;for(split/_/,'KPI1_+09IPK_K;-OA1_+K!;A__1;
Q!7G_1+QK_3CLPI90,_+K!;A_+1!KQ!.N_K+1Q!.F_1+KN.Q__1+KN._K+1Q!.F_1+KN.Q_+1Q__+1!
KQ!.N_1;Q!7G_K3,09Q_+1!K.Q_K+1Q!.F_1+KN.Q'){s/\n//g;for(split/!/){$c->create(
'line',map{$a=-43+ord;($x+($a>>3)*2,5+($a&7)*2)}split//)}$x+=12}MainLoop
Thanks for replying. Perhaps if I offer an example you can
explain some of the subtleties in this MS Windows difference
between a console app and a windows app which appears to break
Unix-style use of standard channels in wish.
Consider this Tcl script:
# FILE: demo.tcl
while {[gets stdin line] != -1} {
puts stdout $line
flush stdout
}
exit 0
# END FILE: demo.tcl
And consider this interactive tclsh session:
C:\> tclsh80
% info patch
8.0.5
% set f [open "|tclsh80 demo.tcl" w+]
file7
% foreach line {foo bar snafu} {
puts $f $line
flush $f
gets $f backLine
puts stdout "Back from demo: $backLine"
}
Back from demo: foo
Back from demo: bar
Back from demo: snafu
Using tclsh as the child shell works fine.
Now, another interactive tclsh session using wish as the child:
C:\> tclsh80
% set f [open "|wish80 demo.tcl" w+]
file7
% foreach line {foo bar snafu} {
puts $f $line
flush $f
gets $f backLine
puts stdout "Back from demo: $backLine"
}
It just sits there.
On Unix it works the same whether the child shell is tclsh
or wish. If the child script needs to use Tk commands on
Windows, I'm stuck.
Now the good news. I tried to reproduce this problem on
Tcl/Tk 8.1.1 for Windows and I can't. The problem with
wish's standard channels seems to be fixed in Tk 8.1.1, at
least for this example.
Any words of Windows wisdom would be welcome.