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

I'm really just starting out with using Tk, so I don't yet know my way around the many components that others have already built. There are several variants on file selection dialogs, but I can't seem to find a widget that both:

Am I just looking in the wrong places or am I going to have to implement this myself?

Thanks in advance.

------------ :Wq Not an editor command: Wq

Replies are listed 'Best First'.
Re: The right Tk file selecter
by zentara (Cardinal) on Mar 30, 2004 at 14:36 UTC
    What comes to mind, from your description of wanting to select multiple files simultaneously is the "listbox". You can choose it's -selectmode to "multiple", and load in your files.

    Here is a fancy version I gleamed from the usenet, which uses drag'n'drop. Select A and D, then drag one to the yellow area. I think it's close to what you want. Just substitute your filenames for A..Z.

    #!/usr/bin/perl use Tk; use Tk::DragDrop; use Tk::DropSite; use strict; my $var; my $curindex; my $mw=tkinit; my $listframe = $mw->Scrolled( 'Listbox', -selectmode=>'multiple', -scrollbars=>'oe')->pack; my $listbox = $listframe->Subwidget('scrolled'); $mw->Label(-text=>'Yellow Entry is the DropSite')->pack; my $entry = $mw->Entry(-bg=>'yellow')->pack; $listframe->insert('end',('A'..'Z')); my $token = $listbox->DragDrop( -event => '<B1-Motion>', -sitetypes => [qw/Local/], -startcommand=>\&draghandler, ); $entry->DropSite( -droptypes => [qw/Local/], -dropcommand => [\&fillEntry,$entry,$listbox], ); $listbox->bind('<ButtonPress-1>',sub { my $e=$listbox->XEvent; $curindex=$listbox->nearest($e->y); }); MainLoop; sub draghandler { #Force selection of the index under the mouse $listbox->selectionSet($curindex,$curindex); } sub fillEntry { my ($e,$l)=@_; $var=''; $e->delete(0,'end'); foreach ($l->curselection){ $var=$var.$l->get($_); } $e->insert('end',$var); $l->selectionClear(0,'end'); } __END__

    I'm not really a human, but I play one on earth. flash japh
Re: The right Tk file selecter
by graff (Chancellor) on Mar 30, 2004 at 03:15 UTC
    I should confess that I hate file-selection widgets, especially the ones that assume the user can't possibly know what he wants or where anything is until you show it to him in excruciating detail, and therefore he has to be walked through every single layer up and down the directory structure in baby-steps -- bleah! It makes me sore.

    So that would explain why I would actually recommend you go ahead and roll your own in this case. I know, from prior SoPW threads where we've both posted relevant help, that you can handle "File::Find" or choose a command-line "find" + "readdir" approach without any trouble. All you need beyond that is a good idea of how the tool should behave, one or two scrollable Listboxes, a Label or two, a nice wide Entry widget where you can type or paste, and maybe a dynamic "combo-box" style pull-down (a fancy way to keep a history of paths and/or files already visited). There's not that much to doing a decent job of it. And you'll know for sure that you can make it fit nicely with the rest of your GUI layout.

    I realize I'm overstating the simplicity a little bit, but most of the subtlety is just a matter of keeping track of where you are, and knowing enough about what the user needs so that you keep it both simple and effective. I'd spend a little extra time looking for a way to have an Entry widget where I can type in a path and have filename completion bound to the tab key. (I don't know if any of the file-selector dialogs provide this. It's crippling not to have it.)

    If you want to go in for all the cute decorations (icons determined by file-type, yadda yadda), then just ignore me, and good luck with the pre-packaged widget that gives you all that.

      Well, I'm not trying to find something terribly fancy, I was just trying to save a little bit of work. Really all that I'm doing is trying to put a GUI interface on a simple perl script that's basically used like:
      x12concatenate outfile.x12 infile1.x12 [infile2.x12 ...]
      Very, very simple... just picking a list of input files and an output file. It's just something I have to hand off to someone else in the company who really isn't quite savee enough to handle command lines and shell globs. :-)

      The funny thing is that it wouldn't take a heck of a lot more work to turn it into a general "run a script" wrapper which could parse a standard command line "usage" description and give a UI for launching the script... well, maybe that would still be a bit of work... but you get the idea. MakeOpt::GUI, or something... heh. Maybe I'll work on that for CPAN after "the Company" clears me to put r.pm up on CPAN.

      ------------ :Wq Not an editor command: Wq
Re: The right Tk file selecter
by eserte (Deacon) on Mar 30, 2004 at 08:51 UTC
    Maybe Tk::PathEntry is suitable for you? It is basically just an entry with the <Tab> key bound to filename-completion. To select all files in a directory you could just enter a path with "*" at the end and do globbing in your application afterwards.
Re: The right Tk file selecter
by crabbdean (Pilgrim) on Mar 31, 2004 at 08:36 UTC
    Here is the result of some code I've just written to use in a program I'm writing - mostly a standard file or directory selector. Unfortunately it doesn't do multiple file selection, but you may get something out of it. Enjoy!

    #!/usr/local/bin/perl use Tk; use Tk::FileDialog; use strict; use warnings; my $selected = ''; my $mw = new MainWindow; $mw->geometry(200 . 'x' . 100 . '+0+0'); $mw->Entry(-textvariable => \$selected )->pack(-expand => 1, -fill => 'x'); $mw->Button(-text => 'Browse', # set the last variable to 1 to only select directories -command => [\&selectme, $mw, 'archive.tar', 'h:', 0] )->pack(-expand => 1, -fill => 'x'); $mw->Button(-text => 'Exit', -command => sub {$mw->destroy} )->pack(-expand => 1, -fill => 'x'); MainLoop; sub selectme { my ($mw, $startfile, $startpath, $seldir) = @_; my $output = undef; ## configuration my($LoadDialog) = $mw->FileDialog(-Title =>'Select ...', -File => $startfile, -Path => $startpath, #-Chdir => 1, #-Create => 1, #-ShowAll => 1, -DisableShowAll => 1, #-Grab => 1, #-Horiz => 1, -SelDir => $seldir, #-FPat => '*', #-Geometry => '', ); $selected = $LoadDialog->Show(); if (!defined($startfile)) { $selected = "No file chosen!" } return $startfile; }

    Dean
    The Funkster of Mirth
    Programming these days takes more than a lone avenger with a compiler. - sam
    RFC1149: A Standard for the Transmission of IP Datagrams on Avian Carriers