Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Wx::Panel not rendering

by japhy (Canon)
on Feb 09, 2005 at 23:34 UTC ( [id://429547]=perlquestion: print w/replies, xml ) Need Help??

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

Here's a simple program demonstrating the problem:
#!/usr/bin/perl use Wx; use warnings; package MyApp; use strict; use vars qw( @ISA ); @ISA = qw( Wx::App ); sub OnInit { my $self = shift; my $frame = MyFrame->new("Dungeon Construction Kit", [50,50], [450,3 +50]); $self->SetTopWindow($frame); $frame->Show( 1 ); 1; } package MyFrame; use strict; use vars qw( @ISA ); @ISA = qw( Wx::Frame ); sub new { my $class = shift; my ($title, $pts, $size) = @_; my $self = $class->SUPER::new( undef, -1, $title, Wx::Point->new(@$pts), Wx::Size->new(@$size), ); # create the menus my $menubar = Wx::MenuBar->new(); my $file_menu = Wx::Menu->new; my ($ID_MAKE_PANEL, $ID_EXIT) = 1 .. 1000; $file_menu->Append($ID_MAKE_PANEL, "&New\tCtrl+N", "Create a new pan +el"); $file_menu->Append($ID_EXIT, "E&xit\tCtrl+X", "Quit"); $menubar->Append($file_menu, "&File"); $self->SetMenuBar($menubar); use Wx::Event qw( EVT_MENU ); # uncomment the next line, and a panel is drawn # Wx::Panel->new($self); # when the "New" menu item is activated, a panel should render EVT_MENU($self, $ID_MAKE_PANEL, sub { Wx::Panel->new($self) }); EVT_MENU($self, $ID_EXIT, sub { $self->Close(1) }); $self; } package main; MyApp->new->MainLoop();
The problem is that the panel doesn't render. If, instead, I create the panel right away, it renders. I'm trying to create the panel only when the menu button is pushed.
_____________________________________________________
Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

Replies are listed 'Best First'.
Re: Wx::Panel not rendering
by tunaboy (Curate) on Feb 10, 2005 at 00:06 UTC
    OS: WinXP
    Perl: ActiveState 5.8.3 build 809
    wxPerl: 0.19

    With your original code if I minimise then maximise the window the panel appears. So my guess is the window needs to be redrawn for the panel to appear. I tried doing a $self->Refresh inside the menu callback but that did not work for me.

    I made the following changes to have it appear automatically:

    ... # when the "New" menu item is activated, a panel should render EVT_MENU($self, $ID_MAKE_PANEL, \&_make_panel ); EVT_MENU($self, $ID_EXIT, sub { $self->Close(1) }); $self; } sub _make_panel { my ( $self ) = @_; return if exists $self->{'panel'}; use Wx qw( wxVERTICAL wxGROW ); my $panel = Wx::Panel->new( $self, # parent -1, # id [ -1, -1 ], # position [ 200, 200 ] ); # size my $sizer = Wx::BoxSizer->new(wxVERTICAL); $sizer->Add( $panel, 1, wxGROW ); $self->SetSizer($sizer); $sizer->SetSizeHints($self); $self->{'panel'} = $panel; } ...

    Using the sizer to resize the window after the panel is created makes it appear for me. Of course the frame changes size as well which may not be what you are after.

    I am not sure if this is what you are after or if it helps at all.

Re: Wx::Panel not rendering
by PodMaster (Abbot) on Feb 10, 2005 at 06:34 UTC
    What you want to do is create ($foo) a panel (or a simple window) as a child of your frame, and then use it ($foo) as a parent for your dynamically created panel.

    I forget the exact reason why other than wxFrame is "special" :) If you really want to know you should ask on wx-users (http://lists.wxwidgets.org)

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Wx::Panel not rendering
by mattr (Curate) on Feb 10, 2005 at 18:06 UTC
    Hi,

    I took a swing at it. Probably you should really post to the wxperl-users list, see wxperl.sf.net. I took two tacks.

    First let me say this is exactly not how I use wxperl stylistically, and it kind of matters here. I use one module per file, don't do much in new(), override Wx modules to make my own, and (so far but this will change quickly) don't build panels on the fly. With the exception of a Wx::Gauge I added today which I Show and hide when done with it. I put my use statements all at the top and use Wx 0.15 qw[:everything]. Basically taking the time to eat through parts of the demo and reading wxwidgets docs and tutorials will be required.

    Okay. My theory was that it was working but there was nothing in the panel so you couldn't see it. When I added a text control I got Show to work (not really adding the panel at the last moment).

    Also added sizers which is standard way to add panels. (sizer in top frame, then panel in sizer in panel..)

    Finally I decided to just add one sizer to the frame, and build everything else at the last moment. This works, but I didn't get removal working (so I scrapped it). Also it will crash if you try to add the same one again. Anyway, the following should work. Caveat, I have done most Wx on windows recently but this I did on Linux. (Wx 0.15, wxWidgets 2.4.2). Note I also find App->Yield useful (not so important this time). Post to the list if you have more questions. So the key was to add something to see in the panel. Incidentally if you just use anonymous subs in new you can't do some things that require the object to exist first. So better to save all objects attached to the frame, and do it in separate subroutines.

    It really seemed flaky this way (things wouldn't erase or draw well, Show's boolean value seemed backwards, etc. When I tried to Destroy I would get segfaults, etc.). This was a big surprise because the past few weeks building a Wx app on Win98 has been quite pleasant and speedy, for example I got printing of a chart drawing done in just a day, etc. This tells me what you are going is not the way to do it. Basically I think you want XRC and I worked on this partly because I am going to do XRC soon. Recommend you check it out for building on the fly interfaces, tearing them up and presumably down (I couldn't tear down cleanly my first swing). But limited tear up using the below method should work I think. Also look at the demo, many modules are used. Just instantiate a module for an entire window when you need it.

    Anyway, here is the direct answer to what you requested, it just creates a panel with sizer and control in it, and adds the panel to the top sizer. Anybody with more experience at Wxperl please jump in! You can diff to see changes from your original. Good luck!

    #!/usr/bin/perl use warnings; use Wx 0.15 qw[:everything]; package MyApp; use strict; use vars qw( @ISA ); @ISA = qw( Wx::App ); sub OnInit { my $self = shift; my ($frame) = MyFrame->new("Dungeon Construction Kit", [50,50], [450 +,350]); $frame->{app} = $self; # the app instance, so we can Yield to GUI $self->SetTopWindow($frame); $frame->Show( 1 ); 1; } package MyFrame; #use strict; use vars qw( @ISA ); use Wx qw[:everything]; ##ADDED @ISA = qw( Wx::Frame ); sub new { my $class = shift; my ($title, $pts, $size) = @_; my $self = $class->SUPER::new( undef, -1, $title, Wx::Point->new(@$pts), Wx::Size->new(@$size), ); # create the menus my $menubar = Wx::MenuBar->new(); my $file_menu = Wx::Menu->new; my ($ID_MAKE_PANEL, $ID_HIDE_PANEL, $ID_EXIT) = 1 .. 1000; $file_menu->Append($ID_MAKE_PANEL, "&New\tCtrl+N", "Create a new pan +el"); $file_menu->Append($ID_EXIT, "E&xit\tCtrl+X", "Quit"); $menubar->Append($file_menu, "&File"); $self->SetMenuBar($menubar); use Wx::Event qw( EVT_MENU ); # put sizer for panel into the frame $self->{topsizer} = Wx::BoxSizer->new(wxEXPAND); $self->SetSizer($self->{topsizer}); EVT_MENU($self, $ID_MAKE_PANEL, \&MyFrame::showpan); EVT_MENU($self, $ID_EXIT, sub { $self->Close(1) }); $self; } sub showpan { my $self = shift; # Make a panel with a text control so we can see it. $self->{text} = Wx::TextCtrl->new($self,-1,"Test",wxDefaultPosition, +wxDefaultSize) unless $self->{text}; $self->{textsizer} = Wx::BoxSizer->new(wxVERTICAL) unless $self->{te +xtsizer}; $self->{textsizer}->Add($self->{text},1,wxLEFT,2); $self->{panel} = Wx::Panel->new($self) unless $self->{panel}; $self->{panel}->SetSizer($self->{textsizer}); # attach text sizer to + panel # Add panel to frame's sizer $self->{topsizer}->Add($self->{panel},1,wxEXPAND|wxALL,2); $self->{topsizer}->Layout; $self->{panel}->Show(0); } package main; MyApp->new->MainLoop();

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2024-04-16 16:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found