Tkinter -> spawn external cmd -> return stdout and stderr to back Tkinter

Fabien Hénon ffjhenon at club-internet.fr
Tue Mar 26 11:40:48 EST 2002


I need some help for firing up an external program from Tkinter.

I am writing an editor for POV-RAY linux under using Tkinter.
The pov-ray scripts are edited in that editor and can be raytraced from
within.
When POV raytraces, it outputs the image being raytraced and the line
number being raytraced.
When the raytrace is over, it outputs to the console the stats( how long

the process was, number of objects,...), or the error if there is an
error in the script

I use 'spawnv' to fire up POV to start it as a new process. Which
command should I use to get interactive stdout and stderr back to my
Tkinter
application.(do you have any running examples of popen ? the doc is not
clear)
I also would like to be able to stop the raytrace when it is started.

I heard about subproc. I can't get to find it in ftp.python.org

Thanks for any help
Here is the code - still a bit messy
the problem is at line 340


8<------------------ cut here --------------------->8
#! /usr/bin/env python
import sys, os, string
from string import split
from os import spawnv, P_NOWAIT
from Tkinter import *
from tkFileDialog import askopenfilename, asksaveasfilename


# ajouter undo
# ajouter buffers pour multifenêtres
# ajouter close dans menu
# ajouter les 'insert' pov avec cascades
# ajouter chemin pour executable



class mainWin:
  def __init__(self,tkRoot):
    self.tkRoot=tkRoot
    self.createWidgets()
    return None


global params
global filename
plat=sys.platform




class App:

## ---------------------- Create GUI ----------------------

    def __init__(self, master):



## ---------------------- Mainframe ----------------------

        mframe = Frame(master)
        mframe.pack(expand=1, fill=BOTH)
        frame_input=Frame(mframe)


## ---------------------- Menu ----------------------

        menubar=Menu(frame_input)
        filemenu=Menu(menubar,tearoff=0)
        filemenu.add_command(label="New",command=self.clr)
        filemenu.add_command(label="Open",command=self.enter_text)
        filemenu.add_command(label="Close")
        filemenu.add_command(label="Save",command=self.save)
        filemenu.add_command(label="Save As",command=self.saveas)
        filemenu.add_separator()
        filemenu.add_command(label="Quit",command=sys.exit)
        menubar.add_cascade(label="File",menu=filemenu)

        editmenu=Menu(menubar,tearoff=0)
        editmenu.add_command(label="Cut")
        editmenu.add_command(label="Copy")
        editmenu.add_command(label="Paste")
        menubar.add_cascade(label="Edit",menu=editmenu)

        rendermenu=Menu(menubar,tearoff=0)
        rendermenu.add_command(label="Render", command=self.render)
        rendermenu.add_command(label="Options", command=self.render)
        menubar.add_cascade(label="Render",menu=rendermenu)

        insertmenu=Menu(menubar,tearoff=0)
        insertmenu.add_command(label="Animation", command=self.render)

#  CSG
        insertmenucsg=Menu(insertmenu,tearoff=0)
        insertmenucsg.add_cascade(label="difference",
command=self.render)
        insertmenucsg.add_cascade(label="intersection",
command=self.render)
        insertmenucsg.add_cascade(label="inverse", command=self.render)
        insertmenucsg.add_cascade(label="merge", command=self.render)
        insertmenucsg.add_cascade(label="union", command=self.render)
        insertmenu.add_cascade(label="CSG Operations",
menu=insertmenucsg)




        insertmenu.add_command(label="Expressions", command=self.render)

        insertmenu.add_command(label="Headers", command=self.render)
        insertmenu.add_command(label="Light sources",
command=self.render)
        insertmenu.add_command(label="Misc directives",
command=self.render)
        insertmenu.add_command(label="Ready made scenes",
command=self.render)
        insertmenu.add_command(label="Shape modifiers",
command=self.render)

# SHAPES
        insertmenushape=Menu(insertmenu,tearoff=0)

insertmenushape.add_cascade(label="bicubic_patch",command=self.render)
        insertmenushape.add_cascade(label="blob",command=self.render)
        insertmenushape.add_cascade(label="box",command=self.render)
        insertmenushape.add_cascade(label="cone",command=self.render)
        insertmenushape.add_cascade(label="cubic",command=self.render)

insertmenushape.add_cascade(label="cylinder",command=self.render)
        insertmenushape.add_cascade(label="disc",command=self.render)
        insertmenushape.add_cascade(label="fractal",command=self.render)


insertmenushape.add_cascade(label="height_field",command=self.render)
        insertmenushape.add_cascade(label="lathe",command=self.render)
        insertmenushape.add_cascade(label="mesh",command=self.render)
        insertmenushape.add_cascade(label="plane",command=self.render)
        insertmenushape.add_cascade(label="polygon",command=self.render)


insertmenushape.add_cascade(label="polynomial",command=self.render)
        insertmenushape.add_cascade(label="prims",command=self.render)
        insertmenushape.add_cascade(label="quadric",command=self.render)


insertmenushape.add_cascade(label="smooth_triangle",command=self.render)

        insertmenushape.add_cascade(label="sphere",command=self.render)

insertmenushape.add_cascade(label="superellipsoid",command=self.render)
        insertmenushape.add_cascade(label="sor",command=self.render)
        insertmenushape.add_cascade(label="text",command=self.render)
        insertmenushape.add_cascade(label="torus",command=self.render)

insertmenushape.add_cascade(label="triangle",command=self.render)
        insertmenu.add_cascade(label="Shapes", menu=insertmenushape)


        insertmenu.add_command(label="Statements", command=self.render)
        insertmenu.add_command(label="Standard colors",
command=self.render)




        insertmenupattern=Menu(insertmenu,tearoff=0)
        insertmenupattern.add_cascade(label="agate",
command=self.render)
        insertmenupattern.add_cascade(label="average",
command=self.render)
        insertmenupattern.add_cascade(label="boxed",
command=self.render)
        insertmenupattern.add_cascade(label="bozo", command=self.render)

        insertmenupattern.add_cascade(label="brick",
command=self.render)
        insertmenupattern.add_cascade(label="bumps",
command=self.render)
        insertmenupattern.add_cascade(label="checker",
command=self.render)
        insertmenupattern.add_cascade(label="crakcle",
command=self.render)
        insertmenupattern.add_cascade(label="cylindrical",
command=self.render)
        insertmenupattern.add_cascade(label="density_file",
command=self.render)
        insertmenupattern.add_cascade(label="dents",
command=self.render)
        insertmenupattern.add_cascade(label="gradient",
command=self.render)
        insertmenupattern.add_cascade(label="granite",
command=self.render)
        insertmenupattern.add_cascade(label="hexagon",
command=self.render)
        insertmenupattern.add_cascade(label="leopard",
command=self.render)
        insertmenupattern.add_cascade(label="mandel",
command=self.render)
        insertmenupattern.add_cascade(label="marble",
command=self.render)
        insertmenupattern.add_cascade(label="onion",
command=self.render)
        insertmenupattern.add_cascade(label="planar",
command=self.render)
        insertmenupattern.add_cascade(label="quilted",
command=self.render)
        insertmenupattern.add_cascade(label="radial",
command=self.render)
        insertmenupattern.add_cascade(label="ripples",
command=self.render)
        insertmenupattern.add_cascade(label="spherical",
command=self.render)
        insertmenupattern.add_cascade(label="spiral1",
command=self.render)
        insertmenupattern.add_cascade(label="spiral2",
command=self.render)
        insertmenupattern.add_cascade(label="spotted",
command=self.render)
        insertmenupattern.add_cascade(label="waves",
command=self.render)
        insertmenupattern.add_cascade(label="wood", command=self.render)

        insertmenupattern.add_cascade(label="wrinkles",
command=self.render)
        insertmenu.add_cascade(label="Patterns",menu=insertmenupattern)



        insertmenufinish=Menu(insertmenu,tearoff=0)
        insertmenufinish.add_cascade(label="ambient",
command=self.render)
        insertmenufinish.add_cascade(label="attenuation",
command=self.render)
        insertmenufinish.add_cascade(label="brilliance",
command=self.render)
        insertmenufinish.add_cascade(label="caustics",
command=self.render)
        insertmenufinish.add_cascade(label="crand", command=self.render)

        insertmenufinish.add_cascade(label="diffuse",
command=self.render)
        insertmenufinish.add_cascade(label="ior", command=self.render)
        insertmenufinish.add_cascade(label="irid", command=self.render)
        insertmenufinish.add_cascade(label="metallic",
command=self.render)
        insertmenufinish.add_cascade(label="phong", command=self.render)

        insertmenufinish.add_cascade(label="phong_size",
command=self.render)
        insertmenufinish.add_cascade(label="reflection",
command=self.render)
        insertmenufinish.add_cascade(label="roughess",
command=self.render)
        insertmenufinish.add_cascade(label="specular",
command=self.render)

        insertmenu.add_cascade(label="Finish",menu=insertmenufinish)

        menubar.add_cascade(label="Insert",menu=insertmenu)

        root.config(menu=menubar)

## ---------------------- Buttons ----------------------

        frame_buttons=Frame(mframe)
        self.button_open = Button(frame_buttons, text="Open..",
fg="blue", command=self.enter_text)
# self.button_open = Button(frame_buttons, image="open.xpm",
command=self.enter_text)
        self.button_open.pack(side=LEFT)
        self.button_render = Button(frame_buttons, text="Render..",
fg="red", command=self.render)
        self.button_render.pack(side=LEFT)
        frame_buttons.pack(expand=0, fill=BOTH)



## ---------------------- Editor ----------------------

        self.text = Text(frame_input)

        self.yscroll_i = Scrollbar(frame_input,orient=VERTICAL,
command=self.text.yview)
        self.yscroll_i.pack(side=RIGHT, fill=Y)
        self.text['yscrollcommand']=self.yscroll_i.set

        self.text.pack(side=LEFT,expand=1, fill=BOTH)

        self.yscroll_i.pack(side=RIGHT, fill=Y)
        frame_input.pack(expand=1, fill=BOTH)

        bind_class=self.text.bind_class
        bind_class('UPD','<KeyPress>',self.keyPress)
        bind_class('UPD','<ButtonPress>',self.keyPress)
        bind_class('UPD','<Motion>',self.keyPress)
        bind_class('UPD','<ButtonRelease>',self.keyPress)

        oldtags = self.text.bindtags()
        self.text.bindtags(oldtags+('UPD',))


## ---------------------- Output ----------------------

 frame_output=Frame(mframe)
        self.text_out = Text(frame_output,state=NORMAL,height=6)
        self.text_out.pack(side=LEFT,expand=1, fill=BOTH)
        self.scroll = Scrollbar(frame_output,
command=self.text_out.yview)
        self.text_out.configure(yscrollcommand=self.scroll.set)
        self.scroll.pack(side=RIGHT, fill=Y)
        frame_output.pack(expand=0, fill=BOTH)


## ---------------------- Status Bar ----------------------


 frame_status_bar=Frame(mframe)
 self.parameters = Label(frame_status_bar,text="Parameters : ",
anchor="w",bg='gray70')
 self.parameters.pack(side='left')
 self.fill_params=Entry(frame_status_bar,bg='gray100')
 self.fill_params.insert(INSERT,"+w320 +h240 -f +dgt +p")
 self.fill_params.pack(side='left', expand=1, fill=BOTH)
        self.status_filename1 = Label(frame_status_bar,text="File :
",width=5, anchor="w",bg='gray70')
        self.status_filename1.pack(side=LEFT )
        self.status_filename2 =
Label(frame_status_bar,text="",width=20,relief=SUNKEN, anchor="w",
bg="gray90")
        self.status_filename2.pack(side=LEFT)



 self.status_line = Label(frame_status_bar,padx=1,
                                 relief=SUNKEN,bg="gray90",
                                 width=10,
                                 anchor="w",
#                                 textvariable=affi_Ligne
                                  text="1"
                                 )
        self.status_line.pack(side='right')
        self.status_linetext =
Label(frame_status_bar,padx=1,bg='gray70',
                                 width=7,
                                 anchor="w",
                                 text="Line : ")
        self.status_linetext.pack(side='right')


        frame_status_bar.pack(side=LEFT,expand=1, fill='x')


## ---------------------- Open file ----------------------

    def enter_text(self):
          filetypes = ( ( "Pov files","*.pov"), ( "Include
files","*.inc"), ( "All","*"))
          self.filename = askopenfilename(filetypes=filetypes)
          if self.filename:
  self.text.delete(1.0, END)
  fd = open(self.filename)
   for line in fd.readlines():
  if line.endswith("\r\n"):
   line = line[:-2] + "\n"
  self.text.insert(END, line)
   fd.close()

self.status_filename2.config(text=os.path.split(self.filename)[1])
          root.title("POV-RAY editor  |  "+self.filename+"  |")
          buf=self.text.get('1.0','end')
#   print buf



## ---------------------- Clear ----------------------

    def clr(self):
        self.text.delete(1.0, END)
        self.status_filename2.config(text="")
        root.title("POV-RAY editor")


## ---------------------- Save ----------------------

    def save(self, forPrt=None):
      try:
        script = self.text.get(1.0, END)
        if script:
          fd = open(self.filename, 'w')
          for line in string.split(script, '\n'):
            fd.write(line)
            fd.write('\n')
          fd.close
      except:
       self.saveas()



## ---------------------- Saveas ----------------------

    def saveas(self, forPrt=None):
        script = self.text.get(1.0, END)
        if script:
#          global filename
#          self.filename=".pov"
          filetypes = ( ( "Pov files","*.pov"), ( "Include
files","*.inc"), ( "All","*"))
          self.filename = file = asksaveasfilename(filetypes=filetypes)
          fd = open(self.filename, 'w')
          for line in string.split(script, '\n'):
                fd.write(line)
                fd.write('\n')
          fd.close

self.status_filename2.config(text=os.path.split(self.filename)[1])
          root.title("POV-RAY editor  |  "+self.filename+"  |")



## ---------------------- Render button ----------------------

    def render(self):
        global params
 params=self.fill_params.get()
 script = self.text.get(1.0, END)
        if script:
          fd = open(self.filename, 'w')
          for line in string.split(script, '\n'):
            fd.write(line)
            fd.write('\n')
          fd.close

        if plat=="linux-i386":
          app = '/usr/bin/x-povray'    # a remettre
          spawnv(P_NOWAIT, app , ('x-povray', "+i"+self.filename+"
"+params))  # a remettre
        if plat=="win32":
          app = 'c:\\image\\3d\\pov31\\bin\\pvengine'    # a remettre
          spawnv(P_NOWAIT, app , ('pvengine.exe', "+i"+self.filename+"
"+params))  # a remettre

#        appli = split(app)[1]
#  os.spawnl(os.P_NOWAIT, app , params)
#  os.popen3(app +' '+params)
#  os.system("dir" +params+" > foo.txt 2>foo.error.txt")

#        os.system("dir *.py" >"foo.txt")
# os.popen3(app +"+i"+self.filename+" "+params)  # a remettre


## ---------------------- Render keyboard ----------------------

    def render_kb(self,event):
         global params
        params=self.fill_params.get()
  app = r"C:\perso\bureautique\Microsoft Office\Office\excel.exe"
                appli = split(app)[1]
#  os.spawnl(os.P_NOWAIT, app , params)
#  os.system(app +' '+params)
#  os.system(app)
                spawnv(P_NOWAIT, app, (appli, params))


## ---------------------- Top-Level Command line button
----------------------

    def parameters_button(self):
      self.tl=Toplevel()
      self.lb=Label(self.tl, text="Render parameters:")
      self.cl=Entry(self.tl,width=40)
      self.ok=Button(self.tl, text="OK", fg="red",
command=self.get_parameters)
      self.ok.pack(side=BOTTOM)
      self.cl.pack(side=RIGHT)
      self.lb.pack()


      #self.stdout = sys.stdout

## ---------------------- Prints the current line number and contents
----------------------


#        line, col = string.split( self.iText.text.index( 'insert'),
'.')
#        self.linecolLabel.config( text="Line %s Col %s" % (line,col))
# self.status_line

    def lin(self):
        Ligne, column = string.split( self.text.index(INSERT),'.')
        self.status_line.config(text="%s" % (Ligne))




## ---------------------- Called when a key is pressed
----------------------

    def keyPress(self,event):
        self.lin()





root = Tk()




affi_Ligne=StringVar()
#params=StringVar()
larg = root.winfo_screenwidth()
haut = root.winfo_screenheight()
app = App(root)
#root.geometry("%dx%d+0+0" % (larg,haut))
root.title("POV-RAY editor")


root.mainloop()
8<------------------ cut here --------------------->8



More information about the Python-list mailing list