7

I am having all the libraries written in TCL. I want to create a GUI in Python which will have few buttons and other options. In the start TCL shell will open. When I will click the buttons, respective commands will be executed on the TCL shell.

Is it possible to fire commands on the same shell of TCL without closing TCL shell.

I searched google and find Tkniter module in Python but it will open TCL shell everytime I need to execute command.

Sumit
  • 1,953
  • 6
  • 32
  • 58
  • Sounds to me like you're Doing It Wrong if you're making a new interpreter each time you want to run a command. That's maximising the amount of overhead, which is ridiculous. – Donal Fellows Mar 03 '16 at 09:56
  • 1
    @DonalFellows I read it as he is asking how to use a single TCL interpreter process. E.g. explicitly not launching a new process each time. – Tom Dalton Mar 03 '16 at 09:59
  • No I dont want to make new interpreter each time. I want to run commands on the same old TCL shell – Sumit Mar 03 '16 at 09:59
  • I do this sort of thing using `os.startfile(cmd)` where, for example, `cmd = 'copy myfile.txt C:\\Users\\Philip\\Desktop'` – Marichyasana Mar 08 '16 at 11:27

3 Answers3

2

You can certainly use Tkinter to run a series of commands in the same Tcl interpreter:

Python 2.7.9 (default, Feb 28 2016, 05:52:45) [C] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>> import Tkinter
>>> root = Tkinter.Tk()
>>> root.tk.eval('set msg "hello world"')
'hello world'
>>> root.tk.eval('string length $msg')
'11'
>>> root.tk.eval('foreach x {1 2 4} {puts "$msg $x"}')
hello world 1
hello world 2
hello world 4
''
>>> 

- here the variable msg is set in one command and its value is used in later commands, which would not work if we were creating a new interpreter for each command. If you don't want the Tk window that gets created, just run root.tk.eval('wm withdraw .') to hide it.

If this doesn't answer your question you had better explain what else it is that you need :-)

Colin Macleod
  • 4,222
  • 18
  • 21
  • 1
    Fun fact: It's possible to use tkinter without creating the root window. The `Tk` class takes a keyword argument named `useTk`. If you set it to `False` you'll get a tcl interpreter without tk. – Bryan Oakley Mar 09 '16 at 16:09
1

This problem can be solved by using Pexpect

Pexpect is a Python module for spawning child applications and controlling them automatically. Pexpect can be used for automating interactive applications such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup scripts for duplicating software package installations on different servers. It can be used for automated software testing. Pexpect is in the spirit of Don Libes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python require TCL and Expect or require C extensions to be compiled. Pexpect does not use C, Expect, or TCL extensions. It should work on any platform that supports the standard Python pty module. The Pexpect interface focuses on ease of use so that simple tasks are easy.

Usage example taken directly from the Pexpect website

child = pexpect.spawn('scp foo myname@host.example.com:.')
child.expect ('Password:')
child.sendline (mypassword)

you can spawn the terminal as a child process and then use this child to send commands when GUI generates an event.

Sharad
  • 1,867
  • 14
  • 33
  • 1
    The questioner says he has libraries already written in Tcl which he needs to call from Python. Expect-style functionality is irrelevant here. – Colin Macleod Mar 08 '16 at 13:58
  • Yes that is true however I think it can be accomplished by associating the events generated on clicking a button on Python GUI with expect statements. – Sharad Mar 08 '16 at 14:02
  • Please expand on it if there is something I am missing over here – Sharad Mar 08 '16 at 14:51
0

I created this simple tcl program pgm.tcl

puts "Hello world"

I can launch it in a console

tclsh pgm.tcl

Here is how it can be launched in python

from subprocess import Popen, PIPE
p1 = Popen( ['tclsh', 'pgm.tcl'], stdout=PIPE )
p1out, p1err = p1.communicate()
if p1out is not None: print (p1out)
if p1err is not None: print (p1err)

This answer is OS dependent (linux), but you should be able to adapt it to other OS.

Sci Prog
  • 2,651
  • 1
  • 10
  • 18