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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

getting tcl to read and store 2 variables from python 2

Status
Not open for further replies.

Sharkadder

Programmer
Apr 22, 2009
10
GB
Hi, since this is a tcl forum i persume you python guys may know about or have used tcl in the past.

I have a question about python and outputting values to another program, i have achieved it but not the way in which i'd like.

Basically i want to send information to a tcl file in which i have created. However the way i've seen so far is to send the data down a pipe using open2 within python. This is great, however does anybody know how i could use 2 pipes or indeed use another form of communication between python and tcl?

With me programming mainly in C# of late i am thinking ways which are not possible in python, however i'm sure one of you guys can point me in the right direction.

Here is code i currently use to send data to tcl from python.

fout, fin = os.popen2("wish ./myfile.tcl", "t")

myvar = "hello"
myvar2 = "world"

fout.write(myvar)
fout.write('\n')
fout.write(myvar2)
fout.write('\n')

fout.close()

So basically i'm wanting to send 2 variables from python to tcl as shown above, then have them stored in their own variable within tcl. It is storing them in seperate variables within tcl i am unsure about.

I am doing this for some good programming practise, so i'd rather not resort to using the tcl/tk interface within python and do it this way instead.

Many thanks
 
Actually this is the Python forum.

Is there any reason you don't want to use sockets?

_________________
Bob Rashkin
 
I've never used sockets in python before and i really don't have the time at the moment to be doing some research on it.

Tell me, have you tried linking python with tcl before? If so, did you manage to change a variables value in python from tcl? It is something in which i am trying to do with pipes but i am not sure how i'd be able to do that.

e.g. i have a variable in tcl called mytclvariable = "hello"

When i send it to python i'd like a variable in python called mypythonvariable to equal "world".

Thanks
 
I've never linked Tcl and Python.

_________________
Bob Rashkin
 
ok dude no worries my man.

p.s. it's something you should look into one time, i've sort of got it working at the moment and it gives you some good results.

Although if tk is integrated within python then there's no need to, but it's good for practice.

Anyways, thanks man
 
Hi Sharkadder,
I would do that using command line arguments in Tcl and os.popen() in Python.

Example:
Given is a Tcl-script which can process 2 command line arguments
cmd_args.tcl
Code:
[COLOR=#804040][b]if[/b][/color] { [COLOR=#008080]$argc[/color] != [COLOR=#ff00ff]2[/color] } {
  [COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"Please enter 2 command line arguments !"[/color]
} [COLOR=#804040][b]else[/b][/color] {
[COLOR=#0000ff]  # storing command line arguments into Tcl-variables[/color]
  [COLOR=#804040][b]set[/b][/color] var01 [[COLOR=#804040][b]lindex[/b][/color] [COLOR=#008080]$argv[/color] [COLOR=#ff00ff]0[/color]] 
  [COLOR=#804040][b]set[/b][/color] var02 [[COLOR=#804040][b]lindex[/b][/color] [COLOR=#008080]$argv[/color] [COLOR=#ff00ff]1[/color]]
  [COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"*Tcl - getting variables from command line arguments:"[/color]
  [COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"var01=$var01, var02=$var02"[/color]
[COLOR=#0000ff]  # compute result[/color]
  [COLOR=#804040][b]set[/b][/color] result [[COLOR=#804040][b]expr[/b][/color] [COLOR=#008080]$var01[/color] * [COLOR=#008080]$var02[/color]]
  [COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"operation result = $result"[/color]
}
We can call the script like this
Code:
C:\Users\Roman\Work>tclsh85 cmd_args.tcl 1 2
*Tcl - getting variables from command line arguments:
var01=1, var02=2
operation result = 2

Then I have this Python script
call_tcl.py
Code:
[COLOR=#a020f0]import[/color] os, string, re

a=5
b=6
[COLOR=#804040][b]print[/b][/color] "[COLOR=#ff00ff]*Python - variables: a = %d, b = %d[/color]" % (a,b)
[COLOR=#0000ff]# create Tcl-command[/color]
tcl_command = "[COLOR=#ff00ff]tclsh85 cmd_args.tcl %d %d[/color]" % (a,b)
[COLOR=#804040][b]print[/b][/color] "[COLOR=#ff00ff] Now executing the command '%s'[/color]" % tcl_command
[COLOR=#0000ff]# call the command[/color]
f=os.popen(tcl_command)
[COLOR=#0000ff]# regex for Tcl-result[/color]
regex_result = re.compile(r"[COLOR=#ff00ff][Rr]esult\s*=\s*(?P<numeric_result>\d+).*[/color]")
[COLOR=#0000ff]# print results[/color]
[COLOR=#804040][b]print[/b][/color] "[COLOR=#ff00ff]*Python - processing results from the Tcl_script:[/color]"
[COLOR=#804040][b]for[/b][/color] line [COLOR=#804040][b]in[/b][/color] f:
  [COLOR=#0000ff]# print line[/color]
  stripped_line=string.rstrip(line)
  [COLOR=#804040][b]print[/b][/color] stripped_line
  [COLOR=#0000ff]# parse result[/color]
  re_search_result=regex_result.search(stripped_line)
  [COLOR=#804040][b]if[/b][/color] re_search_result == None:
    [COLOR=#804040][b]pass[/b][/color]
  [COLOR=#804040][b]else[/b][/color]:
    tcl_result = int(re_search_result.group('[COLOR=#ff00ff]numeric_result[/color]'))
    [COLOR=#804040][b]print[/b][/color] "[COLOR=#ff00ff]Found tcl_result = %d !!![/color]" % tcl_result
    [COLOR=#804040][b]print[/b][/color] "[COLOR=#ff00ff]Now computing a + b + tcl_result = %d + %d + %d = %d[/color]"[COLOR=#6a5acd]\[/color]
        % (a, b, tcl_result, a + b + tcl_result)
Then Python script calls the Tcl-script using os.popen().
The Tcl-output will be parsed line by line using regular expression. If the result of Tcl-script will be found, then it will be used in further computation in Python.
Here is what does the Python script
Code:
C:\Users\Roman\Work>python call_tcl.py
*Python - variables: a = 5, b = 6
 Now executing the command 'tclsh85 cmd_args.tcl 5 6'
*Python - processing results from the Tcl_script:
*Tcl - getting variables from command line arguments:
var01=5, var02=6
operation result = 30
Found tcl_result = 30 !!!
Now computing a + b + tcl_result = 5 + 6 + 30 = 41

Roman
 
Hi,

I tried what you put for use on windows and it works but if i have a tcl program which has some sort of TK output, the output doesn't show, by this i mean no window is displayed showing a possible output.

I tried this code to display a listbox while in tcl when the python script runs a tcl program but i get no joy of graphical output:

if { $argc != 2 } {
puts "Please enter 2 command line arguments !"
} else {
# storing command line arguments into Tcl-variables
set var01 [lindex $argv 0]
set var02 [lindex $argv 1]
puts "*Tcl - getting variables from command line arguments:"
puts "var01=$var01, var02=$var02"
# compute result
set result [expr $var01 * $var02]
puts "operation result = $result"
listbox .box -height 40 -borderwidth 2m -yscrollcommand ".scroll set"
pack .box -side left -padx 2m
scrollbar .scroll -command ".box yview"
pack .scroll -side right -fill y
}

Thanks, hope you can help correct the script. A lot of scripts i have seen are linux variations but obviously you cannot do the same run commands on windows as they do not work
 
Ok just to reply to my post. I have managed to get canvas widgets to be drawn via the command line but when you change tclsh85 to wish85 and run it with the python script it just says no such file, but running the tcl file externally does work.

Anyways to my question. Say i have some widgets on a form, these widgets would be 2 scrollbox's each holding values. What code do i need to send the current text from these scroll boxes over to python when i click on a button saying "submit selection"?

Thanks
 
What code do i need to send the current text from these scroll boxes over to python when i click on a button saying "submit selection"?
It's not possible, that python processes a text from scroll box widget or from other widgets from a Tcl-script.
If you want to use in your python program for calling a Tcl-script this command
Code:
f=os.popen(tcl_command)
then your tcl script should write to standard output (this is console) simply using
Code:
puts "..."
What I showed in my previous post - that windows calls Tcl and then processes the result - works only with console applications.

If you want to use the Tk-widgets from Python, than the best way would be to use Tkinter which is part of python installation.
 
well what i meant was, say that a tcl/tk program is a gui, on this gui you would have a combobox for instance. Ok so is there not a way in which you can tell this value of this combo box to be stored into a list when you press an ok button. Then send the values in a list over to python to do further processing? I am not after sending values direct from a widget to python, i don't mind if they are stored in a list or a tuple first before they are sent.

Thanks, if it's still not possible then just let me know. I guess that i could always save the values to a file and then read them in python from that file. Saying this, there must be a way to store the value from a entry/combo box or both into a list/tuple and then send it over to python.
 
well what i meant was, say that a tcl/tk program is a gui, on this gui you would have a combobox for instance. Ok so is there not a way in which you can tell this value of this combo box to be stored into a list when you press an ok button. Then send the values in a list over to python to do further processing?
Your very first question in this thread was how to send a value from python to Tcl.
Now you ask, how to send a value from Tcl to Python.
It's possible. You surely can call python as any other command from Tcl using command line arguments in python script.
Using command line arguments in python is similar to using them in Tcl (as I showd you in the example above).

But how to do in Tcl a combo box and then on click to store the values of this combo box in a list is tcl-specific question, therefore this would be a question for Tcl-thread here:
 
ok thanks, i have just one question in which you could probably answer for me since you know about linking python to tcl and vise versa.

In python i can call tcl with a command like the one you mentioned via the command line. This will execute a tcl script via the command line.

I can call tcl from python on linux using such a function as this via a pipe:

fout, fin = os.popen2("wish ./your_file.tcl", "t")

(I am not sure what the windows alternative is)


So i can do that, now in tcl i have a value in which i capture from an entry box and then put into a label once a button is clicked as shown below:

set initial "Start With This"
label .lab -text $initial

entry .ent -relief sunken -textvariable initial

button .go -text go -borderwidth 1m

bind .go <ButtonPress-1> {
.lab configure -text $initial
}


pack .go -side left -padx 1m



Ok so what do i need to do to send the variable "initial" to python?

Once i know this, i will be able to send/receive variables to and from tcl/python which is what i am after really, instead of just being able to send them one way.

I tried this code below but i am unsure how i'd capture the variables value in python:

set f [open {| "cmd_args.py"} w];

If you could just explain how i'd capture my variable $initial in python then that would be great.
 
Hi Sharkadder,

I show you the similar example as above, but now I will call Python from Tcl.

So this is a Python-script which can process 2 command line arguments
cmd_args.py
Code:
[COLOR=#a020f0]import[/color] sys

arguments = sys.argv[1:] 
[COLOR=#804040][b]if[/b][/color] len(arguments) != 2:
  [COLOR=#804040][b]print[/b][/color] "[COLOR=#ff00ff]Please enter 2 command line arguments ![/color]"
[COLOR=#804040][b]else[/b][/color]:
  [COLOR=#0000ff]# storing command line arguments into Python-variables[/color]
  var01 = int(arguments[0]) 
  var02 = int(arguments[1])
  [COLOR=#804040][b]print[/b][/color] "[COLOR=#ff00ff]*Python - getting variables from command line arguments:[/color]"
  [COLOR=#804040][b]print[/b][/color] "[COLOR=#ff00ff]var01=%d, var02=%d[/color]" % (var01, var02)
  [COLOR=#0000ff]# compute result[/color]
  result = var01 * var02
  [COLOR=#804040][b]print[/b][/color] "[COLOR=#ff00ff]operation result = %d[/color]" % result
I can call it as follows
Code:
C:\Users\Roman\Work>python cmd_args.py 1 2
*Python - getting variables from command line arguments:
var01=1, var02=2
operation result = 2
And here I have a Tcl-script which calls the above Python script
call_py.tcl
Code:
[COLOR=#804040][b]set[/b][/color] a [COLOR=#ff00ff]5[/color]
[COLOR=#804040][b]set[/b][/color] b [COLOR=#ff00ff]6[/color]
[COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"*Tcl - variables: a = $a, b = $b"[/color]
[COLOR=#0000ff]# create Python-command[/color]
[COLOR=#804040][b]set[/b][/color] py_command [COLOR=#ff00ff]"python cmd_args.py $a $b"[/color]
[COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]" Now executing the command '$py_command'"[/color]

[COLOR=#804040][b]set[/b][/color] py_command [COLOR=#ff00ff]"|python cmd_args.py $a $b"[/color]
[COLOR=#804040][b]set[/b][/color] f [[COLOR=#804040][b]open[/b][/color] [COLOR=#008080]$py_command[/color] [COLOR=#ff00ff]"r"[/color]]

[COLOR=#804040][b]while[/b][/color] {[[COLOR=#804040][b]gets[/b][/color] [COLOR=#008080]$f[/color] line] != -[COLOR=#ff00ff]1[/color]} {
[COLOR=#0000ff]  # print line[/color]
  [COLOR=#804040][b]puts[/b][/color] [COLOR=#008080]$line[/color]
[COLOR=#0000ff]  # parse result[/color]
  [COLOR=#804040][b]set[/b][/color] re_search_result [[COLOR=#804040][b]regexp[/b][/color] {[Rr]esult\s*=\s*(\d+)} [COLOR=#008080]$line[/color] match extracted_group]
  [COLOR=#804040][b]if[/b][/color] {[COLOR=#008080]$re_search_result[/color] == [COLOR=#ff00ff]1[/color]} {
    [COLOR=#804040][b]set[/b][/color] tcl_result [COLOR=#008080]$extracted_group[/color]
    [COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"Found tcl_result = $tcl_result !!!"[/color]
    [COLOR=#804040][b]set[/b][/color] result [[COLOR=#804040][b]expr[/b][/color] [COLOR=#008080]$a[/color] + [COLOR=#008080]$b[/color] + [COLOR=#008080]$tcl_result[/color]] 
    [COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"Now computing a + b + tcl_result = $a + $b + $tcl_result = $result"[/color]
  }
}
[COLOR=#804040][b]close[/b][/color] [COLOR=#008080]$f[/color]
Now, when I call the Tcl-script I get following output
Code:
C:\Users\Roman\Work>tclsh85 call_py.tcl
*Tcl - variables: a = 5, b = 6
 Now executing the command 'python cmd_args.py 5 6'
*Python - getting variables from command line arguments:
var01=5, var02=6
operation result = 30
Found tcl_result = 30 !!!
Now computing a + b + tcl_result = 5 + 6 + 30 = 41
But I see, that calling commands from Tcl seems to be a little bit tricky. Every second time when I call the above script my windows command console freezes and I need to press Ctrl-C. Then it works fine again. I tried several approaches how to call a command from Tcl, but I everytime have this problem. Maybe my Tcl-Version (I use ActiveState Tcl) or my Windows Version (I use Vista Home Basic)??? I don't know.

Ok that's was. I hope that this helps you a little bit. My Tcl experience is not good enough to give you more Tcl-related advice. Ask rather in the Tcl-thread I suggested in my previous post.
 
thanks for all the help man, this is really helpful.

I shall have a little play about with it and see what i come up with. The reason i am needing it is because i extract some data from a file in python but i am wanting to send it over to tcl as i can output it into a widget. I managed to get my data displayed in tcl from python but i never managed to get python to react to tcl scripts.

Hopefully now i can send python a variable from tcl and that can do some processing and then send python the results back.

Many thanks for the help it is apprechiated.
 
First of all, Python has a very tk-like graphical module: Tkinter.
Second, I still don't see why you just don't use sockets.


_________________
Bob Rashkin
 
well my good man, if i knew about sockets in python then i would have done, but since i do not and do not have the time to look into it fully, i shall have to stick to what i have for now.

I will look into sockets with python at a later date probably when i get the time, unless that is sockets are very easy to implement.
 
Sharkadder said:
.. i extract some data from a file in python but i am wanting to send it over to tcl as i can output it into a widget ..
You don't need probably Tcl therefore, because you can do mostly all in Python+Tkinter.
However, I don' know if Tkinter supports all the widgets from Tcl - probably not all, but most of them.

If you only want to process a file and show the results in a widget, then this short example can be useful for you.
It shows you, how you can redirect your standard output to the Tkinter widget named ScrolledText, e.g. for listing of the above given script call_tcl.py in a window:

file2widget.py
Code:
[COLOR=#a020f0]from[/color] Tkinter [COLOR=#a020f0]import[/color] *
[COLOR=#a020f0]from[/color] ScrolledText [COLOR=#a020f0]import[/color] ScrolledText
[COLOR=#a020f0]import[/color] sys

[COLOR=#804040][b]class[/b][/color] [COLOR=#008080]py_text_box[/color]:
  [COLOR=#804040][b]def[/b][/color] [COLOR=#008080]__init__[/color](self, parent):
    [COLOR=#0000ff]# frame[/color]
    self.frame = Frame(parent)
    self.frame.pack()
    [COLOR=#0000ff]# ScrolledText widget[/color]
    self.text = ScrolledText(self.frame, background='[COLOR=#ff00ff]black[/color]',
                foreground='[COLOR=#ff00ff]green[/color]', font=("[COLOR=#ff00ff]Courier[/color]", 9))
    self.text.pack()
    [COLOR=#0000ff]# Buttom widget[/color]
    self.mybutton = Button(self.frame, text="[COLOR=#ff00ff]Quit[/color]",
                    command=self.mybuttonClick)
    self.mybutton.pack()
    self.mybutton.bind("[COLOR=#ff00ff]<Button-1>[/color]", self.mybuttonClick)

  [COLOR=#804040][b]def[/b][/color] [COLOR=#008080]mybuttonClick[/color](self, event):
    self.frame.quit()

  [COLOR=#804040][b]def[/b][/color] [COLOR=#008080]write[/color](self, s):
    self.text.insert(END, s)

[COLOR=#0000ff]### main program[/color]
root=Tk()
text_window = py_text_box(root)
[COLOR=#0000ff]# redirecting standard output to the text_window[/color]
sys.stdout = text_window

[COLOR=#0000ff]# --- Here comes the file processing ---[/color]
f = open('[COLOR=#ff00ff]call_tcl.py[/color]')
[COLOR=#804040][b]for[/b][/color] line [COLOR=#804040][b]in[/b][/color] f:
  [COLOR=#804040][b]print[/b][/color] line[:-1]
f.close
[COLOR=#0000ff]# ---[/color]

root.mainloop()
Now you can call the above script by entering this command on console
Code:
python file2widget.py
or in windows you can call it by double clicking the file file2widget.py or if you don't want to see the command console in background, then you should rename the file to file2widget.pyw and then double click this.

At the similar way you can call other python console application and redirect it's output to the Tkinter window.
 
ok thanks for that, i'll keep it in mind about this tkinker.

I won't have the time to look into it fully but in a few weeks i shall maybe look at it more in detail for use with python.

Anyways, many thanks and it is apprechiated.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top