TKinter + display of a shell command return

Y

Yann.K

Hello.

Using Tkinter, i would create a widget which display a shell command return.
This return is long, and i would display a real time display (like with the
tail -f commande on Linux)

I think to use the text widget.
I have no problem to execute the command, but how to display, in a
*real-time* fashion the shell retrun?

If you have a track or an idee...

Thanks for your help.
 
E

Eric Brunel

Yann.K said:
Hello.

Using Tkinter, i would create a widget which display a shell command return.
This return is long, and i would display a real time display (like with the
tail -f commande on Linux)

I think to use the text widget.
I have no problem to execute the command, but how to display, in a
*real-time* fashion the shell retrun?

What is your problem here? Inserting at the end of the text and call the see
method on the text widget to make sure the last line is displayed should be
enough. An update_idletasks may also be needed to actually display something,
but it depends on the architecture of your script, typically on whether you use
threads or not.

A basic script doing what you want is:

--shell_output.py---------------------
import os
from Tkinter import *

root = Tk()
t = Text(root)
t.pack()

def go():
p = os.popen("find . -name '*.py'", 'r')
for l in p.xreadlines():
t.insert(END, '%s\n' % l.rstrip())
t.see(END)
t.update_idletasks()

Button(root, text='Go', command=go).pack()

root.mainloop()
 
Y

Yann.K

Eric said:
What is your problem here? Inserting at the end of the text and call the
see method on the text widget to make sure the last line is displayed
should be enough. An update_idletasks may also be needed to actually
display something, but it depends on the architecture of your script,
typically on whether you use threads or not.
Yes, really it run great but no as i would!
For long process, the display wait the end of the script execution to
display all the lines of the mesage.

I would that the lines appears as soon as the shell putt the message.
So; if the treatment is very long (ie 10 min), the line of the message
appears every second (in fact h*just when they are forwarder from the
shell.

I would display the shell return like an "tail -f syslog" command on
linux...
I hope to be clearer...

Thanks for your help,
 
E

Eric Brunel

Yann.K said:
Eric Brunel wrote:



Yes, really it run great but no as i would!
For long process, the display wait the end of the script execution to
display all the lines of the mesage.

The problem may not be in the Python script, but in the shell command itself:
the output for commands is usually buffered and you won't get a chance to
display anything until the buffer is full or the command explicitely does a
flush. There may be a means to ask the shell to avoid buffering the command
outputs (like Python's -u option), but my shell knowledge does not go as far as
that... And of course, it will depend on the shell flavor you're using...

[...]
Thanks for your help,

You're welcome. Good luck!
 
K

klappnase

Yann.K said:
Yes, really it run great but no as i would!
For long process, the display wait the end of the script execution to
display all the lines of the mesage.

I would that the lines appears as soon as the shell putt the message.
So; if the treatment is very long (ie 10 min), the line of the message
appears every second (in fact h*just when they are forwarder from the
shell.

I would display the shell return like an "tail -f syslog" command on
linux...
I hope to be clearer...

Thanks for your help,

You can use a tk filehandler to capture the output stream of a shell
command.
Here's a code snippet I used to display the output of a shell command
in a text widget:

from Tkinter import *
import fcntl, popen2, os

(...)
self.text.insert('end', '\nExecuting :\n' + cmd + '\n\n')
self.pp = popen2.Popen4(cmd)
# cmd is of course the shell command
self.mkfilehandler(self.pp, self.get_msg)

def mkfilehandler(self, popen4object, function):
fileobject = popen4object.fromchild
filedescr = fileobject.fileno()
fcntl.fcntl(filedescr, fcntl.F_SETFL, os.O_NONBLOCK)
tkinter.createfilehandler(fileobject, READABLE, function)

def get_msg(self, fileobject, mask):
msg = self.pp.fromchild.read()
if msg == '':
p = self.pp.poll()
if p != -1:
tkinter.deletefilehandler(self.pp.fromchild)
self.pp = None
if p == 0:
tkMessageBox.showinfo(...)
else:
tkMessageBox.showerror(...)
else:
self.text.insert('end', msg)

This works well at least on linux, on windows the createfilehandler()
method may not be available:

http://mail.python.org/pipermail/python-list/2002-February/089526.html

More information on createfilehandler() can be found at:

http://www.python.org/doc/faq/gui.html#id14

I hope this helps

Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top