On Thu, 13 Oct 2005, Shea Martin wrote: > I have a TK app. On a button presses, I call a windows copy command which > can take up to 10 minutes to run. In order to not freeze the GUI, so that the > gui can be doing other stuff, I launch the command in a thread. > > Running the command with system, does not let me get the output of the > command, thought it does not lock gui up at all. So, I tried two other > versions. I had the most success with version 3. I believe version 3 is what > the TkTextIo example uses in ruby 1.8.3. See below. > > # callback for tk button press > def buttonPress > Thread.new do > Button.state( "disable" ); > runCommand( "copy /Y bigfile1 dest1" ); > runCommand( "copy /Y bigfile2 dest2" ); > runCommand( "copy /Y bigfile3 dest3" ); > Button.state( "active" ); > end > end > > #version 1 > def runCommand( cmd ) > system( cmd ) > end > > #version 2 > def runCommand( cmd ) > IO.popen( cmd ) do | cmd_out | > cmd_out.each_line do | line | > MyTextArea.insert( 'end', line, 'normal' ) > end > end > end > > #version 3 > def runCommand( cmd ) > cmd_pipe = IO.popen( cmd ) > t = Thread.new { cmd_pipe.each{ | line | addText( line ) } } > t.join > end > > Only version 1 allows teh gui to remain responsive. Unfortunately it does > not capture the output of the copy command. I would like to something with a > fork, though win32 ruby does not seem to support it. > > Any ideas. > > Thanks, i just found this lying around - i thought i'd messed with it before - it runs unmodified and without blocking on *nix and win*: require "tk" thread_runner = lambda do Thread::new do pipe = IO::popen "ruby", "rb+" pipe.write <<-program STDERR.reopen STDOUT STDOUT.sync = true loop{ p [Process::pid, Time::now]; sleep 0.42 } program pipe.close_write pipe.each{|line| puts line} end end TkButton::new(nil, "text" => "start thread/process", "command" => thread_runner).pack( "fill" =>"x") TkButton::new(nil, "text" => "say hello", "command" => lambda{puts "HELLO"}).pack( "fill" =>"x") TkButton::new(nil, "text" => 'quit', "command" => lambda{exit}).pack("fill" => "x") Tk::mainloop with it you can start multiple threads reading pipes connected to multiple processes while the gui still responds. hth. -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | Your life dwells amoung the causes of death | Like a lamp standing in a strong breeze. --Nagarjuna ===============================================================================