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

Hello, I was trying to create some windows using perl and the WX lib. I've found the answer on how to get it working but i have no clue why. this is code I found online as example, this opens a window with a title bar:
use strict; use warnings; use Wx; use Wx qw(wxOK wxCENTRE); package WxPerlComExample; use base qw(Wx::App); sub OnInit { my $self = shift; my $frame = WxPerlComExampleFrame->new(undef, -1, "WxPerl Example" +); $frame->Show(1); $self->SetTopWindow($frame); return 1; } package WxPerlComExampleFrame; 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); # IDs array 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"); # Create menu bar my $menubar = Wx::MenuBar->new(); $menubar->Append($firstmenu, "First Menu"); $menubar->Append($secmenu, "Exit 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; } sub ShowDialog { my($self, $event) = @_; Wx::MessageBox( "This is a dialog", "Wx::MessageBox example", #wxOK|wxCENTRE, $self ); } package main; my($app) = WxPerlComExample->new(); $app->MainLoop();
now i also found some code which would open a window without a title bar but with some buttons. I wanted to integrate both.
use strict; use warnings; use Wx; use Wx qw(wxOK wxCENTRE); use wxPerl::Constructors; package MyApp; use base 'Wx::App'; use Win32::GUI (); 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, 'Click Me'); $sizer->Add($button, 2, &Wx::wxEXPAND); my $button3 = wxPerl::Button->new($frame, 'Maybe Click'); $sizer->Add($button3, 2, &Wx::wxEXPAND); my $button4 = wxPerl::Button->new($frame, 'select a file'); $sizer->Add($button4, 2, &Wx::wxEXPAND); my $button2 = wxPerl::Button->new($frame, 'Close'); $sizer->Add($button2, 2, &Wx::wxEXPAND); Wx::Event::EVT_BUTTON($button, -1, sub { my ($b, $evt) = @_; $b->SetLabel('Clicked'); $b->Disable; }); Wx::Event::EVT_BUTTON($button2, -1, sub { &Wx::wxTheApp->ExitMainLoop; }); my $i=0; Wx::Event::EVT_BUTTON($button3, -1, sub { my ($b, $evt) = @_; if ($i == 0){ $b->SetLabel('Maybe'); $i++; } else { $b->SetLabel('Maybe not'); $i--; } }); Wx::Event::EVT_BUTTON($button4, -1, sub { my ($b, $evt) = @_; my $file = Win32::GUI::GetOpenFileName(-filemustexist => 1,); if (defined $file) { $b->SetLabel("input: $file"); } else { $b->SetLabel('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"); # Create menu bar my $menubar = Wx::MenuBar->new(); $menubar->Append($firstmenu, "First Menu"); $menubar->Append($secmenu, "Exit 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; } sub ShowDialog { my($self, $event) = @_; Wx::MessageBox( "This is a dialog", "Wx::MessageBox example", #wxOK|wxCENTRE, $self ); } # 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();
It took me a while to figure out this was my error:
my $frame = MyAppFrame->new(undef, -1, 'A wxPerl Application'); # my $frame = wxPerl::Frame->new(undef, 'A wxPerl Application');
with the first line all works fine, with the 2nd the menubar will not appear, just a window with buttons... What is the difference??? Could someone try to explain me? wkr, Luk

Replies are listed 'Best First'.
Re: question about creating windows using WX module
by choroba (Cardinal) on Apr 15, 2020 at 14:07 UTC
    I don't know Wx, but the documentation of the WxFrame from which your class inherited states that its constructor takes the following parameters:
    (wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString& name = "frame" )

    For id, the documentation mentions the value -1:

    id
    The window identifier. It may take a value of -1 to indicate a default value.

    Calling a constructor of a different class with different arguments leads to different behaviour.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      thank you for yor quick response. btw, is this outdated information? https://www.perl.com/pub/2005/10/06/wxperl_menus.html/ I've been messing a bit further around with this but there's no way i can get a sub menu working...even if I follow the example exactly according to that website... (not that I'm using the menu yet, so don't care too much though)
        As I wrote earlier, I have no experience with Wx, I only tried Tk for GUI. To ask a new question, start a new question; and try to provide as much detail as possible (e.g. code that compiles and demonstrates the problem).

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: question about creating windows using WX module
by Anonymous Monk on Apr 16, 2020 at 07:22 UTC

    Hello, I was trying to create some windows using perl and the WX lib. I've found the answer on how to get it working but i have no clue why.

    this is code I found online as example, this opens a window with a title bar:

    ... code ...

    now i also found some code which would open a window without a title bar but with some buttons. I wanted to integrate both.

    ... code ...

    It took me a while to figure out this was my error:

    my $frame = MyAppFrame->new(undef, -1, 'A wxPerl Application'); # my $frame = wxPerl::Frame->new(undef, 'A wxPerl Application');

    with the first line all works fine, with the 2nd the menubar will not appear, just a window with buttons...

    What is the difference??? Could someone try to explain me? wkr, Luk

    Hi,

    Its simple

    Ask yourself

    How are a MyFrame and a wxPerl::Frame different?

     

    Wx::Event::EVT_BUTTON($button4, -1, sub { my ($b, $evt) = @_; my $file = Win32::GUI::GetOpenFileName

    Eww, you got some Win32::GUI in your Wx program :P