The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
=head1 NAME

Creating a PerlQt application - The Perl part

=head1 DESCRIPTION

PerlQt is meant to be a very direct mapping of Qt methods to PerlQt.
Programming is more than methods, however. This document will show the
basic differences you will need to be aware of as you translate
programming techniques from C++ Qt to PerlQt.

=head1 BASICS

=head2 Including PerlQt in your application

Including PerlQt is very simple. The top of almost every PerlQt
application will be the same.

    #!/usr/bin/perl -w
    use Qt;
    import Qt::app;

=over 4

=item #!/usr/bin/perl -w

This the #! business which starts Perl on your system. I always recommend
using the B<-w> option, because relying on PerlQt to find your errors will
leave you stranded. If you intend to distribute your app, make sure it
uses F</usr/bin/perl> as the path for B<perl>.

=item use Qt;

This causes the PerlQt module to be loaded and the Qt library to be linked
to Perl. From that line on, you can call any PerlQt method or access any
PerlQt constant.

=item import Qt::app;

This line imports the $app variable into your namespace. The $app variable
is equivalent to the C<qApp> variable in Qt. In PerlQt, C<qApp> is stored
as C<$Qt::app>.

The reason we C<import Qt::app> instead of using $Qt::app directly is
that C<import Qt::app> will create $Qt::app if it does not already
exist.

The reason we C<import> instead of C<use Qt::app> is to allow the creation
of modules which subclass C<Qt::Application> and create $Qt::app, without
worrying about coding order.

If you want to create your own C<$Qt::app>, this is how you do it.

    use Qt;
    BEGIN { $Qt::app = Qt::Application->new(\@ARGV) }
    import Qt::app;

=back

=head2 Creating objects

Now that we have included PerlQt into our program, we can call any Qt
method we want. Since most of the methods require an object, it would help
if we created one.

    $widget = Qt::Widget->new;

Please note that every class in Qt has had it's initial Q replaced with
Qt:: (C<QWidget> => C<Qt::Widget>).

In Perl, C<new> is a method, and C<Qt::Widget>, the class, can be treated
as an object. It's weird, but it works. However, if you're inclined, you
are also allowed to use more C++-compatible syntax.

    $widget = new Qt::Widget;

I use the first way just to show a good example, since the second can lead
to ambiguous function-calls under bizzare circumstances.

=head2 Calling methods

At this point, we want to call methods on our $widget. I'm going to resize
this widget a few times, demonstrating the old perl motto that There Is
More Than One Way To Do It.

    $widget->resize(100, 100);
    resize $widget 100, 100;    # Yes, this works
    $widget->resize(Qt::Size->new(100, 100));
    $widget->resize(new Qt::Size(100, 100));

I chose this example in particular because it demonstrates a few important
principals.

=over 4

=item $widget->resize(100, 100);

This is a standard method-call in perl. Parentheses are required on
methods called with C<-E<gt>> that are called with arguments. On methods
without arguments, no parentheses are required. That allows you to access
object attributes easily with code like C<$widget-E<gt>size> instead of
C<$widget-E<gt>size()> if that strikes your fancy.

=item resize $widget 100, 100;

I admit this is weird, and could start looking like tcl after a while.
It's interesting and perfectly valid, though. It would also make for an
good graphical IRC client interface.

=item $widget->resize(Qt::Size->new(100, 100));

If you look at the Qt documentation, C<QWidget::resize> has two
prototypes.

    virtual void resize ( int w, int h )
    void resize ( const QSize & )

The C<QSize> class is supported in PerlQt. We created a new Qt::Size
object, and passed it to C<resize>. The C<resize> function saw that it was
passed one C<Qt::Size> instead of two numbers, and called the C<resize>
function that accepts C<const QSize &>.

=item $widget->resize(new Qt::Size(100, 100));

You can also use a more C++-like syntax. In C++ however, you would never
allocate a new QSize object and pass it to C<resize> since that would
leak memory. In PerlQt, that object will be deleted automatically when
the function returns. See L<Object destruction>

=back

=head1 SUBCLASSING

In order to add functionality to your program, it is often a good idea to
subclass a Qt widget. If you want to create a custom dialog-based program,
you would subclass C<Qt::Dialog>. If you wanted to write PerlExcel, you
would subclass C<Qt::TableView>. By subclassing, you gain all the
functionality of the class you inherit, and can change that functionality
by overriding virtual methods from that class.

=head2 Creating a class

In Perl, classes are known as packages, because they are declared with the
keyword C<package>. In reality, C<package> creates a namespace into which
you place your methods, and it is through some perl magic that it gains
object-oriented status. I prefer calling them classes nonetheless.

There are two ways to define your class. You can define it in its own file
"F<MyClass.pm>" and C<use> it in your application, or you can define it in
the main application file.

This is a class defined in F<MyClass.pm> which inherits Qt::Widget:

    package MyClass;
    use Qt;
    @ISA = qw(Qt::Widget);

    # your code here
    1;

The C<1> at the end of the file is required by Perl, and must be at the
end of the file. To use that class from your application, add
C<use MyClass> to your application after C<use Qt>.

This is a class defined in the main application file which inherits
Qt::Dialog:

    package MyClass;
    @ISA = qw(Qt::Dialog);

    # your code here
    package main;

The C<package main> does the reverse of C<package MyClass> and puts you
into the global namespace with normal variable access again.

=over 4

=item *

I<Note:> variables declared at the class level with C<my()> will be
visible from all classes in a file, but not outside a file.

=back

That was it, you now have a class called C<MyClass> into which you can
write some code.

=head2 Constructor

In Perl, the constructor is a method called C<new>. There is some
tradition for using C<$self> in Perl as the equivalent to C<this> in C++,
and that's what I will demonstrate. This is I<not> required, and you are
free to call it C<$this>, C<$that>, or C<$my_special_friend>.

    sub new {
	my $self = shift->SUPER::new(@_);
	# your constructor code here
	return $self;
    }

The first line of the constructor allows PerlQt to create your object.
The one I've shown you passes all the arguments to your constructor to the
superclass constructor. If you want to hide some of those arguments from
your superclass and use them yourself, this is what you need to do:

    sub new {
	my $class = shift;
	my $argument = shift;  # repeat for each argument
	my $self = $class->SUPER::new($class, @_);
	# your constructor code here
	return $self;
    }

If you don't want to pass the arguments passed to you to your superclass,
omit C<@_> and replace it with your own arguments. Every constructor must
C<return $self> in order to work. The variable C<$self> and the function
C<&new> have no special signifigance to Perl, so there is no reason for
Perl to do that for you. Your constructor must return the object it
created.

If you want to create a destructor, create a method called DESTROY, and
put your destruction code in it. You usually don't need a destructor,
because Perl and Qt automatically deallocate everything associated with
your object when it's destroyed.

=head2 The object

When you call C<&SUPER::new>, you are calling your superclass constructor.
If you use multiple-inheritance, it will call C<$ISA[0]-E<gt>new>.
Your superclass constructor will create the C++ version of itself, and
return a blessed perl hash reference. You cannot inherit two Qt classes
properly, since C<$self> can only represent one Qt object at a time.

All objects in Perl are blessed references. Blessed means it represents a
package and methods can be called on it. References are Perl pointers,
and can refer to a variable or function. In this case, it refers to a perl
associated list, or hash. This allows us to have named member-variables.

    sub new {
	my $self = shift->SUPER::new(@_);
	$self->{button} = Qt::PushButton->new("OK", $self);
	return $self;
    }

We have saved a pushbutton in C<$self-E<gt>{button}>.

=head2 Virtual methods

A large part of the Qt API involves overriding virtual methods. When a
widget is resized or hidden, Qt calls a virtual method on your object.
If you've reimplemented that virtual method, you get the opportunity to
respond to that event.

PerlQt allows you to override Qt virtual functions. The C<resizeEvent>
method is called whenever a widget is resized.

    sub resizeEvent {
	my $self = shift;
	my $e = shift;

	printf "Old size: %s, %s\n",
	    $e->oldSize->x, $e->oldSize->y;
	printf "Current size: %s, %s\n",
	    $self->size->x, $self->size->y;

	$self->SUPER::resizeEvent($e);
    }

That reimplementation of C<resizeEvent> prints out the old widget size and
the current widget size. It also calls the superclass C<resizeEvent> since
our implementation didn't actually do anything useful.

=head2 Declaring signals and slots

The Qt callback mechanism is called signals and slots. It is a way for
objects to communicate with each other. When a button is pushed, it emits
a signal called C<clicked()>. If you want to know when the button is
pushed, you create a slot and connect the C<clicked()> signal to it.
To see how C<connect()> works in PerlQt, read L<Signals and slots>.

Slots are just normal methods which have been registered with Qt.
Signals are methods created by PerlQt and given the name you specify.
When you C<emit> (call) that signal, every slot connected to it gets
called.

When you create a class, you will need to create slots to pick up signals
such as C<clicked()> from Qt::PushButton, and C<returnPressed()> from
Qt::LineEdit. You can also choose to emit signals, so other classes can
be told what you are doing.

    use Qt::slots 'buttonWasClicked()',
                  'returnWasPressed()';
    use Qt::signals 'somethingHappened()';

That declares two slots, which you can implement in your class, and a
signal which can be connected to slots in C++ or Perl.

    sub buttonWasClicked {
	my $self = shift;   # you can use $self
	# lets emit a signal
	emit $self->somethingHappened;
    }

    sub returnWasPressed {
	my $self = shift;   # you can use $self
	# your code here
	emit $self->somethingHappened;
    }

The C<emit> keyword does nothing, it's syntactic sugar to make it clear
you are emitting a signal.

Signals and slots can have arguments. PerlQt limits signals and slots
created by Perl to three arguments. See L<Signals and slots>.

=head1 WORKING IN PERL

Right off the bat, Perl eliminates pointers and references. That makes for
a great deal of simplification. Also, Perl has garbage collection which
means it will automatically free memory for a variable when it's no-longer
needed. That eliminates the need for destructors usually.

=head2 Constants

Global constants in C++ Qt, like C<AlignLeft>, are accessed as
C<Qt::AlignLeft> in PerlQt. They are constant functions, not variables.
Class constants like C<QScrollBar::Vertical> are predictably accessed as
C<Qt::ScrollBar::Vertical> in PerlQt.

Please note that if you inherit a class that has a constant, you must
still use its fully-qualified name. Perl does not allow function
inheritance like that. Of course, you could always try calling it as a
method and use method inheritance (C<$scrollbar-E<gt>Vertical>).

=head2 NULL pointer

PerlQt supports two-way C<NULL> pointer conversion to C<undef>. If you
pass C<undef> to a function accepting a pointer argument, that function
receives a C<NULL> pointer. If a function returns a C<NULL> pointer, Perl
receives C<undef>.

=head2 Object destruction

There are several types of objects in PerlQt when it comes to object
destruction.

There are the normal objects, which need to be destroyed when
their Perl variable is destroyed.

Widgets are destroyed by their parent. I call this behavior suicidal,
because these objects will delete themselves even if I lose track of them.
The perl variable for these objects can be destroyed, but the C++ object
will still be there. It is important that these objects have been given a
parent or have been added to an object which will destroy them from C++.

Virtual objects are from classes which have been implemented in PerlQt
with virtual functions. These objects keep a reference to the Perl object,
so that even if you, the programmer, have destroyed every reference to the
object you can find, PerlQt still keeps one which you cannot get rid of.
A virtual object must either delete itself, or be suicidal in order for it
to be destroyed.

Every object in PerlQt has three methods to handle object destruction.

=over 4

=item $object->delete

This calls the C++ delete operator on the object pointer, and causes
immediate object destruction.

=item $object->continue

An object that would normally be deleted at the end of a method can be
told to stick around with C<continue>. If you pass an object
created in Perl to a method which deletes that variable, you must call
C<continue> to stop PerlQt from deleting it.

=item $object->break

If you create a suicidal object like a dialog box, and don't give it a
parent which will destroy it, you can make it get deleted when Perl
destroys its object with C<break>.

=back

=head2 Signals and slots

PerlQt allows programmers to create signals and slots in Perl which are
usable from Perl and C++. If your subclass inherits C<Qt::Object>, PerlQt
will automatically do the C<Q_OBJECT> voodoo which Qt does, and you don't
have to worry about any of that.

The SIGNAL() and SLOT() macros in C++ are replaced with simple quotes in
PerlQt.

In C++:
    QObject::connect(sender, SIGNAL(didSomething(int)),
                     receiver, SLOT(sawSomething(int)));

In PerlQt:
    $receiver->connect($sender, 'didSomething(int)',
                       'sawSomething(int)');

Now, there are a multitude of argument-types which can be passed through a
signal, and here is a short translation

=over 4

=item SLOT(member(Object))

Sorry, you cannot connect to a signal or slot that sends an object by
value.

=item SLOT(member(Object *))

'member(Object)'

=item SLOT(member(const Object *))

'member(const Object)'

=item SLOT(member(Object &))

'member(\Object)'

=item SLOT(member(const Object &))

'member(const \Object)'

=item SLOT(member(int, long, double))

'member(int, long, double)'

=item SLOT(member(const char *))

'member(const string)'
OR
'member(cstring)'

=item SLOT(member(const QString &))

'member(const \QString)'

=item SLOT(member(const QString *))

'member(const QString)'

=item SLOT(member(SV *))

'member($)'

Yes, you can pass perl scalar variables as signal/slot arguments.

=back

These are the functions you use for signals and slots.

=over 4

=item use signals LIST

Declare all of the signals in LIST. Each signal in LIST will cause a
function to be imported into your namespace by that name which calls all
the slots connected to it. Each signal name can be listed only once,
multiple prototypes are not supported.

=item use slots LIST

Declare all of the slots in LIST. Each slot is a normal method defined in
Perl. When it is declared as a slot, you can C<connect()> signals from Qt
or Perl to it. Each slot name can be listed only once, multiple prototypes
are not supported.

=item $receiver->connect($sender, $signal, $slot)

The C<connect()> method from Qt works the same way in Perl. Just replace
the SIGNAL() and SLOT() macros from Qt with quotes.

In Qt terminology, C<$sender> emits C<$signal>, C<$receiver> has
C<$slot>.

=item emit $sender->signal()

The emit keyword is imported into your namespace whenever you
C<use signals>. It is provided for syntactic sugar to identify that you
aren't calling a normal function, but are emitting a signal.

=back

=head1 SEE ALSO

Qt has a massive amount of documentation which I will not attempt to
duplicate. Read it.

http://www.troll.no/

Perl also has some great manual pages describing object-oriented practices
which are particularly relevant.

    perlobj             Perl objects
    perltoot            Perl OO tutorial

Included with PerlQt is alot of sample code. Look in the F<tutorials> and
F<examples> directories of your PerlQt directory.

=head1 BUGS

Much of PerlQt is untested. Signals and slots are limited to 3 arguments.
Alot of datatypes are still not supported.

=head1 AUTHOR

Ashley Winters <jql@accessone.com>