Re: [pygtk] Need help with spawn_async and callback
On RHEL5 I prefer to use Glade to build all the GUI's the project needs. That way I can redesign things if needed without hacking too much in the finished code. On 09/07/2011 02:02 PM, Grant McWilliams wrote: Thanks, Do you find that using Glade is worth the trouble over just hacking it up in gtk directly? I've heard opinions both ways. I'll check over your code. Doing cli programming takes 1/4 the time over gui programming. I'm creating a cli version of my program to satisfy the powers that be while I work on the async gui version which effectively gives someone a couple of buttons and a bunch of progress bars. Really in the end it's just prettier for a while lot more work. Grant McWilliams http://grantmcwilliams.com/ Some people, when confronted with a problem, think "I know, I'll use Windows." Now they have two problems. ___ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/
Re: [pygtk] Need help with spawn_async and callback
Thanks, Do you find that using Glade is worth the trouble over just hacking it up in gtk directly? I've heard opinions both ways. I'll check over your code. Doing cli programming takes 1/4 the time over gui programming. I'm creating a cli version of my program to satisfy the powers that be while I work on the async gui version which effectively gives someone a couple of buttons and a bunch of progress bars. Really in the end it's just prettier for a while lot more work. Grant McWilliams http://grantmcwilliams.com/ Some people, when confronted with a problem, think "I know, I'll use Windows." Now they have two problems. On Wed, Sep 7, 2011 at 7:15 AM, Tony Freeman wrote: > I should mention that my office is using RHEL5 ... so pygtk and > associated are at the 2.10 version. > > > On Wed, Sep 7, 2011 at 10:07 AM, Tony Freeman > wrote: > > Hello Grant, > > > > Below is the entire bit of code I was working on at that time. Pay > > attention to the spawn_async stuff. Good luck! > > > > -- Tony > > > > > > > > #!/usr/bin/python > > > > > > ## THIS IS A GUI FRONT END TO THE adjust_grids.sh > > ## SCRIPT LOCATED IN /DATA/LOCAL/IFPS/ > > ## > > > > > > > > ## SETUP THE ENVIRONMENT: > > > > > > import pygtk > > import gtk > > import gtk.glade > > import gobject > > import os > > > > os.chdir("/awips/dev/localapps/adjust_grids/") > > > > > > ### GLOBAL VARIABLES AND SITE CONFIGURATION: > > > > > > import siteConfig > > > > xx = siteConfig.xx > > guess = siteConfig.guess > > program = siteConfig.program > > > > ### GLOBAL VARIABLES: > > > > keep_pulsing = True > > > > > > ### PULL IN THE GUI: > > > > > > wTree = gtk.glade.XML('adjust_grids.glade') > > > > ### MAIN WINDOW ITEMS (window1): > > > > calendar = wTree.get_widget('calendar1') > > gridbox = wTree.get_widget('combobox_grid') > > modelbox = wTree.get_widget('combobox_model') > > hourbox = wTree.get_widget('combobox_hour') > > statusbar = wTree.get_widget('label_status') > > > > ### PROGRESS WINDOW ITEMS (window2): > > > > window2 = wTree.get_widget('window2') > > dialog1 = wTree.get_widget('dialog1') > > > > progressbar = wTree.get_widget('progressbar1') > > progress_headline = wTree.get_widget('label_progress_headline') > > progress_info = wTree.get_widget('label_progress_info') > > > > textview = wTree.get_widget('textview1') > > textbuffer=textview.get_buffer() > > > > > > ### FILL IN THE LIST BOXES: > > > > > > for i in xx: > >gridbox.append_text(i) > > > > for i in guess: > >modelbox.append_text(i) > > > > gridbox.set_active(0) > > modelbox.set_active(0) > > hourbox.set_active(0) > > > > > > ### DEFINE FUNCTIONS: > > > > > > def write_status(comment): > >statusbar.set_text(comment) > >progress_info.set_text(comment) > > > > def cstdout_callback(fd, condition, channel): > >global keep_pulsing > >if condition == gobject.IO_HUP: > >keep_pulsing=False > >elif condition == gobject.IO_IN: > >text = channel.readline() > >iter = textbuffer.get_end_iter() > >textbuffer.insert(iter, text) > >textview.scroll_to_mark(textbuffer.get_insert(),0) > >return keep_pulsing > > > > def update_progress_callback(): > >global keep_pulsing > >if keep_pulsing: > >progressbar.pulse() > >else: > >write_status("Done") > >window2.hide() > >return keep_pulsing > > > > def run_command(command): > >global keep_pulsing > >keep_pulsing=True > >textbuffer.set_text("") > >(cpid, cstdin, cstdout, cstderr) = > > > gobject.spawn_async(command,flags=gobject.SPAWN_DO_NOT_REAP_CHILD,standard_output=True) > >channel = os.fdopen(cstdout) > >gobject.io_add_watch(cstdout, gobject.IO_HUP|gobject.IO_IN, > > cstdout_callback, channel) > >gobject.timeout_add(150, update_progress_callback) > >window2.show() > > > > def get_active_text(combobox): > >model = combobox.get_model() > >active = combobox.get_active() > >if active < 0: > >return None > >return model[active][0] > > > > def build_timestamp(): > >year, month, day = calendar.get_date() > >hour = get_active_text(hourbox) > >month = "%02d" % mont
Re: [pygtk] Need help with spawn_async and callback
I should mention that my office is using RHEL5 ... so pygtk and associated are at the 2.10 version. On Wed, Sep 7, 2011 at 10:07 AM, Tony Freeman wrote: > Hello Grant, > > Below is the entire bit of code I was working on at that time. Pay > attention to the spawn_async stuff. Good luck! > > -- Tony > > > > #!/usr/bin/python > > > ## THIS IS A GUI FRONT END TO THE adjust_grids.sh > ## SCRIPT LOCATED IN /DATA/LOCAL/IFPS/ > ## > > > > ## SETUP THE ENVIRONMENT: > > > import pygtk > import gtk > import gtk.glade > import gobject > import os > > os.chdir("/awips/dev/localapps/adjust_grids/") > > > ### GLOBAL VARIABLES AND SITE CONFIGURATION: > > > import siteConfig > > xx = siteConfig.xx > guess = siteConfig.guess > program = siteConfig.program > > ### GLOBAL VARIABLES: > > keep_pulsing = True > > > ### PULL IN THE GUI: > > > wTree = gtk.glade.XML('adjust_grids.glade') > > ### MAIN WINDOW ITEMS (window1): > > calendar = wTree.get_widget('calendar1') > gridbox = wTree.get_widget('combobox_grid') > modelbox = wTree.get_widget('combobox_model') > hourbox = wTree.get_widget('combobox_hour') > statusbar = wTree.get_widget('label_status') > > ### PROGRESS WINDOW ITEMS (window2): > > window2 = wTree.get_widget('window2') > dialog1 = wTree.get_widget('dialog1') > > progressbar = wTree.get_widget('progressbar1') > progress_headline = wTree.get_widget('label_progress_headline') > progress_info = wTree.get_widget('label_progress_info') > > textview = wTree.get_widget('textview1') > textbuffer=textview.get_buffer() > > > ### FILL IN THE LIST BOXES: > > > for i in xx: > gridbox.append_text(i) > > for i in guess: > modelbox.append_text(i) > > gridbox.set_active(0) > modelbox.set_active(0) > hourbox.set_active(0) > > > ### DEFINE FUNCTIONS: > > > def write_status(comment): > statusbar.set_text(comment) > progress_info.set_text(comment) > > def cstdout_callback(fd, condition, channel): > global keep_pulsing > if condition == gobject.IO_HUP: > keep_pulsing=False > elif condition == gobject.IO_IN: > text = channel.readline() > iter = textbuffer.get_end_iter() > textbuffer.insert(iter, text) > textview.scroll_to_mark(textbuffer.get_insert(),0) > return keep_pulsing > > def update_progress_callback(): > global keep_pulsing > if keep_pulsing: > progressbar.pulse() > else: > write_status("Done") > window2.hide() > return keep_pulsing > > def run_command(command): > global keep_pulsing > keep_pulsing=True > textbuffer.set_text("") > (cpid, cstdin, cstdout, cstderr) = > gobject.spawn_async(command,flags=gobject.SPAWN_DO_NOT_REAP_CHILD,standard_output=True) > channel = os.fdopen(cstdout) > gobject.io_add_watch(cstdout, gobject.IO_HUP|gobject.IO_IN, > cstdout_callback, channel) > gobject.timeout_add(150, update_progress_callback) > window2.show() > > def get_active_text(combobox): > model = combobox.get_model() > active = combobox.get_active() > if active < 0: > return None > return model[active][0] > > def build_timestamp(): > year, month, day = calendar.get_date() > hour = get_active_text(hourbox) > month = "%02d" % month > day = "%02d" % day > timestamp = str(year) + str(month) + str(day) + "_" + str(hour) > return timestamp > > def on_dialog1_destroy(*args): > write_status("Backgrounded script") > dialog1.hide() > > def on_closebutton1_clicked(*args): > write_status("Backgrounded script") > dialog1.hide() > > def on_window1_destroy(*args): > write_status("Good-bye!") > gtk.main_quit() > > def on_window2_destroy(*args): > window2.hide() > dialog1.show() > write_status("Continuing in background") > return True > > def on_window2_delete_event(*args): > window2.hide() > dialog1.show() > write_status("Continuing in background") > return True > > def on_button_quit_clicked(*args): > write_status("See ya next time") > gtk.main_quit() > > def on_button_apply_clicked(*args): > scripttime = build_timestamp() > scriptmodel = get_activ
Re: [pygtk] Need help with spawn_async and callback
Hello Grant, Below is the entire bit of code I was working on at that time. Pay attention to the spawn_async stuff. Good luck! -- Tony #!/usr/bin/python ## THIS IS A GUI FRONT END TO THE adjust_grids.sh ## SCRIPT LOCATED IN /DATA/LOCAL/IFPS/ ## ## t0ny.fr33...@noaa.gov (26 July 2010) ## ## SETUP THE ENVIRONMENT: import pygtk import gtk import gtk.glade import gobject import os os.chdir("/awips/dev/localapps/adjust_grids/") ### GLOBAL VARIABLES AND SITE CONFIGURATION: import siteConfig xx = siteConfig.xx guess = siteConfig.guess program = siteConfig.program ### GLOBAL VARIABLES: keep_pulsing = True ### PULL IN THE GUI: wTree = gtk.glade.XML('adjust_grids.glade') ### MAIN WINDOW ITEMS (window1): calendar = wTree.get_widget('calendar1') gridbox = wTree.get_widget('combobox_grid') modelbox = wTree.get_widget('combobox_model') hourbox = wTree.get_widget('combobox_hour') statusbar = wTree.get_widget('label_status') ### PROGRESS WINDOW ITEMS (window2): window2 = wTree.get_widget('window2') dialog1 = wTree.get_widget('dialog1') progressbar = wTree.get_widget('progressbar1') progress_headline = wTree.get_widget('label_progress_headline') progress_info = wTree.get_widget('label_progress_info') textview = wTree.get_widget('textview1') textbuffer=textview.get_buffer() ### FILL IN THE LIST BOXES: for i in xx: gridbox.append_text(i) for i in guess: modelbox.append_text(i) gridbox.set_active(0) modelbox.set_active(0) hourbox.set_active(0) ### DEFINE FUNCTIONS: def write_status(comment): statusbar.set_text(comment) progress_info.set_text(comment) def cstdout_callback(fd, condition, channel): global keep_pulsing if condition == gobject.IO_HUP: keep_pulsing=False elif condition == gobject.IO_IN: text = channel.readline() iter = textbuffer.get_end_iter() textbuffer.insert(iter, text) textview.scroll_to_mark(textbuffer.get_insert(),0) return keep_pulsing def update_progress_callback(): global keep_pulsing if keep_pulsing: progressbar.pulse() else: write_status("Done") window2.hide() return keep_pulsing def run_command(command): global keep_pulsing keep_pulsing=True textbuffer.set_text("") (cpid, cstdin, cstdout, cstderr) = gobject.spawn_async(command,flags=gobject.SPAWN_DO_NOT_REAP_CHILD,standard_output=True) channel = os.fdopen(cstdout) gobject.io_add_watch(cstdout, gobject.IO_HUP|gobject.IO_IN, cstdout_callback, channel) gobject.timeout_add(150, update_progress_callback) window2.show() def get_active_text(combobox): model = combobox.get_model() active = combobox.get_active() if active < 0: return None return model[active][0] def build_timestamp(): year, month, day = calendar.get_date() hour = get_active_text(hourbox) month = "%02d" % month day = "%02d" % day timestamp = str(year) + str(month) + str(day) + "_" + str(hour) return timestamp def on_dialog1_destroy(*args): write_status("Backgrounded script") dialog1.hide() def on_closebutton1_clicked(*args): write_status("Backgrounded script") dialog1.hide() def on_window1_destroy(*args): write_status("Good-bye!") gtk.main_quit() def on_window2_destroy(*args): window2.hide() dialog1.show() write_status("Continuing in background") return True def on_window2_delete_event(*args): window2.hide() dialog1.show() write_status("Continuing in background") return True def on_button_quit_clicked(*args): write_status("See ya next time") gtk.main_quit() def on_button_apply_clicked(*args): scripttime = build_timestamp() scriptmodel = get_active_text(modelbox) scriptgrid = get_active_text(gridbox) command = [program, scriptgrid, scriptmodel, scripttime] write_status("Here we go ...") run_command(command) ### CONNECT SIGNALS TO OUR HANDLERS: wTree.signal_
Re: [pygtk] Need help with spawn_async and callback
Tony Freeman gmail.com> writes: Can you post the whole code anyway for those of us trying to figure out the same thing. ___ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/
Re: [pygtk] Need help with spawn_async and callback
Thanks Robert, It took a few days, but I finally figured out how to go about it. I needed to first create a 'channel' to the cstdout file descriptor intiger. Here's what I did initially to get thing working: import pygtk import gtk import gtk.glade import gobject import os import io keep_pulsing = True textview = wTree.get_widget('textview1') textbuffer=textview.get_buffer() def cstdout_callback(fd, condition, channel): global keep_pulsing if condition == gobject.IO_HUP: keep_pulsing=False elif condition == gobject.IO_IN: text = channel.readline() iter = textbuffer.get_end_iter() textbuffer.insert(iter, text) textview.scroll_to_mark(textbuffer.get_insert(),0) return keep_pulsing def update_progress_callback(): global keep_pulsing if keep_pulsing: progressbar.pulse() else: write_status("Done") window2.hide() return keep_pulsing def run_command(command): global keep_pulsing keep_pulsing=True textbuffer.set_text("") (cpid, cstdin, cstdout, cstderr) = gobject.spawn_async(command,flags=gobject.SPAWN_DO_NOT_REAP_CHILD,standard_output=True) channel = io.open(cstdout) gobject.io_add_watch(cstdout, gobject.IO_HUP|gobject.IO_IN, cstdout_callback, channel) gobject.timeout_add(150, update_progress_callback) window2.show() Then when I went to work I found that on my RHEL5 system I could not import io ... so after a while I discovered I could use fdopen to create the channel. All is well now ;-) I have things documented here: http://www.linuxquestions.org/questions/programming-9/pygtk-send-output-from-a-file-descriptor-to-a-textview-821595/#post4045253 -- Tony On Mon, Jul 26, 2010 at 8:02 PM, Robert Schroll wrote: > On 07/25/2010 08:46 PM, Tony Freeman wrote: > >> In short: What do I need to do in order to get the text being generated >> by my child process to show up in the textview? >> > > This doesn't answer your question, but have you considered running the > child inside a vte.Terminal? Faced with a similar problem, I created a > window containing a vte.Terminal and then used vte.Terminal.fork_command() > [1] to launch the child process. The terminal will emit the 'child-exited' > signal when the child exits (how convenient!), at which point I hide the > window. Hooking up the progress bar might be more difficult in this case, > though. > > Good luck, > Robert > > [1] As near as I can figure, fork_command() takes two arguments - the first > is the name of the command to run and the second is a list of arguments. > But the first element of this list must be the name of the command to run. > I'm sure a UNIX guru could explain why this is the only obvious way to do > things. > ___ > pygtk mailing list pygtk@daa.com.au > http://www.daa.com.au/mailman/listinfo/pygtk > Read the PyGTK FAQ: http://faq.pygtk.org/ > ___ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/
Re: [pygtk] Need help with spawn_async and callback
On 07/25/2010 08:46 PM, Tony Freeman wrote: In short: What do I need to do in order to get the text being generated by my child process to show up in the textview? This doesn't answer your question, but have you considered running the child inside a vte.Terminal? Faced with a similar problem, I created a window containing a vte.Terminal and then used vte.Terminal.fork_command() [1] to launch the child process. The terminal will emit the 'child-exited' signal when the child exits (how convenient!), at which point I hide the window. Hooking up the progress bar might be more difficult in this case, though. Good luck, Robert [1] As near as I can figure, fork_command() takes two arguments - the first is the name of the command to run and the second is a list of arguments. But the first element of this list must be the name of the command to run. I'm sure a UNIX guru could explain why this is the only obvious way to do things. ___ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/
[pygtk] Need help with spawn_async and callback
I hope someone can help me with this. Problem: I have a window widget (window2) that has a progress bar and a textview. I want to show the output of the child process that I launch inside the textview. Right now when I run the program, window2 pops up totally blank (no widgets displayed at all) but does indeed hide when the child process finishes. If I should comment out the io_watch_add line for gobject.IO_IN then window2 pops up nicely with a running progress bar and closes when the child process is finished. In short: What do I need to do in order to get the text being generated by my child process to show up in the textview? Here are the relevant parts of the script (let me know if I should post the entire script ... it's only 161 lines): import pygtk import gtk import gtk.glade import gobject import os import sys textview = wTree.get_widget('textview1') textbuffer=textview.get_buffer() keep_pulsing = True def cstdout_hup_callback(fd, condition): global keep_pulsing, textbuffer if condition == gobject.IO_HUP: keep_pulsing=False return keep_pulsing def cstdout_in_callback(fd, condition): global keep_pulsing, textbuffer if condition == gobject.IO_IN: #text = fd.read(1024) <-- this is not reading text from the fd. My workaround for now is below. text = "blah ... \n" iter = textbuffer.get_end_iter() textbuffer.insert(iter, text) return keep_pulsing def update_progress_callback(): global keep_pulsing if keep_pulsing: progressbar.pulse() else: write_status("Done") window2.hide() return keep_pulsing def run_command(command): global keep_pulsing keep_pulsing=True (cpid, cstdin, cstdout, cstderr) = gobject.spawn_async(command,flags=gobject.SPAWN_DO_NOT_REAP_CHILD,standard_output=True) gobject.timeout_add(150, update_progress_callback) gobject.io_add_watch(cstdout, gobject.IO_HUP, cstdout_hup_callback) gobject.io_add_watch(cstdout, gobject.IO_IN, cstdout_in_callback) window2.show() ___ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/