perltutorial
boo_radley
This is the second demonstration program I've written for [http://wxperl.sourceforge.net|wxperl]. Jouke mentioned that my last tutorial was better suited to someone familiar with wxperl than not, and I've tried to keep the same level of detail & explanation here.<br/>
This script shows how to load and display a file (in this case, a jpeg) into a bitmap control. I found that wxWindows' documentation was unclear on how image handlers interacted with image controls and bitmap controls, and it took a little under two hours to come up with the 9 (!) lines of code to complete the task. It also shows how to implement constraints to keep resized objects looking good.<br/>
You'll have to change the name of the file being loaded, but otherwise the script should load as-is.<br/>
<readmore>
<code>#!/usr/bin/perl
use Wx;
package MyApp;
#As always, we need to subclass Wx::App and populate it with a frame.
use strict;
use vars qw(@ISA);
@ISA=qw(Wx::App);
sub OnInit {
my $this = @_;
my $frame = MyFrame->new( "Mini-image demo", [-1,-1], [-1,-1]);
# if the frame didn't get created, exit early. don't use die here, as it seems to be a little unstable...
# if OnInit returns false,though, wx will clean up after itself nicely.
unless ($frame) {print "unable to create frame -- exiting."; return undef}
$frame->Show( 1 );
1; #everything's ok, on with the show.
}
package MyFrame;
# subclass wx::Frame to insert the image control.
use vars qw(@ISA);
use strict;
#
# All we load here are 2 constants used
# to keep the image stretched to the dimensions of the window.
#
use Wx qw( wxWidth wxHeight);
#
# Wx::Image loads the Image control and all of the Image handlers.
#
use Wx::Image;
use IO::File;
@ISA=qw(Wx::Frame);
sub new {
my $class = shift;
my $this = $class->SUPER::new( undef, -1, $_[0], $_[1], $_[2] );
#
# replace the filename with something appropriate.
#
my $file = IO::File->new( "c:/halo2.jpg", "r" ) or return undef;
binmode $file;
#
# define a handler for jpeg images.
# handlers are half of what translates file formats (.jpg in this case)
# into streams readable by wxBitmap objects for diplay.
# yes, this means you typically can't cram a file's contents into
# a wxBitmap control -- the exception being windows bitmaps.
#
# There is a method called 'Wx::Image::FindHandlerType', but I couldn't
# get the thing to work in any way, shape or form.
#
my $handler = Wx::JPEGHandler->new();
#
# wxImages are the other half of getting images displayed --
# they hold the data stream created by a handler.
# Although there's many functions that can be performed with an wxImage,
# all we're interested is turning the stream into a bitmap.
#
my $image = Wx::Image->new();
my $bmp; # used to hold the bitmap.
#
# here we load the file into $image. simple enough.
#
$handler->LoadFile( $image, $file );
#
# and here, we turn the data in $image into a bitmap, and store in $bmp.
# if the data in $bmp is bad for some reason, $bmp->Ok() will fail.
$bmp = $image->ConvertToBitmap();
if( $bmp->Ok() ) {
# create a static bitmap called ImageViewer that displays the
# selected image.
$this->{ImageViewer}= Wx::StaticBitmap->new($this, -1, $bmp);
}
# At this point, we could just return the frame, and be ok.
# unfortunately, the static bitmap could be *really* static and not
# resize itself when the window's resized, which'd look pretty ugly.
#
# To make sure everything looks ok, we'll assign constraints to
# Imageviewer.
# Layout constraints determine how controls will appear within the
# window. They consist of 4 members : left, top, width and height.
# constraints are objects by themselves, and need to be assigned to
# objects in order to have any use. We'll be using this contstraint
# in order to stretch the picture out to the full size of the window.
#
my $b1 = Wx::LayoutConstraints->new();
# set the upper left corner to absolute [0,0].
# if there were other controls using constraints, we could change these to
# something like $b1->left->RightOf ($widget, 5) to make this control appear
# 5 pixels to the right of $widget's constraints.
$b1->left->Absolute(0);
$b1->top->Absolute(0);
# now set the width and height to 100% each way.
$b1->width->PercentOf( $this, wxWidth,100);
$b1->height->PercentOf( $this, wxHeight, 100);
#
# Now that all the dimensions of the constraint are complete,
# assign it to ImageViewer.
#
$this->{ImageViewer}->SetConstraints( $b1 );
$this; # return the frame object to the calling application.
}
package main;
my $app = MyApp->new();# create an instance of the Wx::App-derived class
$app->MainLoop(); # run
</code>