http://www.perlmonks.org?node_id=1029770

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

Update 2: I found the error - it was my error - the DatePickerCtrl was referring to the wrong panel. Still, for the benefit of PerlMonks users, I am attaching at the end a (correct, well-behaved) example of the same set of widgets, this time including the DatePickerCtrl.
I'd still say that wxPerl (and wxWidgets) are not forgiving - it's not for newbies. If you don't know what you're doing, you'll quickly get lost.
BTW, comments for improvement of style and quality are welcome.

Update 1: at the end of the post, I have attached an example of a set of well-behaved widgets and sizers. In a little while, I'll attach "update 2" with the problematic DatePickerCtrl.

Dear esteemed PerlMonks:

I am trying to use Wx::DatePickerCtrl, since it's useful and seems neat.

The problem is, it seems to crash the enveloping sizer.
For example, assume there is a window, with several widgets and buttons spread in it, positioned using sizers. The window is rendered fine.
When I replace a button, (or a text control, for example) with a Wx::DatePickerCtrl, it crashes the entire sizer, and the window looks garbled: all widgets get piled up on top of each other.

Same phenomenon with box sizers and/or FlexGridSizer.

I am posting this post initially without a code example, with the hope that there is a known issue (or fix), or maybe I am doing a "known missout". If necessary, I'll later add a code example - I have to extract it from a larger code base (and then make sure it works).

Many TIA - Helen

Update 1: Here is example 1: a well-behaved set of widgets and sizers

use strict; use warnings; use warnings qw< FATAL utf8 >; use Wx; use 5.014; use utf8; use autodie; use Carp; use Carp qw {cluck}; use Carp::Always; use Win32::Console; use English '-no_match_vars'; package MyForm; # ------------------------------------------------- +----------------- package MyForm:: use strict; use warnings; use Wx qw[:everything]; # easy when testing use Wx::Event qw(EVT_BUTTON EVT_LIST_CACHE_HINT EVT_CLOSE EVT_SIZE EVT +_MENU EVT_COMBOBOX EVT_UPDATE_UI EVT_TOOL_ENTER); use parent -norequire, 'Wx::Frame'; use Wx qw(:id :toolbar :statictext wxNullBitmap wxDefaultPosition wxDefaultSize wxNullBitmap wxTB_VERTICAL wxSIZE wxTE_MULTI +LINE wxBITMAP_TYPE_BMP); sub new { #1 --------------------------- new My +Form:: my $class = shift; my $self = $class->SUPER::new( undef, -1, # parent window; ID -1 means any 'Well-behaved widgets', # title wxDefaultPosition, wxDefaultSize, ); my ( $label1, $label2, $label3, $utext1, $utext2, $utext3, $sizer1 +, $sizer2, $sizer3, $sizer_main); my $panel = Wx::Panel->new( # Add a panel so it looks correc +t on all platforms $self, -1, # parent window, ID wxDefaultPosition, wxDefaultSize); $panel->SetBackgroundColour(Wx::Colour->new('light blue')); $label1 = Wx::StaticText->new($panel, -1, 'Label 1', [150, 250] +, wxDefaultSize, wxALIGN_CENTER); $label2 = Wx::StaticText->new($panel, -1, 'Label 2', [150, 250] +, wxDefaultSize, wxALIGN_CENTER); $label3 = Wx::StaticText->new($panel, -1, 'Label 3', [150, 250] +, wxDefaultSize, wxALIGN_CENTER); my @labels = ($label1, $label2, $label3); my $font = Wx::Font->new(13, -1, wxNORMAL, wxBOLD, 0, 'times new r +oman'); foreach (@labels) {$_->SetFont($font)}; my $btn1 = Wx::Button->new( $panel, -1, 'Button 1', wxDefaultPosit +ion, wxDefaultSize, ); my $btn2 = Wx::Button->new( $panel, -1, 'Button 2', wxDefaultPosit +ion, wxDefaultSize, ); my $btn3 = Wx::Button->new( $panel, -1, 'Button 3', wxDefaultPosit +ion, wxDefaultSize, ); $utext1 = Wx::TextCtrl->new($panel, -1, q{utext1} ); $utext2 = Wx::TextCtrl->new($panel, -1, q{utext2} ); $utext3 = Wx::TextCtrl->new($panel, -1, q{utext3} ); $sizer_main = Wx::BoxSizer->new(wxVERTICAL); $sizer1 = Wx::BoxSizer->new(wxHORIZONTAL); $sizer2 = Wx::BoxSizer->new(wxHORIZONTAL); $sizer3 = Wx::BoxSizer->new(wxHORIZONTAL); $sizer1 -> Add ( $btn1, 0, wxALL, 5 ); $sizer1 -> Add ( $label1, 0, wxALL, 5 ); $sizer1 -> Add ( $utext1, 0, wxALL, 5 ); $sizer2 -> Add ( $label2, 0); $sizer2 -> Add ( $utext2, 0, wxALL | wxEXPAND, 10); $sizer2 -> Add ( $btn2, 0, wxALL | wxEXPAND, 5); $sizer3 -> Add ( $utext3, 0); $sizer3 -> Add ( $btn3, 0, wxALL | wxEXPAND, 10); $sizer3 -> Add ( $label3, 0, wxALL | wxEXPAND, 5); $sizer_main->Add( $sizer1, 1, wxALL | wxEXPAND, 5 ); $sizer_main->Add( $sizer2, 1, wxALL | wxEXPAND, 5 ); $sizer_main->Add( $sizer3, 1, wxEXPAND); $panel->SetSizer($sizer_main); $sizer_main->Fit($self); $sizer_main->SetSizeHints($self); $panel->Fit; return $self; } #1 end sub new MyForm:: 1; # end package MyForm package main; # ------------------------------------------- +-------------------------- package main:: use strict; use warnings; use 5.014; use utf8; use autodie; use Carp; use Carp qw {cluck}; use Carp::Always; use Win32::Console; use English '-no_match_vars'; binmode(STDOUT, ':unix:utf8'); binmode $DB::OUT, ':unix:utf8' if $DB::OUT; # for the debugger Win32::Console::OutputCP(65001); # Set the console code p +age to UTF8 my $app = Wx::SimpleApp->new; my $frame = MyForm->new; $frame->Show(1); $app->MainLoop; 1;

Update 2: for the benefit of PerlMonks users: a (correct) example of the same set of widgets and sizers, this time with a DatePickerCtrl replacing the middle widget.

use strict; use warnings; use warnings qw< FATAL utf8 >; use Wx; use 5.014; use utf8; use autodie; use Carp; use Carp qw {cluck}; use Carp::Always; use Win32::Console; use English '-no_match_vars'; package MyForm; # ------------------------------------------------- +----------------- package MyForm:: use strict; use warnings; use Wx qw[:everything]; # easy when testing use Wx::Event qw(EVT_BUTTON EVT_LIST_CACHE_HINT EVT_CLOSE EVT_SIZE EVT +_MENU EVT_COMBOBOX EVT_UPDATE_UI EVT_TOOL_ENTER); use parent -norequire, 'Wx::Frame'; use Wx qw(:id :toolbar :statictext wxNullBitmap wxDefaultPosition wxDefaultSize wxNullBitmap wxTB_VERTICAL wxSIZE wxTE_MULTI +LINE wxBITMAP_TYPE_BMP); use Wx::DateTime; use Wx::Calendar; use Wx qw(:sizer :datepicker :misc); sub new { #1 --------------------------- new My +Form:: my $class = shift; my $self = $class->SUPER::new( undef, -1, # parent window; ID -1 means any 'Well-behaved widgets', # title wxDefaultPosition, wxDefaultSize, ); my ( $label1, $label2, $label3, $utext1, $utext2, $utext3, $sizer1 +, $sizer2, $sizer3, $sizer_main); my $panel = Wx::Panel->new( # Add a panel so it looks correc +t on all platforms $self, -1, # parent window, ID wxDefaultPosition, wxDefaultSize); $panel->SetBackgroundColour(Wx::Colour->new('light blue')); $label1 = Wx::StaticText->new($panel, -1, 'Label 1', [150, 250] +, wxDefaultSize, wxALIGN_CENTER); $label2 = Wx::StaticText->new($panel, -1, 'Label 2', [150, 250] +, wxDefaultSize, wxALIGN_CENTER); $label3 = Wx::StaticText->new($panel, -1, 'Label 3', [150, 250] +, wxDefaultSize, wxALIGN_CENTER); my @labels = ($label1, $label2, $label3); my $font = Wx::Font->new(13, -1, wxNORMAL, wxBOLD, 0, 'times new r +oman'); foreach (@labels) {$_->SetFont($font)}; my $btn1 = Wx::Button->new( $panel, -1, 'Button 1', wxDefaultPosit +ion, wxDefaultSize, ); my $btn2 = Wx::Button->new( $panel, -1, 'Button 2', wxDefaultPosit +ion, wxDefaultSize, ); my $btn3 = Wx::Button->new( $panel, -1, 'Button 3', wxDefaultPosit +ion, wxDefaultSize, ); $utext1 = Wx::TextCtrl->new($panel, -1, q{utext1} ); # $utext2 = Wx::TextCtrl->new($panel, -1, q{utext2} ); my $date_from = Wx::DateTime->new; my $date_ctrl = Wx::DatePickerCtrl->new( $panel, -1, $date_from, w +xDefaultPosition, + wxDefaultSize, wxDP_ALLOWNONE ); $utext3 = Wx::TextCtrl->new($panel, -1, q{utext3} ); $sizer_main = Wx::BoxSizer->new(wxVERTICAL); $sizer1 = Wx::BoxSizer->new(wxHORIZONTAL); $sizer2 = Wx::BoxSizer->new(wxHORIZONTAL); $sizer3 = Wx::BoxSizer->new(wxHORIZONTAL); $sizer1 -> Add ( $btn1, 0, wxALL, 5 ); $sizer1 -> Add ( $label1, 0, wxALL, 5 ); $sizer1 -> Add ( $utext1, 0, wxALL, 5 ); $sizer2 -> Add ( $label2, 0); $sizer2 -> Add ( $date_ctrl, 0, wxALL | wxEXPAND, 10); $sizer2 -> Add ( $btn2, 0, wxALL | wxEXPAND, 5); $sizer3 -> Add ( $utext3, 0); $sizer3 -> Add ( $btn3, 0, wxALL | wxEXPAND, 10); $sizer3 -> Add ( $label3, 0, wxALL | wxEXPAND, 5); $sizer_main->Add( $sizer1, 1, wxALL | wxEXPAND, 5 ); $sizer_main->Add( $sizer2, 1, wxALL | wxEXPAND, 5 ); $sizer_main->Add( $sizer3, 1, wxEXPAND); $panel->SetSizer($sizer_main); $sizer_main->Fit($self); $sizer_main->SetSizeHints($self); $panel->Fit; return $self; } #1 end sub new MyForm:: 1; # end package MyForm package main; # ------------------------------------------- +-------------------------- package main:: use strict; use warnings; use 5.014; use utf8; use autodie; use Carp; use Carp qw {cluck}; use Carp::Always; use Win32::Console; use English '-no_match_vars'; binmode(STDOUT, ':unix:utf8'); binmode $DB::OUT, ':unix:utf8' if $DB::OUT; # for the debugger Win32::Console::OutputCP(65001); # Set the console code p +age to UTF8 my $app = Wx::SimpleApp->new; my $frame = MyForm->new; $frame->Show(1); $app->MainLoop; 1;

Replies are listed 'Best First'.
Re: wxPerl: Wx::DatePickerCtrl crashes its sizer?
by Anonymous Monk on Apr 22, 2013 at 00:13 UTC

    I'd still say that wxPerl (and wxWidgets) are not forgiving - it's not for newbies. If you don't know what you're doing, you'll quickly get lost. BTW, comments for improvement of style and quality are welcome.

    The two are not unrelated. Naming your variables mainsizer,sizer1,sizer2,button1... is not the best way to keep track of what's what, or what goes where, its easy to get confused

    One way of keeping track (what goes where) is naming your sizer/container elements by position, and incorporating the parent/child relationship into the name. Afterwards you incorporate your action elements (text/buttons) and name then by purpose/property/action (email_input/email_text,submit_button,cancel_button... )

    Working incrementally on sub problems also helps , like separating the general layout from the rest of your program (in a separate file). Here is an example, generated with wxglade

    wxglade gui builder shows the parent/child relationships with a treectrl:), here's the corresponding wxg (wxglade xml)

      Thank you, AM. I'll study this, and comment.

      Helen