Python, Tkinter and popen problem

norseman norseman at hughes.net
Thu May 28 21:03:23 CEST 2009


Peter Otten wrote:
> norseman wrote:
> 
>> Peter Otten wrote:
>>> norseman wrote:
>>>
>>>> This was sent 5/19/09 and as yet has received no comments.
>>>> I'm resending just in case a new reader might have an answer.
>>> If you had posted two tiny scripts demonstrating your problem instead of
>>> the longwinded explanation I might have tinkered.
> 
>> That's one of the problems - with Tkinter you don't get tiny files. :)
> 
> Nonsense. The minimal Tkinter program is
> 
> from Tkinter import Tk
> root = Tk()
> root.mainloop()
> 
> The idea is that you remove everything but the parts relevant to your 
> problem (or build a toy example from scratch). This makes it easier for a 
> non-guru to verify a potential answer. That non-guru might even be yourself, 
> by the way.
> 
>> NOTE: program runs perfectly on both Linux and Windows XP Pro when run 
>> from the keyboard. But not from another python program that wants the 
>> phone line connected. (stdin/stdout)  Gee... There is never a County 
>> Lineman when needed is there Glen? :)
> 
> It's not clear why you need to start the GUI at all as you seem to have 
> control over boths scripts.
> 
> Peter
> 
=========================================================================
To cover two responses at once:

Response from MRAB  google at mrabarnett.plus.com

> [snip]
>
> You're more likely to get help if you provide the minimum code that
> demonstrates the problem.
>
> Anyway, your original post said that you're running the child with
> os.popen. The documentation says:
>
> """Open a pipe to or from command. The return value is an open file
> object connected to the pipe, which can be read or written depending on
> whether mode is 'r' (default) or 'w'."""
>

Yes - that is what the docs say.
They also say flush() is supposed to work. The flush() designed for the
file type being used. (I think I counted six different flush() in the
lib.pdf for python 2.5.2...)

> In other words, it's one-way.
>
> Are you really using os.popen and not, say, os.popen2?
>
> (Providing actual code would make this clear.


I have tried both and Popen2.popen2().
os.popen runs both way, contrary to docs.

# master.py
import os
#                both lines work same
#xx= os.popen("/mnt/mass/py/z6.py").readlines()
xx= os.popen("/mnt/mass/py/z6.py",'r',1).readlines()
#                I had hoped small buffer would force a sync (flush())
#                No such luck.
for i in xx:
   print "\t"+i[:-1]

#"""
#                              end of file

The "\t" is to prove where the screen output came from.

========================================================
========================================================

 From Peter __peter__ at web.de

> Nonsense. The minimal Tkinter program is
>
> from Tkinter import Tk
> root = Tk()
> root.mainloop()
>

Just to be clear, that's as much a minimal program as

/* shp2dxfu.c
    purpose: To convert shp files to dxf files. (GNU C Unix version)
*/
#ifdef MSDOS
#include <stdio.h>
#include <math.h>
#include <fcntl.h>
#include <stat.h>
#include <io.h>
#include <alloc.h>
#include <stdlib.h>
#include <string.h>
#include <mem.h>
#endif

#ifdef UNIX
#include <stdio.h>
#include <math.h>
#include <fcntl.h>
#include "stat.h"
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#define O_BINARY 0x00
#define S_IREAD 0400
#endif

int main(argc,argv)
int argc;
char *argv[];
{
/* */
}
and both accomplish absolutely nothing :)

> The idea is that you remove everything but the parts relevant to your
> problem (or build a toy example from scratch). This makes it easier for a
> non-guru to verify a potential answer. That non-guru might even be yourself,
> by the way.

# child.py
import os
import sys
import array
from array import *
import Tkinter
from Tkinter import *
from Tkconstants import *
#
def AttPanel():

   def PlaceIt():
       sys.stdout.write( "Switching to ESRI for placement\n")
       sys.stdout.flush()
       sys.stdout.flush()

       #print "Switching to ESRI for placement"
       ##zatt= bl_x+bl_y+acrs+c1+c2[2:]+c3[2:]+'\n'
       zatt='123456\n'
       #print zatt
       sys.stdout.write(zatt)
       sys.stdout.flush()

       #set system variable to zatt
       root.withdraw()
       #root.iconify()
       while raw_input() != ' ':
         pass
       root.deiconify()

   def CRASH():
     print "\nCRASH Initiated\n"
     exit(1)
#
   root = Tk()

   LU = Frame(root)
   LU.pack(fill="both", expand=1)

   f1 = Frame(LU, relief = GROOVE, bd = 2)
   f1.grid(row = 0, column = 0)
   Button(f1, width= 45, state= DISABLED).grid(row= 0, column= 0)
   Button(f1, text= "Place Attribute", fg= "black", bg= "green",
          anchor= N, command = PlaceIt).grid(row = 0, column = 1)
   Button(f1, width= 45, state= DISABLED).grid(row= 0, column= 2)
   Button(f1, text= "Cancel Attributing", fg= "white", bg= "red",
          anchor= E, command= CRASH).grid(row = 0, column = 3)
   f1.pack()
   #
   root.mainloop()
#---------------#

if __name__ == "__main__":
   while TRUE:
     AttPanel()

#                              end of file


...(snip)
> It's not clear why you need to start the GUI at all as you seem to have
> control over boths scripts.
>
> Peter


Because the master has control over the production line and the child
(one stop along the way) has the purpose of pre-editing the visually
displayed but manually entered data which in turn greatly reduces post
processing problems.



The direct question comes back to:
How does one force a sync or flush() to take effect in Python with
Tkinter in use? Or just in Python period. The keyword being force.

The .force() above has absolutely no visually discernible effect during
program calling program.

Running child direct from keyboard yields correct results.
Calling child from master shows problem.

   In case you missed it - <Place Attribute> - hides widget,
                           <spacebar>        - returns widget,
                           (Cancel ---     > - exits child.
   At least on my machines (Linux and Windows XP Pro).


Steve




More information about the Python-list mailing list