in reply to How to perform a subroutine run in cpan Tk::ExecuteCommand module

I'll need to perform a series of tasks within a subroutine,

It seems you are trying to make Tk::ExecuteCommand do more than what it was intended for. The easiest way to solve your problem, would be to put all the commands you wish to run, in a separate shell(bash) script, then use ExecuteCommand to execute the shell script. You could even put it all into a second Perl script, if it was easier.

The other alternative is to roll-your-own Tk execute script, for example:

#!/usr/bin/perl use warnings; use strict; use Tk; use IPC::Open3; require Tk::ROText; $|=1; my $mw = new MainWindow; my $entry=$mw->Entry(-width => 80)->pack; $mw->Button(-text => 'Execute', -command => \&send_to_shell)->pack; my $textwin =$mw->Scrolled('ROText', -width => 80, -bg =>'white', -height => 24, )->pack; $textwin->tagConfigure( 'err', -foreground => 'red' ); my $pid = open3( \*IN, \*OUT, \*ERR, '/bin/bash' ) or warn "$!\n"; $mw->fileevent( \*OUT, readable => \&read_stdout ); $mw->fileevent( \*ERR, readable => \&read_stderr ); $entry->bind('<Return>',[\&send_to_shell]); $entry->focus; MainLoop; sub read_stdout { if( sysread( OUT, my $buffer, 1024 ) > 0 ){ $textwin->insert( 'end', $buffer ); $textwin->see('end'); } } sub read_stderr { if( sysread(ERR, my $buffer, 1024 ) > 0 ){ $textwin->insert( 'end', $buffer, 'err' ); $textwin->see('end'); } } sub send_to_shell { my $cmd= $entry->get(); print IN "$cmd\n"; }
You can modify this code to do what you need or want. Instead of getting your commands from the Entry, you could read it from a subroutine.

Post a fully working example if you need more help.

P.S.
Tk::ExecuteCommand could be used as you desire, by using configure to load different commands from your subroutine.

# in your subroutine $ec->configure( -command => $choice ); $ec->execute_command;

I'm not really a human, but I play one on earth.
Old Perl Programmer Haiku ................... flash japh

Replies are listed 'Best First'.
Re^2: How to perform a subroutine run in cpan Tk::ExecuteCommand module
by Janish (Sexton) on Jun 26, 2014 at 01:38 UTC

    Thank you Zentara, I have read similar code as you posted and tried the code before I posted this question. The script work fine except for 2 things:-

    i.The button freeze once it is hitted, and there is no way to kill the ongoing job.

    ii.The entry seem only capture first single word from the command line to show in the text widget, I need the whole command line to be prompt.

    Is there any solution fto fix above 2 problems, I don't mind switching to this method if they can achieve my 2 objectives below:-

    i. To show the state of the command within the text widget.

    ii. There is a way to cancel the ongoing process.

    I chosen Tk::ExecuteCommand as it is non-blocking and the button is tactfully turn to "cancel" when a job is running so that user could have chance to cancel an ongoing job.

      To add on, is there a way to call subroutine in Tk::ExecuteCOmmand instead of calling a single liner command?

      To add on, is there a way to call subroutine in Tk::ExecuteCOmmand instead of calling a single liner command?

Re^2: How to perform a subroutine run in cpan Tk::ExecuteCommand module
by Janish (Sexton) on Jun 26, 2014 at 08:26 UTC

    Hi Zentara, I tried to apply your hint of can use the configure command every where finally enable my output result shown on the text widget. Thank you! Though there's seem to have the extra entry and button in the form, but it at least solve my problem on showing test in the widget. However is there a way to print plain font to the text widget in Tk::ExecuteCommand say if I don't want to set a couple of mini scripts for simple info message? I tried to print this to the text widget, but it execute like treating it as a script, complaining missing file or directory but it is in fact it is just a pure info text to user.

    My code as below

    my $first_line = "Start running project 1...please wait"; $ec_pc->configure(-command=> $first_line); $ec_pc->execute_command; $ec_pc->update;

    And, below is what is shown within the test widget:

    'Start running project 1...please wait' : No such file or directory
      is there a way to print plain font to the text widget in Tk::ExecuteCommand say if I don't want to set a couple of mini scripts for simple info message? ....
      'Start running project 1...please wait' : No such file or directory

      You have a serious misunderstanding of what is going on. Tk::ExecuteCommand is designed to do just that .... execute a command , which means sending a valid command to a shell to be run. What you want to do is just plainly run some perl code and have it's output in the Text widget.

      For the question of killing a running command, make another button labeled 'Stop', and use Tk::ExecuteCommand's $exec->kill_command;

      my $kill_button = $mw->Button( -text => 'Stop', -command=> sub{ $exec->kill_command; } )->pack();

      As to your other problem of sending plain text messages to the Text Widget, instead of a command, you will need to figure out a way in your subroutine of determining if you have a valid command, or just an informational message. If it's an information message, you can write it directly into the ROText subwidget like the following:

      #!/usr/bin/perl use Tk; use Tk::ExecuteCommand; my $mw = MainWindow->new; $ec = $mw->ExecuteCommand( -command => '', -entryWidth => 50, -height => 10, -label => '', -text => 'Execute', )->pack; $ec->configure( -command => 'dir' ); $ec->execute_command; $ec->bell; $ec->update; # read perldoc Tk::ExecuteCommand for the Advertised Widget section my $ROText = $ec->Subwidget('text'); print "$ROText\n"; $ROText->configure(-bg=>'white'); $ROText->insert('end', "\n\nHi, this is a message\n\n"); $ROText->see('end'); #execute some perl code and output it to the text widget &do_something; MainLoop; sub do_something{ # the Tk::ExecuteCommand kill button won't stop this for (1..5){ $ROText->insert('end', "$_\n"); $ROText->see('end'); } }

      I'm not really a human, but I play one on earth.
      Old Perl Programmer Haiku ................... flash japh

        Hi Zentara, I couldn't help to express my thankfulness to you, your explanation and sample codes did help me to clear my doubts and misunderstanding on all those that I found by googling, which bothering me since the past weeks. Now I'm much clearer on the usage and how to apply both the ROText and ExecuteCommand in my codes. Yeah.. the explanation with sample codes means a lot! ALso, not forget to thanks all those who take the trouble on replying to me- Corion and RonW. I'm so excited to implement that in my real code now! Thanks a bunch!

        Hi Zentara, I have one extra question regarding the text widget gui, is that possible to change the vertical scrollbar to the right hand side instead of current position on the left sided.