in reply to Writing and maintaining Tk GUIs with ZooZ

Thanks g0n.

I am the author of ZooZ, and to that extent am very well aware of its limitations. You bring up very good points that I have thought about before and that aren't very easily addressable. I have struggled with many such issues as I developed the program. In fact, ZooZ was written from scratch 4 times before I decided on the current format. As you probably guess, I still think it's far from perfect.

In my opinion, and this might seem ironic, GUI builders aren't really as useful as they are hyped to be. Since it's a program, it will always try to cater to the lowest common denominator of its users, and will thus pollute the final code with a lot of unnecessary junk, which makes it really really hard to tweak manually later on. Furthermore, besides very simple widget with very well defined behaviour, it's really hard to incorporat complex widgets in a GUI builder. You can easily instantiate a canvas, for example, but it's really hard to define all the canvas bindings. For this, you need to intermix manual code with program-generated code, which is a recipe for disaster.

That's why I think ZooZ is best used for prototyping and creating simple UI collections in the form of Perl modules. This nicely segragates machine-generated code from manually-written code. I mainly use it for that. What this means is that you can create a part of a GUI with ZooZ, and dump that as a .PM file. The .PM file will contain a Tk mega widget that you can include as:

my $w = $mw->myZooZwidget->pack;
I struggled with a way to let users easily control the widgets inside the ZooZ mega-widget, and resorted to the ugly hack of making everything a global var, which explains all the main::'s. My plan, going forward, is to define everything as an option of the megawidget, so that they can be accessed like other options:
$w->configure(-label1_text => 'new text');
you can sort of do something like that right now using Subwidget to access the internal widgets:
$w->Subwidget('label1')->configure(-text => 'new text');
Anyway, enough ranting for me. I'll keep all your points in mind as I think of how to extend ZooZ. To be honest, I received way many more emails about ZooZ than I expected. I didn't expect too many people to take notice of it, but I was wrong (as I often am). This is leading me to think in different directions like having a clean API for "extensions", and dumping the .zooz file in a standard XML format so that it can be generated by any other program, and perhaps having a stand-alone XML to Perl/Tk converter that uses ZooZ's "engine" to dump Perl code from .zooz files.

As always, I'm open to suggestions. Feel free to contact me at aqumsieh@cpan.org.


--Ala

Replies are listed 'Best First'.
Re^2: Writing and maintaining Tk GUIs with ZooZ
by g0n (Priest) on Jun 03, 2006 at 11:20 UTC
    What this means is that you can create a part of a GUI with ZooZ, and dump that as a .PM file. The .PM file will contain a Tk mega widget that you can include as:

    my $w = $mw->myZooZwidget->pack;

    ++ to that, several times over. Now, what would be really cool would be to pass an object into the megawidget, and use that for callbacks/variables in the same way as I described in the OP. The Tk::mega constructor doesn't like more than 2 params, but that can be overloaded in the .pm file like this:

    my $worker; sub new { my ($class, $mw, $worker) = @_; my $self = $class->SUPER::new($mw); return $self; }

    Done this way the callbacks would be acting on $worker, which is in package scope, so don't need to be exported into main::

    This would entail changes to dumpPerlPM to declare objects as undef, then construct the my ($class,$mv,..,..,..) = @_ line in new with a list of the objects. From playing with this last night, I don't think the changes I sent you last week write out object attributes to .pm files correctly anyway - I'll take another look at that.

    That would allow me to create standard megawidgets associated with my classes, and maybe even in the class, create methods like this:

    sub widget { my $self = shift; my $mw = shift; if ($self->{widget}){return $self->{widget}} use autouse 'workerwidget'; my $widget = $mw->workerwidget($self); $self->{widget} = $widget; return $widget; }

    (With the autouse just in case I'm using my class on a system with no tk installed). Then, to put (for example) a list of servers with checkboxes in my window, I'd just need to do this:

    my $worker = ServerListClass->new(); my $serverlistwidget = $mv->$worker->widget($mw)->pack();

    I guess this kind of stuff in general Tk programming terms is probably covered in one of the Tk programming books. Perhaps a trip to the bookshop is called for...

    --------------------------------------------------------------

    "If there is such a phenomenon as absolute evil, it consists in treating another human being as a thing."
    John Brunner, "The Shockwave Rider".

    Can you spare 2 minutes to help with my research? If so, please click here