Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

writing modules/widgets

Status
Not open for further replies.

zby

Programmer
Oct 31, 2003
22
0
0
CZ
I have kind of a beginer's question:
How can I create some sort of a module (using here the Perl jargon) in TCL/TK?

Situation:
I have 'master' and 'slave' scripts.
Both work fine separately.
Now I want to make them cooperate from within master.
First one collects info from DB while the second one processes user's wish (once he/she clicks on the 'from-DB-returned' line within the master).
Some sort of a 'use DBI' construction in Perl's environtment.
How do I do that?
Some link or a piece of advice?
Thank you?
 
Why wouldn't you make the "slave" a "proc" that is called from the "master"?

Bob Rashkin
rrashkin@csc.com
 
I wanted to somehow separate these scripts for:
Master talks to DB and can up to a certain point live on his own.
Slave picks an id retrieved from DB via master and gets an image from a FS over http.

To debug any possible future troubles I thought it would be more suitable to have them separated and use the 'imageretriever-dislayer' by other possible upcomming applications.

Today I used the proc as you have proposed.
The script became a bit bulkier than I wanted.
I am primarily a perl programmer and writing a module to use in more than one application - script is a good solution.
I supposed this TCL/TK application to work this way as well.
Just like you use 'package require'.
That is how my question raised.

If it is not easy to accomplish I let it for time I am more experienced.
Thank you.
 
Well, as you suggest, there are some complicated ways of doing what you want. However, I think the simplest way, if I understand you correctly, is still to use a proc. However, don't put it in the same file as your "master" script. Rather, put it in a file called, say, "slaveproc.tcl". Or, if you plan to build up a library of procs, "bunchoprocs.tcl". Then, when you want to use the proc, you have two options. You can (and this is simplest) "source slaveproc.tcl" and then call the proc as if it were in the same file. Alternatively, you can create an index file out of as may files of procs as you like: "auto_mkindex <directory> <filename(s)>". Then, in your "master", "lappend auto_path <directory>". Then, when you call a proc, the script will search the index files in all the directories in the list "auto_path" and find the proc you want.

Bob Rashkin
rrashkin@csc.com
 
If you choose to approach this in a 'modular'
way you could look at Itcl.
Using an OO approach might simplify this
problem of yours.
OTOH, it seems like your problem is basically
an IPC issue at some level and either setting
up a local server socket that handles requests
and input from your processes and acts as a
traffic cop may be the solution you are looking
for.
The comm package may also be something you are
interested in.
 
Thank you guys,
the source command is exactly what a want!
Just to pull in the so called 'shared' script once the 'master' script starts up.

Two more things I have:
1. Within the 'shared' one do I have to include '#!/usr/bin/tclsh' ?
2. Do you have any experience with img::tiff (tkimg3.1) ?
 
1. No, you don't need to include the UNIX directives in the sourced script (any more than you would in a proc in the same file).
2. I don't have any experience with the IMG package, but what problems are you having?

Bob Rashkin
rrashkin@csc.com
 
I've had a problem with flooding my memory with image data.
I am working on an application displaying images based on a piece of info from mysql.
The image itself (tiff with JPEG compressed pages) is retrieved via http protocol (sort of a gateway).
It gets stored in a cache dir and split up into single tiff files - pages (out of a multipage tiff) by tiffsplit tool.
Each tiff representing a single page is displayed upon the push of the forward or backward button. Sort of a leafing through.
Whenever a new page is requested, all images in memory MUST be deleted or the memory chokes up slowing down my machine.
THE TROUBLE was that I forgot to 'delete' them and wondered why my PC becomes slow after leafing thourgh more than four pages!!
It even crashed with simple SIGTERM echo on the console when wildly leafing through.
Well, some of the tiffs have more than hundred pages!
Once the 'delete' command was used the leafing through began to 'fly'.
I have tested it on WinXP and Win98 both with ActiveTCL and it worked (with no mysql queries) turning this application into multiplatform.

The part of code was like:
## Get list of pages after previous ones have been deleted
## It is done once a request a completly new DB row
set filelist [ globe -nocomplain -directory $cache * ]

proc src {i} {
global source
set source [image create photo -file [lindex $filelist $i] -format "tiff"]
resize reset # a proc to set the starting display image dimensions that is ok
}

proc resize {w} {
global source
## An image to copy the source into
set img [ image create photo -format "tiff" ]
$img copy $zdroj -subsample $zoom
# write the image data to the frame two
set l [ label $if.two.l -image $img -relief ridge ]
}

The code is 'a few' more lines bigger that this one.

NOW,
I have a trouble with positioning the image '$img' to 0 0 once it is (or before it is) being displayed.

If you feel like digging or playing around with this you can figure something out. I'd be glad to hear about it.
 
How are you displaying the images? In a canvas, with .c create ...? If so, you specify the x,y of the image (lower left, I think). That isn't working?

If you're putting the image in a label widget, as it appears you are in the "resize" proc, then I think it fills the label with the image starting at the lower left of both.

Try just displaying the image in a canvas widget after the resize action. That way you can see what the whole thing looks like. My guess is that you need to crop it for the part you want.

Bob Rashkin
rrashkin@csc.com
 
Thanks for your hint Bob.
I have been assigned to a different project for a time so sorry for no echo since last reply.
My project works with canvas as you proposed, but now a new problem has emerged.
Displaying images (tiff pages) one by one upon a button press (leafing through), the button envokes a procedure:

proc showpic {img} {
global zdroj img c
set zoom 1
$img copy $zdroj -subsample $zoom
$c itemconfigure "dokument" -image ""
$c configure -scrollregion "0 0 [image width $img] [image height $img]"
$c itemconfigure "dokument" -image $img
}

the proc is supposed to:
1. wipe out the old image if any so that only the canvas background is visible for a split of a second
2. configure the canvas object for scrollregions
3. place a new image in the canvas object.

Previous images (pages) don't get wiped out of the screen. The new image is simply laid on top of the old one. If the new one's area is smaller, the old one's edges are sticking out from below.
I tested the 'itemconfigure' canvas option by using a clear shell (wish) and it worked command by command clearing and displaying as presented in the above proc.
This test got me confused. It should work in the same way within a script I guess. Why it doesn't.
Tcl/Tk 8.4.6 (custom compilled)

Thank you for a piece of advice.
 
Well, I think I see what you're trying to do. I've never tried clearing that way. I suspect the problem is the blank image (""). Two suggestions come to mind.
1. If there's nothing else in the canvas, don't use the "itemconfigure" but rather "delete" and "create" (or even if there are other things in the canvas). The problem this may cause to your application is that I think this will delete the tag/ID as well.
2. Actually create a blank image and use it rather than "".

Good luck.

Bob Rashkin
rrashkin@csc.com
 
Hey Bob,

I have returned to my viewer today and before running head first to use your proposal a performed a simple command line test as below:

Code:
[shell]$ wish
% pack [ canvas .c ] -side top -expand yes -fill both
% set obr [ image create photo -file "cz.gif"]
image1
% .c create image 1 1 -anchor nw  -tags "Obr"
1
% .c itemconfigure "Obr" -image $obr
## Got one picture of the czech flag
% image delete $obr
% .c itemconfigure "Obr" -image ""
% set obr [image create photo -file "oracle8i.gif"]
image2
% .c itemconfigure "Obr" -image $obr
## Got the Oracle logo gif displayed
% .c itemconfigure "Obr" -image ""
% image delete $obr
% set obr [image create photo -file "en.gif"]
image3
% .c itemconfigure "Obr" -image $obr
## Got the english flag gif displayed

Outcome:
The Oracle logo was larger than the national flag gifs which were the same in dimensions.
Whenever I did ' .c itemconfigure "Obr" -image "" ' the canvas got cleand out of any image within the tag. I recreated the image object and reconfigured the canvas tag and it displayed the new image without the previous one bugging the current one with anything. The 'clearing' process worked just as I wanted.
Why not in my script when so in shell?

Thank you.
 
Code:
proc showpic {img} {
        global zdroj img c
        set zoom 1
        $img copy $zdroj -subsample $zoom
        $c itemconfigure "dokument" -image ""
        $c configure -scrollregion "0 0 [image width $img] [image height $img]"
        $c itemconfigure "dokument" -image $img
   }

Silly me. See the code? What is weird about it is that whenever I envoke this proc a new copy of the source is made into the $img var and displayed on canvas. Nothing new. BUT, there is no 'image delete $img' prior to '$img copy $zdroj -subsample...'!
It all occured to me when I compared the shell test and my script proc.
It seems to work after I have inserted the missing line in my code.

Thanks a lot for your patience and hints.
Zbyn?k
zby@post.cz
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top