BaRud
BaRud

Reputation: 3218

calling a tcl proc in python3

I am trying to call a tcl proc in a python program.

The tcl script starts with

proc scale_wigner-seitz_radii { } {

(I am not sure if I can put the full proc here, as this is a part of a licensed program).

This program is called by my python script:

#!/usr/bin/python3
import sys
from numpy import arange
from tempfile import mkstemp
from shutil import move, copy
from os import remove, close, mkdir, path
import Tkinter


def repll(file_path, pattern, subst):
    print(pattern)
    print(subst)
    print(file_path)
    r = Tkinter.Tk
    # fullpath = str(subst) + "/" + file_path
    fh, abs_path = mkstemp()
    with open(abs_path, "w") as new_file:
        with open(file_path, "r") as old_file:
            for line in old_file:
                new_file.write(line.replace(pattern.strip(),
                                            str(subst).strip()))
    r.tk.eval('source /home/rudra/WORK/xband/create_system_util.tcl')
    r.tk.eval('proc scale_wigner-seitz_radii')
    copy(abs_path, path.join(str(subst), file_path))


inpf = str(sys.argv[1])
a = []
print (inpf)
with open(inpf, "r") as ifile:
    for line in ifile:
        if line.startswith("lattice parameter A"):
            a = next(ifile, "")
            print(a)

for i in arange(float(a)-.10, float(a)+.10, 0.02):
    if not path.exists(str(i)):
        mkdir(str(i))
    repll(inpf, a, i)

I havn't make a minimal example, because this seems better than explaining in english.

At the very end of def repll, it is calling the tcl proc. I have never encountered a tcl script before, and found the calling process from this question. But when I am running this, I am getting error:

Traceback (most recent call last):
  File "xband.py", line 41, in <module>
    repll(inpf, a, i)
  File "xband.py", line 24, in repll
    r.tk.eval('source /home/rudra/WORK/xband/create_system_util.tcl')
AttributeError: class Tk has no attribute 'tk'

How I can solve this?

After Donal's Comment Thanks for your reply. After following your suggestion, I got same error from source line.

Traceback (most recent call last):
  File "xband.py", line 41, in <module>
    repll(inpf, a, i)
  File "xband.py", line 24, in repll
    r.tk.eval('/home/rudra/WORK/xband/create_system_util.tcl')
AttributeError: class Tk has no attribute 'tk'

Sorry if its silly, but since the tcl is in different file, I must source that first, right? And, as I said, this is the first tcl code I am looking at, please be elaborate.

Upvotes: 1

Views: 508

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 385900

The problem seems to be this line:

r = Tkinter.Tk

My guess is, you think this is creating an instance of Tk, but you're merely saving a reference to the class rather than creating an instance of the class. When you instantiate it, the object that gets returned has an attribute named tk, which the object internally uses to reference the tcl interpreter. Since you aren't instantiating it, r (which points to Tk) has no such attribute.

To fix it, instantiate the class by adding parenthesis:

r = Tkinter.Tk()

r will now be a proper reference to a Tk object, and should have a tk attribute, and with that you can call eval on raw tcl code.

Upvotes: 2

Related Questions