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

Hello, I had 2 questions regarding below script:

- at line 47 I execute an external command. Why does the window close and the script end? The external command is executed though. Isn't there a way to keep my window open, preferable even in such a state I could try to run another external script simultaneously? I' a bit lost here, I hoped Proc::Simple would have helped me but that doesn't want to install under strawberry perl.

- is https://metacpan.org/pod/Wx::Perl::BrowseButton the answer to write this part more elegant "$inputfile = Win32::GUI::GetOpenFileName" ? (just yes or no is enough, I didn't investigate that part too much yet)

wkr, Luk
use strict; use warnings; use Wx; use Wx qw(wxOK wxCENTRE); use wxPerl::Constructors; package MyApp; use base 'Wx::App'; use Win32::GUI (); my $script = undef; my $inputfile = undef; my $outputfile = undef; sub OnInit { my $self = shift; my $frame = MyAppFrame->new(undef, -1, 'A wxPerl Application'); # my $frame = wxPerl::Frame->new(undef, 'A wxPerl Application'); $frame->SetMinSize([120,80]); my $menubar = Wx::MenuBar->new(); my $sizer = Wx::BoxSizer->new(&Wx::wxVERTICAL); my $button = wxPerl::Button->new($frame, 'Execute'); $sizer->Add($button, 2, &Wx::wxEXPAND); my $button3 = wxPerl::Button->new($frame, 'Select a script'); $sizer->Add($button3, 2, &Wx::wxEXPAND); my $button4 = wxPerl::Button->new($frame, 'Select an input file'); $sizer->Add($button4, 2, &Wx::wxEXPAND); my $button5 = wxPerl::Button->new($frame, 'Select an output file') +; $sizer->Add($button5, 2, &Wx::wxEXPAND); my $button2 = wxPerl::Button->new($frame, 'Close'); $sizer->Add($button2, 2, &Wx::wxEXPAND); # adding functinallity to the buttons Wx::Event::EVT_BUTTON($button, -1, sub { my ($b, $evt) = @_; my $cmd=undef; if ($script){ $cmd="\"$script\""; } else { Wx::MessageBox( "No script selected.", "Error!!!" ); }; if ($cmd){ if ($inputfile){$cmd .=" \"$inputfile\""}; if ($outputfile){$cmd .=" \"$outputfile\""}; print "$cmd\r\n"; exec ("perl $cmd") or print STDERR "couldn't exec $cmd: $! +"; } }); Wx::Event::EVT_BUTTON($button2, -1, sub { &Wx::wxTheApp->ExitMainLoop; }); my $i=0; Wx::Event::EVT_BUTTON($button3, -1, sub { my ($b, $evt) = @_; $script = Win32::GUI::GetOpenFileName(-filemustexist => 1,); if (defined $script) { $b->SetLabel("script: $script"); } else { $b->SetLabel('script unknown'); } }); Wx::Event::EVT_BUTTON($button4, -1, sub { my ($b, $evt) = @_; $inputfile = Win32::GUI::GetOpenFileName(-filemustexist => 1,) +; if (defined $inputfile) { $b->SetLabel("input: $inputfile"); } else { $b->SetLabel('input unknown'); } }); Wx::Event::EVT_BUTTON($button5, -1, sub { my ($b, $evt) = @_; $outputfile = Win32::GUI::GetOpenFileName(-filemustexist => 0, +); if (defined $outputfile) { $b->SetLabel("output: $outputfile"); } else { $b->SetLabel('output unknown'); } }); $frame->SetSizer($sizer); $frame->Show(1); $self->SetTopWindow($frame); return 1; } package MyAppFrame; use base qw(Wx::Frame); use Wx qw( wxDefaultPosition wxDefaultSize wxDefaultPosition wxDefaultSize wx +ID_EXIT ); use Wx::Event qw(EVT_MENU); our @id = (0 .. 100); sub new { my $class = shift; my $self = $class->SUPER::new( @_ ); # Create menus my $firstmenu = Wx::Menu->new(); $firstmenu->Append($id[0], "Normal Item"); $firstmenu->AppendCheckItem($id[1], "Check Item"); $firstmenu->AppendSeparator(); $firstmenu->AppendRadioItem($id[2], "Radio Item"); my $secmenu = Wx::Menu->new(); $secmenu->Append(wxID_EXIT, "Exit\tCtrl+X"); # my $submenu = Wx::Menu->new(); # $submenu->Append($id[4], "this is a test"); # $submenu->Enable($id[4],0); my $thirdmenu = Wx::Menu->new(); $thirdmenu->AppendRadioItem($id[3], "Radio Item"); # $thirdmenu->AppendSubMenu($id[100],"this is a test", $submenu); # Create menu bar my $menubar = Wx::MenuBar->new(); $menubar->Append($firstmenu, "First Menu"); $menubar->Append($secmenu, "Exit Menu"); $menubar->Append($thirdmenu, "Third Menu"); # Attach menubar to the window $self->SetMenuBar($menubar); $self->SetAutoLayout(1); # Handle events only for Exit and Normal item EVT_MENU( $self, $id[0], \&ShowDialog ); EVT_MENU( $self, wxID_EXIT, sub {$_[0]->Close(1)} ); return $self; } #start subroutines sub ShowDialog { my($self, $event) = @_; Wx::MessageBox( "This is a dialog", "Wx::MessageBox example", #wxOK|wxCENTRE, $self ); } #end subroutines # create the application object, this will call OnInit # before the constructor returns. package main; my($app) = MyApp->new(); # process GUI events from the application this function # will not return until the last frame is closed $app->MainLoop();

Replies are listed 'Best First'.
Re: some general question / Wx related question
by Fletch (Bishop) on Apr 16, 2020 at 18:54 UTC

    WRT your first question: when you use exec the current process is replaced with the new command (so your gui program disappears); you want system (or some wrapper thereof like IPC::Run) instead.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      thank you, works like a charm!

      this was the output when trying to execute a random txt file:

      "C:\perl\input.txt" Bareword found where operator expected at C:\perl\input.txt line 1, near "<Name>Softwares"

      I replaced it by just system ($cmd), didn't bother the "or die" part or in case of failure the window closes anyway :) https://perldoc.perl.org/functions/system.html the error is seen in my command prompt anyway.
Re: some general question / Wx related question
by Anonymous Monk on Apr 17, 2020 at 06:57 UTC

    - is https://metacpan.org/pod/Wx::Perl::BrowseButton the answer to write this part more elegant "$inputfile = Win32::GUI::GetOpenFileName" ? (just yes or no is enough, I didn't investigate that part too much yet)

    Hi. Direct equivalent is Wx::FileSelector()

    #!/usr/bin/perl -- use strict; use warnings; use Wx qw[ :everything ]; Main( @ARGV ); exit( 0 ); sub Main { my $frame = Wx::Frame->new( undef, -1, __FILE__ ); $frame->{text} = Wx::TextCtrl->new( $frame, -1, '', [ -1, -1 ], [ -1, -1 ], Wx::wxTE_MULTILINE() ); MakeMenuBar( $frame ); $frame->Show( 1 ); $frame->SetIcon( Wx::GetWxPerlIcon() ); ## to end Demo Wx::Event::EVT_CLOSE( $frame, sub { Wx::Exit() } ); Wx::SimpleApp->new->MainLoop; } sub MakeMenuBar { my( $frame ) = @_; my $bar = Wx::MenuBar->new; my $menu = Wx::Menu->new; Wx::Event::EVT_MENU( $frame, $menu->Append( -1, "&Demo!\tCtrl-D", "Launch Wx::Demo!" ), \&LaunchDemo ); Wx::Event::EVT_MENU( $frame, $menu->Append( -1, "&About!\tCtrl-A", "About BOX!" ), \&OnAbout ); $frame->{info} = Wx::AboutDialogInfo->new; $frame->{info}->AddDeveloper( 'Anonymous Monk' ); for my $letter ( qw/ B C/, 'E' .. 'I' ) { my $item = "&$letter$letter$letter \tCtrl-$letter"; my $id = Wx::NewId(); $menu->Append( $id, $item, ); Wx::Event::EVT_MENU( $frame, $id, \&SayWhat ); } Wx::Event::EVT_MENU( $frame, $menu->Append( -1, "&Open!\tCtrl-O", "Launch Wx::Demo!" ), \&GetOpenFileName, ); $bar->Append( $menu, "&Lively" ); my $submenu = Wx::Menu->new(); $submenu->Append( -1, "submenu A" ); $submenu->Append( -1, "submenu B" ); $submenu->AppendSeparator(); $submenu->Append( -1, "submenu C" ); $submenu->Append( -1, "submenu D" ); $submenu->AppendSeparator(); $submenu->Append( -1, "submenu E" ); $submenu->Append( -1, "submenu F" ); $menu->AppendSubMenu( $submenu, "&Submenu" ); Wx::Event::EVT_MENU( $frame, $_, \&SayWhat ) for $submenu->GetMenu +Items; $frame->SetMenuBar( $bar ); return $bar; } sub LaunchDemo { my( $frame, $event ) = @_; $frame->{text}->AppendText( join ' ', "In 3", "\n" ); SayWhat( @_ ); $frame->{text}->AppendText( join ' ', "In 2", "\n" ); require Wx::Demo; $frame->{text}->AppendText( join ' ', "In 1", "\n" ); $frame->{demo} ||= !! Wx::Demo->new; } sub SayWhat { my( $frame, $event ) = @_; my $id = $event->GetId; my $hi = $frame->GetMenuBar->GetLabel( $id ); $frame->{text}->AppendText( join ' ', $id, $hi, "\n" ); } sub GetOpenFileName { my( $frame, $event ) = @_; SayWhat( @_ ); $frame->{text}->AppendText( join "\n", Wx::FileSelector( '$message' ) , "\n" ); } sub OnAbout { my( $frame, $event ) = @_; Wx::AboutBox( $frame->{info} ); } __END__