in reply to Which tk to use and how to show images?

Updated: to remove unnecessary use of IO::String from the second example based on comments from BrowserUk.

Updated again: Thanks to Zentara for pointing out an error in both examples that I missed by not using strict. my $gd = $graph->plot(\@data) or die $my_graph->error;. I corrected it, but it's still wrong in Traveler's and BrowserUk's nodes. I don't feels as bad. ;-)


I respectfully disagree with Traveler about GTk being the easiest, but it's a minor quibble at best as you'll see below. Nice example, though (++ as soon as the xp fairy visits). Also, with Courage - since I have my own petty gripes with the Tcl::Tk module, even though I have to admit it seems like the inevitable future (sigh...).

Since you are considering using GD::Graph, any one of the three options will all work reasonably well, with a roughly equivalent amount of code. Each may have additional modules or extensions for providing specific support for charts. I know that Perl/Tk, and Tcl::Tk (through external tcl/tk libraries such as blt) do. For this node, I'll stick to GD::Graph.

In the way of example, and borrowing from Traveler, here's one way it might be done using Tk.

use strict; use Tk; use Tk::PNG; use GD::Graph; use GD::Graph::bars; ## almost straight from the pod my $data = [ [qw/1st 2nd 3rd 4th 5th 6th 7th 8th 9th/], [qw/ 1 2 5 6 3 1.5 1 3 4/], ]; my $graph = GD::Graph::bars->new(400, 300); $graph->set( x_label => 'X Label', y_label => 'Y label', title => 'Some simple graph', y_max_value => 8, y_tick_number => 8, y_label_skip => 2 ) or die $graph->error; my $gd = $graph->plot(\@data) or die $graph->error; open(IMG, '>file.png') or die $!; binmode IMG; print IMG $gd->png; close IMG; ## Up to this point, except for the the module ## imports it's nearly identical to the GTK Example my $mw = MainWindow->new; my $png = $mw->Photo(-format => 'png', -file => 'file.png'); $mw->Label(-image => $png)->pack; MainLoop;

The same example, but this time without the temp file:

use strict; use Tk; use Tk::PNG; use MIME::Base64; use GD::Graph; use GD::Graph::bars; my $data = [ [qw/1st 2nd 3rd 4th 5th 6th 7th 8th 9th/], [qw/ 1 2 5 6 3 1.5 1 3 4/], ]; my $graph = GD::Graph::bars->new(400, 300); $graph->set( x_label => 'X Label', y_label => 'Y label', title => 'Some simple graph', y_max_value => 8, y_tick_number => 8, y_label_skip => 2 ) or die $graph->error; my $gd = $graph->plot($data) or die $graph->error; my $mw = MainWindow->new; my $png = $mw->Photo(-data => encode_base64($gd->png)); $mw->Label(-image => $png)->pack; MainLoop;

I imagine that the Tcl::Tk option would be virtually identical to the above examples, though I haven't tested it.

As far as choosing toolkits, it will largely depend on what you are looking for in a toolkit. I'm sure you can find a few nodes on this site and others that compare and constrast them. I'll offer up a few, barely organized and biased thoughts of my own:

TK

The good: Good community that is responsive on Perlmonks, the ptk mailing list, the c.l.p.tk newsgroup, and a website. There are plenty of decent articles, tutorials, and Mastering Perl/Tk is an outstanding reference. There are also a decent assortment of custom widgets of varying quality on CPAN and other locations on the net. I also have a very large library of my own custom widgets that mitigate some of my personal issues with the API.

The bad: I find the Tk distribution somewhat bloated, and a little crusty with lots of seemingly random odds and ends. The API lacks cohesion, is not released as often as it used to and for a distribution of its size, there seem to be a fairly small number of folks doing maintainance and pushing out releases regularly. I'm distressed about the number of memory leaks still in the distro, and other minor annoyances. In short: it has warts, but I still like and have a lot of fun with it.

Tcl::Tk

Unlike Tk, which attempts to replace much of the Tcl c code with Perl code, Tcl::Tk is a bridge that relies on a locally installed Tcl/Tk distribution. There are several advantages to this approach that cannot be understated. Very little C code to maintain, ability to take advantage of the latest and greatest that the Tcl/Tk community has to offer, which is quite a bit. I especially like the blt library that has a few nice charting widgets (Alas, this library is somewhat dated). However, unicode support is solid, threads too, I really like what is being done with tiles, and the Tcl/Tk maintainers are a really talented group of folks. (Too bad I never warmed to the language...)

The bad: Personally, I don't care that the module(s) allow me to interpret Tcl code. If I wanted to code in Tcl/Tk, then I would be writing a tcl script, and not a perl one. I realize that it has a Perl/Tk compatibility mode, that supports a syntax which is virtually identical to Perl/Tk. I find that this is basically a thin facade, however, that doesn't fully support the Perl/Tk mega widget model, and replaces it with one that I don't care for (last time I checked...) Tcl::Tk's poor support for Perl/Tk's megawidgets is a serious issue for me. Despite these things, I may end up grudgingly converting my library to Tcl::Tk, or more likely switch to GTk and/or Qt which I already use in C/C++.

GTk

I like GTk, and Qt, too, but I haven't really embraced them in Perl yet, beyond a few toys. I have used them a bit with c/c++. Both have a more cohesive API, and very active and dedicated user bases on the C side. The big strike for me is that I can't easily download a Perl distro from Activestate with support for either one that is already built in, but that is mostly laziness talking ;-). I've seen some impressive things in both, but really haven't dedicated the time to either that I have to Tk.

I encourage you to find some simple task and experiment with each one toolkit to implement the task. Decide for yourself which works best for your personal situation. I don't think there's a wrong choice, but plenty of different right ones that will depend on you, your requirements, and preferences. Hope this helps,

Replies are listed 'Best First'.
Re^2: Which tk to use and how to show images?
by BrowserUk (Patriarch) on Nov 04, 2005 at 04:09 UTC

    I cannot verify this myself as I upgraded to 5.8.7 and I am still working through rebuilding everything else, and I haven't done GD yet. Shouldn't you be able to bypass the intermediate file by using the Tk::Photo -data option?

    my $png = $mw->Photo( -format => 'png', -data => $gd->png );

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Shouldn't you be able to bypass the intermediate file by using the Tk::Photo -data option?

      Well, I did bypass the intermediate file in the second example using the -data option, but I tried to use your snippet which looked shorter anyway. Unfortunately, it didn't work. I think I've tried this in the past, but hoped for a second that the internals had been modified when you mentioned it. For it to work, the data has to be base64 encoded, before it can be passed, otherwise Tk complains that it doesn't understand the format.

      I'd be interested if you have a way around this. I've only occasionally used GD, and I'm definitely not an expert with it.

      Rob
        For it to work, I had to make sure the data is base64 encoded ...

        Now you mention it, I think I had to go that route also. It was a while ago.

        That said, logic suggests that you should be able to bypass IO::String, and pass the output from gd directly to encode_base64():

        my $png = $mw->Photo(-data => encode_base64( $gd->png ));

        I see no reason that shouldn't work as what ends up in the file is exactly what comes out of the image methods, hence the need for binmode;

        I've made quite a lot of use of GD (though I hardly qualify as an expert), but I am light on Tk;

        (Grrr. I hate being unable to try stuff, and I hate the available upgrade paths for perl.)


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.