How to Call TCL Procedure using Python
Question:
Using below code i can able to call all procedure in the Proc.tcl file ,but i want to call individually the procs like sum or sub ,Please let me know any other possibility to call it
My proc file program,
puts "hello"
proc sum {a b} {
set c [expr $a + $b]
puts "Addition: $c "
}
proc sub {a b} {
set c [expr $a - $b]
puts "Substraction: $c "
}
My Main file program,
import Tkinter
import os
r=Tkinter.Tk()
r.tk.eval('source proc.tcl')
Answers:
I do not know tcl, but this looks logical:
import tkinter
r=tkinter.Tk()
r.tk.eval('source proc.tcl')
r.tk.eval('sum 1 2')
r.tk.eval('sub 1 2')
>>> hello
>>> Addition: 3
>>> Substraction: -1
Just carry on as you are:
>>> import Tkinter
>>> r = Tkinter.Tk()
>>> r.tk.eval('proc sum {a b} {set c [expr {$a + $b}]; puts "Sum $c"; return $c}')
''
>>> r.tk.eval('sum 2 5')
Sum 7
'7'
So in your case, having sourced the tcl file you can just do r.tk.eval("sum 5 5")
to call that procedure.
Note: always brace expr expressions in tcl. As in my example above.
If you don’t need the power of Tkinter, you can restructure proc.tcl a little and call the proc
via subprocess
:
proc.tcl:
proc sum {a b} {
set c [expr $a + $b]
puts "Addition: $c "
}
proc sub {a b} {
set c [expr $a - $b]
puts "Subtraction: $c "
}
eval $argv; # NOTE 1
caller.py:
import subprocess
import shlex
def tcl(command):
command_line = shlex.split(command)
output = subprocess.check_output(command_line)
return output
print(tcl('tclsh proc.tcl sum 5 8'))
print(tcl('tclsh proc.tcl sub 19 8'))
Output of caller.py:
b’Addition: 13 n’
b’Subtraction: 11 n’
Discussion
-
Note 1: In the Tcl script, the line eval $argv
takes what on the command line and execute it. It does not provide error checking at all, so potentially is dangerous. You will want to check the command line for malicious intention before executing it. What I have here is good for demonstration purpose.
-
The function tcl
in caller.py takes a command line, split it, and call proc.tcl to do the work. It collects the output and return it to the caller. Again, for demonstration purpose, I did not include any error checking at all.
instead of r.tk.eval(‘source proc.tcl’)
try with os.system (‘source proc.tcl’)
and import OS
Use can use r.eval
:
r.eval('source proc.tcl')
r.eval('sub {0} {1}'.format(a, b))
You should write just functions in proc.tcl
.line like puts "hello"
will be executed when evaluated with eval
.
import subprocess
r = subprocess.check_output('tclsh proc.tcl', shell=True)
in Caller.py try:
import tkinter
import os
r = tkinter.Tk()
r.tk.evalfile('proc.tcl')
r.tk.eval('sum 1 2')
r.tk.eval('sub 1 2')
also, if you want to give numbers from your Python file, change like:
import tkinter
import os
r = tkinter.Tk()
r.tk.evalfile('proc.tcl')
x = 1
y = 2
r.tk.eval('sum {} {}'.format(x,y))
r.tk.eval('sub {} {}'.format(x,y))
Using below code i can able to call all procedure in the Proc.tcl file ,but i want to call individually the procs like sum or sub ,Please let me know any other possibility to call it
My proc file program,
puts "hello"
proc sum {a b} {
set c [expr $a + $b]
puts "Addition: $c "
}
proc sub {a b} {
set c [expr $a - $b]
puts "Substraction: $c "
}
My Main file program,
import Tkinter
import os
r=Tkinter.Tk()
r.tk.eval('source proc.tcl')
I do not know tcl, but this looks logical:
import tkinter
r=tkinter.Tk()
r.tk.eval('source proc.tcl')
r.tk.eval('sum 1 2')
r.tk.eval('sub 1 2')
>>> hello
>>> Addition: 3
>>> Substraction: -1
Just carry on as you are:
>>> import Tkinter
>>> r = Tkinter.Tk()
>>> r.tk.eval('proc sum {a b} {set c [expr {$a + $b}]; puts "Sum $c"; return $c}')
''
>>> r.tk.eval('sum 2 5')
Sum 7
'7'
So in your case, having sourced the tcl file you can just do r.tk.eval("sum 5 5")
to call that procedure.
Note: always brace expr expressions in tcl. As in my example above.
If you don’t need the power of Tkinter, you can restructure proc.tcl a little and call the proc
via subprocess
:
proc.tcl:
proc sum {a b} {
set c [expr $a + $b]
puts "Addition: $c "
}
proc sub {a b} {
set c [expr $a - $b]
puts "Subtraction: $c "
}
eval $argv; # NOTE 1
caller.py:
import subprocess
import shlex
def tcl(command):
command_line = shlex.split(command)
output = subprocess.check_output(command_line)
return output
print(tcl('tclsh proc.tcl sum 5 8'))
print(tcl('tclsh proc.tcl sub 19 8'))
Output of caller.py:
b’Addition: 13 n’
b’Subtraction: 11 n’
Discussion
-
Note 1: In the Tcl script, the line
eval $argv
takes what on the command line and execute it. It does not provide error checking at all, so potentially is dangerous. You will want to check the command line for malicious intention before executing it. What I have here is good for demonstration purpose. -
The function
tcl
in caller.py takes a command line, split it, and call proc.tcl to do the work. It collects the output and return it to the caller. Again, for demonstration purpose, I did not include any error checking at all.
instead of r.tk.eval(‘source proc.tcl’)
try with os.system (‘source proc.tcl’)
and import OS
Use can use r.eval
:
r.eval('source proc.tcl')
r.eval('sub {0} {1}'.format(a, b))
You should write just functions in proc.tcl
.line like puts "hello"
will be executed when evaluated with eval
.
import subprocess
r = subprocess.check_output('tclsh proc.tcl', shell=True)
in Caller.py try:
import tkinter
import os
r = tkinter.Tk()
r.tk.evalfile('proc.tcl')
r.tk.eval('sum 1 2')
r.tk.eval('sub 1 2')
also, if you want to give numbers from your Python file, change like:
import tkinter
import os
r = tkinter.Tk()
r.tk.evalfile('proc.tcl')
x = 1
y = 2
r.tk.eval('sum {} {}'.format(x,y))
r.tk.eval('sub {} {}'.format(x,y))