Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Best/Fast/Simple way to add a GUI to a batch process

by vitoco (Hermit)
on Aug 27, 2018 at 09:15 UTC ( [id://1221166]=perlquestion: print w/replies, xml ) Need Help??

vitoco has asked for the wisdom of the Perl Monks concerning the following question:

Hi!

I'm writing a simple batch process that performs a quite slow job using Perl in Windows. As always, it is a command line that requires a pair of files (a list and a template) to generate an output log while it interacts with another system.

The user wants an app with a window where he could type/select the required and the output files and control the status during the integration process. Which could be the best, fast and/or simple way to add a GUI to this script? Should I use WxPerl, Perl-Tk or whatever in my script or write wrapper using either them or any other language in Visual Studio?

I've never wrote a GUI for a script, so I want to do it simple... I don't have much time to learn a bunch of rules, may be just to modify some simple example.

Thank you!

  • Comment on Best/Fast/Simple way to add a GUI to a batch process

Replies are listed 'Best First'.
Re: Best/Fast/Simple way to add a GUI to a batch process
by zentara (Archbishop) on Aug 27, 2018 at 11:54 UTC
    I'm somewhat biased :-), but I would use Tk. Why? Because the coding is simpler, and the number of libraries needed is far less. Do a strace or ltrace on a Perl/Tk script, then on a Wx, Gtk, or Qt script, and you will see what I mean. Some toolkits load many 10's of un-needed libraires, just to display a window and a few widgets.

    As a quick solution, you could use Tk::ExecuteCommand, here is a fairly complete example.

    #!/usr/bin/perl use warnings; use strict; use Tk; use Tk::Pane; use Tk::ExecuteCommand; my %commands = ( #buttontext => command sleep => 'sleep 20', dir => 'dir', date => 'date', date1 => 'date; sleep 5; date;', ls => 'ls -la', users => 'cat /etc/passwd', who => 'who', whomai => 'whoami', ps => 'ps mauxww', top => 'top', cat_error => 'cat foobar' ); my $width = 90; my $height = 120; my $mw = MainWindow->new(); $mw->geometry($width.'x'.$height.'+100+100'); $mw->configure(-background => 'black'); $mw->Button(-text => 'Quit', -activebackground => 'red', -highlightbackground => 'yellow', -background => 'pink', -command=> sub{Tk::exit} )->pack; my $p = $mw->Scrolled('Pane', -scrollbars => 'oe',)->pack; foreach my $key (keys %commands){ $commands{'tl'}{$key} = $mw->Toplevel(-background => 'lightsteelblu +e'); $commands{'tl'}{$key}->title($key); $commands{'ec'}{$key} = $commands{'tl'}{$key}->ExecuteCommand( -background => 'lightsteelblue', -command => $commands{$key}, -entryWidth => 50, -height => 10, -label => '', -text => 'Execute', )->pack; my $t = $commands{'ec'}{$key}->Subwidget( 'text' ); # ROText widget $t->configure(-background => 'lightyellow'); my $f1 = $commands{'tl'}{$key}->Frame(-background => 'black') ->pack(-expand => 1, -fill => 'x'); $f1->Button(-text => "Clear", -activebackground => 'lightyellow', -highlightbackground => 'white', -background => 'yellow', -command => sub { $t->delete( '1.0' => 'end' ); })->pack(-side =>'left', -padx => 70); $f1->Button(-text => "Get Status", -activebackground => 'lightgrey', -highlightbackground => 'white', -background => 'grey', -command => sub { my @return = $commands{'ec'}{$key}->get_status; #Returns a 2 element array of $? and $! from last command execut +ion. $t->insert( 'end' => "\nStatus->\t\$?=$return[0]\t\$!=$return[1] +\n\n"); $t->see('end'); })->pack(-side =>'left', -padx => 70); $f1->Button(-text => "Close", -activebackground => 'hotpink', -highlightbackground => 'white', -background => 'pink', -command => sub { $commands{'tl'}{$key}->withdraw; $commands{'button'}{$key}-> configure(-state => 'normal'); })->pack(-side => 'right', -padx => 70); $commands{'tl'}{$key}->withdraw; $commands{'button'}{$key} = $p->Button(-text => $key, -background => 'lightyellow', -activebackground => 'yellow', -command=>[\&execute, $key, ] ) ->pack(-fill => 'x',-expand => 1,-pady => 1); } MainLoop; sub execute { my $key = shift; $commands{'button'}{$key}->configure(-state => 'disabled'); $commands{'tl'}{$key}->deiconify; $commands{'tl'}{$key}->raise; $commands{'ec'}{$key}->bell; $commands{'ec'}{$key}->update; }

    I'm not really a human, but I play one on earth. ..... an animated JAPH
Re: Best/Fast/Simple way to add a GUI to a batch process
by Lotus1 (Vicar) on Aug 27, 2018 at 19:59 UTC

    If simple dialog windows to choose the files and present Yes or No kinds of questions would work then the following is pretty quick and easy. Instead of choosing an output file this uses a Save As dialog to input the file name. You could write to a temporary file and then copy to the file named in the Save As dialog when finished.

    use strict; use warnings; use Win32::GUI(); use Win32; use Win32::FileOp qw(SaveAsDialog); my $startdir = 'C:\Users'; my $filename = Win32::GUI::GetOpenFileName( -title => 'Select a file' +, -directory => $startdir, -filter => ["Perl scripts (*.pl, *.pm)" => "*.pl;*.pm", "All files +" => "*.*", ],); if ($filename) { my $returnvalue = Win32::MsgBox("Use $filename ?",4,"Use it?"); if ($returnvalue == 6){ Win32::MsgBox("Using $filename as input."); } else{ Win32::MsgBox("Not using $filename as input."); } print "--- $filename\n"; } else { print "\$filename was not chosen by Win32::GUI::GetOpenfilename\n" +; exit; } my %parameters = ( title => "Output file", filters => {'Filter 1' => '*.txt;*.log', 'Filter 2' => '*.dat'}, filename => 'output.txt', ); my $output_file = SaveAsDialog %parameters , "output.txt"; if($output_file){ Win32::MsgBox("Using $output_file as output."); } else{ Win32::MsgBox("No output file chosen."); }

      To try this example, I had to install Win32, Win32::GUI and Win32::FileOp, but the last one failed like in Win32::FileOp issues and aborted. Argh!!!! Any hint? It seems that this module is not maintained anymore (Anyone wants to take over Win32::FileOp?).

      I'm thinking about to remove x64 version of Starwberry Perl from my Win10 machine and replace it with the 32 bits one...

        You can replace the Win32::FileOp part with the code below. I used several modules from whatever example code I found and quickly copy/pasted into my (Edit: original) reply. It was intended to show that there are a few options out there.

        I tested this on 64 bit Strawberry Perl. (Edit: My previous post was tested on 32 bit Strawberry Perl.)

        use strict; use warnings; use Win32::GUI(); my $startdir = 'C:\Users'; my $output_file = Win32::GUI::GetSaveFileName( -title => "Save as...", -directory => $startdir, -file => "output.txt", -filter => [ "Text documents (*.txt)" , "*.txt", "All files" , "*.*", ], ); if($output_file){ print("Using $output_file as output."); } else{ print("No output file chosen."); }

        I noticed that after I ran it once and chose a user directory it went to that same directory the next time. I assume it's a feature that it remembers. I found an option that seems to disable this kind of thing but haven't tried it. -nochangedir is 0 by default. It seems to be more to prevent the directory changing during the run so I'm surprised that the directory is remembered on the next run. Refer to http://perl-win32-gui.sourceforge.net/cgi-bin/docs.cgi?doc=Reference-Methods for more detail and other options.

        "I'm thinking about to remove x64 version of Starwberry Perl from my Win10 machine and replace it with the 32 bits one..."

        Re^4: Win32::FileOp issues includes "I'm using 32bit perl".

Re: Best/Fast/Simple way to add a GUI to a batch process
by zentara (Archbishop) on Aug 28, 2018 at 12:25 UTC
    Since you are just starting to get into making it easy to run remote commands, I feel obligated to point out that the best solution, although not a pure gui, is to use tmux. Google for many tutorials or see tmux intro.

    The nice thing about tmux, is that it will display correctly over a ssh connection, giving you a multipane window, each of which can run different commands. You can also easily put the commands in the background, detached, and come back hours later to reattach to it. A very professional approach. BTW, you can also run mc "Midnight Commander" over ssh, this comes in very handy, and between tmux and mc, you may have a simple, secure solution.


    I'm not really a human, but I play one on earth. ..... an animated JAPH

      I never said that I wanted to run remote commands. My script connects to a remote server and send messages to it based on the template and the listing files, while logging the results in a third file. The GUI is for a user who don't like command line utilities, and he will use this program in his Windows "server" (might be using Remote Desktop or directly in front of the machine, I don't care).

      But I like your idea. It could be fine if the user work in such environment, but this is not the case. He likes to run apps double-clicking on local icons from the desktop and expects windows to interact with them. The less configurations involved, the better.

Re: Best/Fast/Simple way to add a GUI to a batch process
by Laurent_R (Canon) on Aug 27, 2018 at 17:35 UTC
    I have only a very limited experience in terms of GUI, but it could be that the simplest solution would be a Web type of interface from a browser.

    This is just a suggestion, possibly a silly one, please other monks correct me if this is more complicated than I think.

      I second that.

      Basically the batch process communicates its progress via a local log file which the web interface via a simple cgi script reads and then formats the progress. I can also imagine killing the batch job via another cgi script. And spawning a batch job as well, after ticking some boxes on the web interface regarding options/preferences. The web interface can keep track of multiple batch jobs running, via their pid.

      The system could equally support 1 user running a single job on their private computer or several users who each logs in and checks their own batch jobs even remotely. Can also send email on certain events.

      Hi, there is no advantage to a web interface, which is quite insecure if you follow the news. What about the problem of cancelling a running program quickly? I wouldn't run any important program over a web interface. Why should your precious data output be filtered thru an apache module, or a browser filter?

      A console or even a Tk app can be run remotely via ssh with -X enabled. You have full control that way.

      <2 cents> Why not use a browser? Its not worth the bloat and risk. Just my opinion. P.S. If you do run it thru a browser be sure to use alot of javascript, so your browser can make umpteen network connections while you run your program. :-) Browsers are insecure, period. The various agencies have their backdoors in every browser. </2 cents>


      I'm not really a human, but I play one on earth. ..... an animated JAPH

      I would also second this, but unfortunatelly it is not an option. I cannot install neither perl nor a mini site in the server. :-(

Re: Best/Fast/Simple way to add a GUI to a batch process
by vitoco (Hermit) on Aug 27, 2018 at 20:34 UTC

    Thanks for the ideas. I'll take a look and try them.

    But I intenionally omited a bit of info: I cannot install perl in the destination server, so I'll use PAR to make an executable for the user. I think this would limit the options, or not?

    For instance, I made a fresh Strawberry x64 install in my notebook and then added WxPerl using cpan, which took me more than an hour to complete the makefile. Then I added PAR::Packer and it added Tk as a dependency!!! Why? And it also took almost another hour to complete!!!

    Finally, I tried to include Padre in my installation to see what can it do, but cpan couldn't finish the installation (I guess it is something related to x64 and DBM on Strawberry installs).

    Thank you again...

      Hi, if I were in your shoes, this would be my approach. If you can, run your app thru ssh. If your server has an X server, you can even run X apps thru ssh and it will be displayed on your local display. The problem most run into, is that most servers don't allow an X server to be run, because of system bloat and insecurities. This normally means that you will have to run your programs remotely as commandline via ssh. There are numerous examples on google. What you can then do, is use the Tk::ExecuteCommand example I showed on your local machine, but with ssh remote commands instead of local commands. I hope that makes sense. For example, see Net::SSH2::Channel Net::SSH2 Interactive command example and A little demo for Net::SSH2.

      Remember, unless your server has an X server running, which it probably dosn't, you won't be able to run any gui program. If you don't want to use Net::SSH2, you can always run (individual ssh with options) from a local Tk-ExecuteCommand gui. That way, you have your gui on your local machine, but run non-gui commands on the server you connect to.


      I'm not really a human, but I play one on earth. ..... an animated JAPH

        The OP described it as a Windows server so I assumed an RDP session is being used. Even if you aren't allowed to install things you can put a portable Perl folder such as from Strawberry Perl onto the server. This is the situation I work in with servers that are behind a firewall that doesn't allow web access. Most servers have an older version of ActiveState Perl that is required by a software application. I have a portable Perl folder that I have installed authentication email modules to on my personal workstation using CPAN. I can then deploy this folder to the servers so I can send authenticated emails. In the good old days I created install scripts to install modules on the ActiveState Perl in a particular order according to dependancies and hoped I didn't mess something up. It took me hours to deploy to multiple servers. Now I just give teammates a document describing how to copy the portable Perl folder and use portableshell.bat.

        Actually, the server doesn't need to have an X server. Properly configured, an application running on a server can use an X server running on a desktop (or laptop) PC. (Has been many years since I last did this, but as best I can determine, it it still possible.)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1221166]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2024-04-25 23:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found