Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

WxPerl woes -- putting a Tree into a ScrolledWindow

by SuperCruncher (Pilgrim)
on Mar 17, 2002 at 16:30 UTC ( #152323=perlquestion: print w/ replies, xml ) Need Help??
SuperCruncher has asked for the wisdom of the Perl Monks concerning the following question:

Perhaps rather unwisely, I decided to use wxPerl for my final year project. (Having said that, from the tutorial at YAPC::Europe 2001, Tk didn't look like a picnic either!). I started out trying to learn wxPerl by reading Jouke's Perl.com wxPerl tutorial, and that was good--but of course, I need a lot more. The only GUI programming I've done previously is *cough* VB *cough* and suffice it to say, a fully programmatic GUI like wxPerl is hugely different. I've looked at the various wxPerl tutorials on PerlMonks - wxPerl tutorial 3 --, wxPerl Tutorial one :: The basics, and while the former even describes trees (my main problem at the minute), it's not really in the right context.

Anyway, I am creating a music organiser application. The general design is that there will be variable-width "split" at the left hand side of the window which will display the user's music collection as a tree structure. At the minute, my program creates a window, menus and is split into two using Wx::SplitterWindow. Each of the split canvases is a Wx::ScrolledWindow.

Generally, I don't really understand how wxPerl operates. What I understand is that you must, at the very least, extend Wx::Frame and Wx::App and provide an OnInit method for Wx::App. That's fine, I can understand that, and I can understand wx's event model. I can understand creating menus, and that seems relatively straightforward.

What I don't understand is how to create other controls inside the different canvases. When I look at the documentation for the C++ version of wx, I see that when I create a control, I need to specify a parent. As far as I know, this can be any class derived from Wx::Window. However, some of the example wxPerl programs (from which I've learnt most of what I know about wx!) seem to suggest that objects derived from Wx::Window have a method called "add" or similar that can be used to add controls to windows or canvases. However, Wx::ScrolledWindow doesn't seem to support this.

In the code below, when I've created a tree, I've specified $lcanvas, a reference to the left hand canvas, as the parent. If I change this to $self (the window or frame?), the window isn't split properly and only a small rectangular region is displayed. So, my main questions are:

  • How can I add a tree to the left-hand part/canvas of the window?
  • How can I generally add controls to frames?
  • How can I create multiple frames for my application? How can I load and unload them?
#!/usr/bin/perl use strict; use Wx; package MyCanvas; use strict; use vars qw(@ISA); @ISA = qw(Wx::ScrolledWindow); sub new { my( $class ) = shift; my( $this ) = $class->SUPER::new( @_[0,1,2,3], 0, $_[4] ); return $this; } package MusicOrganiserSplitterWindow; use strict; use vars qw(@ISA); @ISA = qw(Wx::SplitterWindow); use Wx qw(:splitterwindow wxDefaultPosition wxDefaultSize); use Wx::Event qw(EVT_SPLITTER_SASH_POS_CHANGED); sub new { my( $class ) = shift; my( $this ) = $class->SUPER::new( @_, wxDefaultPosition, wxDefaultSi +ze, wxSP_3D|wxSP_LIVE_UPDATE ); $this->{FRAME} = $_[0]; return $this; } # Extend Wx's "Frame" class to create the main window. package MusicOrganiserFrame; use base qw(Wx::Frame); use Wx qw(wxOK wxICON_INFORMATION wxDefaultPosition wxDefaultSize); use Wx::Event qw(EVT_MENU); sub new { my $class = shift; my $self = $class->SUPER::new(@_); # Call superclass' constructor # Assign ID values my ($ID_MENU_FILE_REPORT, $ID_MENU_FILE_STATISTICS, $ID_MENU_EDIT_AD +D, $ID_MENU_EDIT_DELETE, $ID_MENU_TOOLS_SETUP, $ID_MENU_HELP_CONTEN +TS, $ID_MENU_HELP_ABOUT, $ID_MENU_FILE_EXIT) = (1 .. 100); # Create menu objects my $file_menu = Wx::Menu->new(); my $tools_menu = Wx::Menu->new(); my $edit_menu = Wx::Menu->new(); my $help_menu = Wx::Menu->new(); # Create File menu $file_menu->Append($ID_MENU_FILE_REPORT, "\&Report\tCtrl+R", "Produce reports about your collection."); $file_menu->Append($ID_MENU_FILE_STATISTICS, "\&Statistics\tCtrl+S", + "Display statistics for part or all of your collection."); $file_menu->AppendSeparator(); $file_menu->Append($ID_MENU_FILE_EXIT, "E\&xit\tCtrl+Q"); # Create Edit menu $edit_menu->Append($ID_MENU_EDIT_ADD, "\&Add volume", "Add a volume to your collection."); $edit_menu->Append($ID_MENU_EDIT_DELETE, "\&Delete volume", "Delete a volume from your collection."); # Create Tools menu $tools_menu->Append($ID_MENU_TOOLS_SETUP, "\&Setup", "Configure Music Organiser."); # Create Help menu $help_menu->Append($ID_MENU_HELP_CONTENTS, "\&Contents"); $help_menu->AppendSeparator(); $help_menu->Append($ID_MENU_HELP_ABOUT, "\&About"); # Create the menu bar that stores all the above menus my $menubar = Wx::MenuBar->new(); $menubar->Append($file_menu, '&File'); $menubar->Append($edit_menu, '&Edit'); $menubar->Append($tools_menu, '&Tools'); $menubar->Append($help_menu, '&Help'); $self->SetMenuBar($menubar); # Set up event handling for menu items. EVT_MENU($self, $ID_MENU_FILE_REPORT, \&OnMenu); # Set window icon $self->SetIcon(Wx::GetWxPerlIcon()); # Create status bar and assign values to the various segments $self->CreateStatusBar(3); $self->SetStatusText("Welcome to Music Organiser!", 1); $self->SetStatusText(scalar(gmtime), 2); my ($splitter) = $self->{SPLITTER} = MusicOrganiserSplitterWindow->new($self, -1); my ($lcanvas) = $self->{LEFTCANVAS} = MyCanvas->new($splitter, -1, [0,0], [400,40 +0], 'Test1'); my ($rcanvas) = $self->{RIGHTCANVAS} = MyCanvas->new($splitter, -1, [0,0], [400,4 +00], 'Test2'); $self->{TREE} = MusicOrganiserTree->new($lcanvas, -1, wxDefaultPosit +ion, wxDefaultSize, wxTR_HAS_BUTTONS); $self->{SPLITTER}->SetMinimumPaneSize(250); $splitter->Initialize($lcanvas); $self->{LEFTCANVAS}->Show( 1 ); $self->{RIGHTCANVAS}->Show( 1 ); $self->{SPLITTER}->SplitVertically( @{$self}{'LEFTCANVAS','RIGHTCANV +AS'} ); $self->{SPLITTER}->SetSashPosition(250,1); return $self; } sub OnMenu { Wx::MessageBox("Menu item selected", "Menu selected", wxOK | wxICON_INFORMATION, $_[0]); } package MusicOrganiserTree; use strict; use base qw(Wx::TreeCtrl); sub new { my $class = shift; my $this = $class->SUPER::new(@_); my $root = $this->AddRoot('Root', -1, -1, Wx::TreeItemData->new('Dat +a')); my $tree_item; $tree_item = $this->AppendItem($root, "Please work", -1, -1, Wx::TreeItemData->new("I really hope this works!")); } package MusicOrganiserApp; use base qw(Wx::App); sub OnInit { my $self = shift; my $frame = MusicOrganiserFrame->new( undef, # Parent window -1, # Window ID 'Music Organiser', # Window title [1, 1], # X, Y position [600, 300] # X, Y size ); $self->SetTopWindow($frame); # Set the top-level window. $frame->Show(1); # Show the frame. } package main; my $app = MusicOrganiserApp->new(); $app->MainLoop;

Comment on WxPerl woes -- putting a Tree into a ScrolledWindow
Download Code
Replies are listed 'Best First'.
Re: WxPerl woes -- putting a Tree into a ScrolledWindow
by Jouke (Curate) on Mar 18, 2002 at 13:55 UTC
    The main thing I'm missing (but that can be because of a copy-and-paste error on your side) is the definition of your 'MyCanvas' class.

    my ($lcanvas) = $self->{LEFTCANVAS} = MyCanvas->new($splitter, -1,[0, +0], [400,400],'Test1'); my ($rcanvas) = $self->{RIGHTCANVAS} = MyCanvas->new($splitter, -1,[ +0,0], [400,400],'Test2');
    You could also use a Wx::Panel instead of your MyCanvas, which is what I normally use to put controls on. That would result in something like this:
    my ($lcanvas) = $self->{LEFTCANVAS} = Wx::Panel->new($splitter, -1,[0 +,0], [400,400]); my ($rcanvas) = $self->{RIGHTCANVAS} = Wx::Panel->new($splitter, -1, +[0,0], [400,400]);

    update

    I see I overlooked the definition of your MyCanvas. I don't have any documentation nor wxPerl itself at hand where I am now, but I suspect something is going wrong in your new() definition of MyCanvas. But since you're not really adding anything to the Wx::ScrolledWindow Class here, I'd just use a Wx::ScrolledWindow directly instead of subclassing it (the only thing you seem to add is letting the caller omit 1 parameter). Try that and let me know if it works.
    Hope this helps

    Jouke Visser, Perl 'Adept'
    Using Perl to help the disabled: pVoice and pStory

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://152323]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (14)
As of 2015-07-30 14:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (271 votes), past polls