This was the way our project evolved. We are around 44K lines of wxPerl,
and around 98K lines of server-side API calls (and another 500K lines of C
that the Perl APIs can access). wxPerl *never* does any SQL or db access
directly. The clients are built for Win32, OSX and Linux. This is our
approach, and you may have different preferences, so take it for what it is
worth.
1) We use POE as an api server, as well as POE::Loop::Wx in the client.
2) We have some wxg templates with our tweaks pre-done, so that we can use
wxGlade to generate the initial version of a frame. We also have a
"postglade" script that can do a number of fix-ups on the generated code to
accommodate our preferred way of doing things.
3) We have written a number of our own data-aware sub-classed controls
including a SuperFrame that uses POE::Component::Client::TCP to connect back
to our server (based on POE::Component::Daemon). These controls can be
"prepared" with our own custom behavior. We chose "prepare" so that we
would not interfere with wxGlade's handling of the "new" method.
4) Each sub-classed control (such as a custom version of wxListCtrl) can
fetch it's own data to populate itself from the server, using client-side
caching rules to avoid unnecessary requests over the wire.
5) As an example we have a sub-classed wxButton that is a "Submit" which can
gather values from other controls in the frame to pass back to a server side
API call.
Obviously there is a lot more detail than this, but hopefully this gives you
one idea, and one approach. I'm sure others will have different ideas. The
XRC code was not really stable in wxPerl back when we started all this, so
others may wonder why we did things this way, but it works for us.
As a stripped down example:
sub new {
my $self = shift;
# begin wxGlade: SharedDialogs::List::new
<SNIPPED>
# end wxGlade
# This is where we hook into the wxGlade generated stuff
# to extend with our custom behavior
my %args=(@_);
$self->prepare( version => $VERSION,
incoming=> \%args );
return $self;
}
sub __set_properties {
my $self = shift;
# begin wxGlade: SharedDialogs::List::__set_properties
<SNIPPED>
# end wxGlade
}
sub __do_layout {
my $self = shift;
# begin wxGlade: SharedDialogs::List::__do_layout
<SNIPPED>
# end wxGlade
}
sub prepare {
my $self = shift;
$self->SUPER::prepare(@_);
# our different custom controls have different
# extended behaviors that allow them to fetch data,
# interact with other controls, etc
$self->{list}->prepare(
listname => 'REPLACE',
list_label => 'REPLACE',
columns => getColSpec('REPLACE'),
api_args => { this => $self->{__that} },
api_module => 'REPLACE',
api_method => 'REPLACE',
cachekey => 'REPLACE',
cache_mode => 'OFF',
status_bar => $self->{statusbar},
refreshbutton => 'submit',
itemactivated => \&REPLACE,
ondatareceived => \&REPLACE,
popupmenu => getPopup('REPLACE'),
auto_focus => 1,
);
}
HTH!