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

I have a fairly big application with a pTk interface. While writing this app, I began to wonder if I was doing the "right thing" when I designed the way different bits communicate.

The application is broken into several distinct interfaces, each has a "Manager" object that handles a specific set of related UIs, for example I have a DisplayManager that handles the details of creating and controlling various screens that display data, I also have a ConfigurationManager that handles the presentation of configuration screens. Each manager collects input from its children and then operates on the back-end objects, mostly through registered callbacks or eval-ing standard methods on child objects.

sub UpdatePanels { my $self = shift; my $net = $self->network; my @sensors = $net->sensors; my @display_objects = ( @{$self->display_objects} ); foreach my $display ( @display_objects ) { eval { $display->UpdatePanel( $self->session_state, @sensors ); }; warn $@ if $@; } } # END UpdatePanels

After further reading and experimentation, it seems to me that a better design might be to use Tk's event system to pass information.

sub UpdatePanels { my $self = shift; $self->eventGenerate('<<UpdatePanels>>'); }

Of course, I would need to create the UpdatePanel virtual event and bind a callback for each display object for this to work.

What I would like to know is:

  1. What are the reasons to keep the design the way I have it?
  2. What are the reasons to switch to pTk managed events?
  3. Should I be considering an entirely different approach that I did not outline above?
  4. Can you recommend any good resources on GUI and/or event driven style of programming?


TGI says moo

Replies are listed 'Best First'.
Re: Perl Tk - propagating events
by renodino (Curate) on Jun 15, 2006 at 04:12 UTC
    Forgive me as I trot out an old, tired, and yet still very relevant cliche: KISS.

    Yes, pTk (and Perl in general) provide lots of clever ways to do things, esp. for propagating events. And they're very convenient if an app is 100 lines or less in size.

    But when dealing with large scale apps, with lots of GUI components and HMI interactions, I've learned the hard way that keeping to simple disciplines is a far better solution than trying to implement every clever bit of minimalist sigilism.

    I've developed a large scale IDE for database apps in Perl and pTk. At first, it was very organic: model and view were all tangled up together. That worked OK when there were 4-5 distinct HMI functions. But the logic got very convoluted after that. Ultimately, I took 3 or more big steps back and rewrote the app to completely separate the GUI from the app logic. As in isolating the View code completely, and explicitly routing all the GUI events to the model through an imperative controller interface.

    No, its not sexy. And its a bit more code, It even starts looking like Java at times. It makes me cringe a bit every time I think about the overhead of passing events and responses back and forth through a Controller object.

    But every time I put it away for 3 months, and then go back to do some maintenance, I can quickly dive back in. Perhaps as importantly, I'm in the process of converting everything to a browser based solution, and its much easier to focus on just the view components, and XHR all the interactions back to the model.

    My advice is to avoid the pitfall of trying to be too clever. Perl and pTk provide many opportunities to use short cuts. They're great for golfing quick solutions to simple problems to impress friends and coworkers. But in the arena of large scale GUI apps, its probably best to let the right and left cranial lobes each focus on the things they do well, and implement a simple bridge between them. Within their hemispheres, feel free to minimize as much as you like; but trying to optimize by declaratively leaking GUI event dispatch into the model will eventually become a liability.

      But in the arena of large scale GUI apps, ...

      Some years ago I also discovered that perl/Tk isn't suitable for large scale GUI apps, because its syntax too verbose and immediately after some widgets are packed, I have a forest of unmaintainable code.

      Things went more smoothly after I started creating apps a bit differently, namely I used to separate GUI and logic, and write GUI with pure Tcl/Tk, after that use Tcl::Tk CPAN module to connect GUI to Perl.

      This approach required some learning of Tcl/Tk, so took some efforts.
      But I never regret that, and the only regret I have is why I did not moved to Tcl::Tk earlier.

      While Tcl is a very different beastie compared to Perl, and may be not suitable for many tasks where Perl is the right choice, Tcl/Tk is very suitable for GUI, much more than perl/Tk do.

        My comments were not specifically about pTk vs. Gtk2 vs. Tcl::Tk vs. whatever (that debate has been repeatedly thrashed out on ptk@lists.Stanford.edu and clp.tk - frankly, if it had usable documentation, I'd use wxPerl), but instead about a design philosophy and the pitfalls of using shortcuts early on (usually in the form of burying Model logic in closures assigned to GUI event dispatches).

        The same pitfalls exist in Web app development in the form of Templating systems and/or languages that encourage burying Model logic inside HTML. That capability is great for quickly cranking out a few pages that slam some forms into a DBMS. But when the application starts expanding, and the page contents and navigation get complicated, that approach also starts to suffer from the forest v. trees problem, as well as the ripple effect when minor changes are made to either the view or the model.

        Some years ago I also discovered that perl/Tk isn't suitable for large scale GUI apps,

        Perl/Tk is perfectly suitable for large scale apps (I know it is; I've seen me do it). Tcl::Tk probably is too. (tho tracking down widgets for it tends to be much more of a chore than just hopping over to CPAN). wxPerl is probably also a capable solution. And now my personal preference is for browser based AJAX/Javascript solutions. But when model logic gets muddled up with view logic, they will all suffer from both tangled complexity, maintenance ripple effects, and probably GUI lock-in.

        So, to reiterate: isolate view logic from the model, and avoid clever code (e.g., pseudo-events, or GUI dispatched closures loaded with model logic, etc.)

Re: Perl Tk - propagating events
by zentara (Cardinal) on Jun 15, 2006 at 10:31 UTC
    I agree with what renodino says, that is for big complex programs, use the Tk portion for visual display only, and keep the logic separate. Don't use Tk objects as containers to store your data, use them as viewports into your data.

    Perl/Gtk2 relies heavily on it's signalling mechanisms, which may be what you are looking for, but be warned....it's what makes things difficult in Gtk2, and causes many to return to good'ole Tk. :-)


    I'm not really a human, but I play one on earth. flash japh