Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Directory and file selection with PERL/Tk

by chanklaus (Acolyte)
on Sep 25, 2009 at 09:41 UTC ( #797438=perlquestion: print w/replies, xml ) Need Help??
chanklaus has asked for the wisdom of the Perl Monks concerning the following question:

Dear sisters and brothers in PERL,

for my applications I am looking for both a pure directory selection and a mixed fie and directory selection in PERL/Tk. There are a number of example programs available in the net, and I tried some of them, but I didn't find any which does exactly what I want to have. So I would like to ask you for help to find such an example program.

One of the examples for a directory selection tree I found and which I like is from Slaven Resic, located at

use Tk; use Tk::DirTree; use Cwd; my $top = new MainWindow; $top->withdraw; my $t = $top->Toplevel; $t->title("Choose directory:"); my $ok = 0; my $f = $t->Frame->pack(-fill => "x", -side => "bottom"); my $curr_dir = 'd:'; #my $curr_dir = Cwd::cwd(); my $d; $d = $t->Scrolled('DirTree', -scrollbars => 'osoe', -width => 35, -height => 20, -selectmode => 'browse', -exportselection =>1, -browsecmd => sub { $curr_dir = shift }, -command => sub { $ok = 1; }, )->pack(-fill => "both", -expand => 1); $d->chdir($curr_dir); $f->Button(-text => 'Ok', -command => sub { $ok = 1 })->pack(-side => 'left'); $f->Button(-text => 'Cancel', -command => sub { $ok = 1 })->pack(-side => 'left'); $f->waitVariable(\$ok); if ($ok == 1) { warn "The resulting directory is '$curr_dir'\n"; } __END__

It does more or less what I want it to do, only that it displays the directory tree of one drive only, and I want to have a directory tree displaying all of the drives which are in use, both hard discs and rather temporary device like USB sticks. In an ideal situation the directory tree starts with a display of all drives (c:, d:, etc.) with the highest level of directorys, from which people then can click down to the folder they want to select.

With a slight modification of the above mentioned example program I almost get that: if I replace the line


$d->chdir("c:"); $d->chdir("d:"); $d->chdir("e:");

I'll have all of the trees available, albeit the drive from which the program is started doesn't look exactly the way I described above, but opens to the directory in which the program is located.

I could live with this situation, but a more dynamic display through a program line

for (my $i=0;$i<=$#drives;++$i) { $d->chdir($drives[$i); }

(in which the @drives list contains all active drives, eg. estimated through an analysing function) didn't work, and I couldn't find the reason why.

So, once again, my questions:
Where can I find any example program which creates me a file and directory selection tool which is able to display the entire directory structure of a computer instead of just the structure for one drive only?
How can I modify the above mentioned program to show this entire drive and directory structure (built from a drive list) without hard coding the drives available on the computer?

Many thanks for your help,
best greetings and wishes,



Learning is like swimming against the current - as soon as you stop you'll drift back
(Chinese proverb)

Replies are listed 'Best First'.
Re: Directory and file selection with PERL/Tk
by biohisham (Priest) on Sep 25, 2009 at 10:34 UTC
    I find this option useful on Windows, run cmd from the command prompt, then in there just type widget

    C:\Documents and settings> widget
    This invokes an application that gives many useful scripts demonstrating what you can do with Tk widgets, it runs the Tk program demonstration for you to watch it with provision for parameters modification and from there you are provided with a button to see the code with regard to the demonstration you ran too.

    Now Scroll to the heading Common Dialogs you got links to the following there:

    1. Message Boxes.
    2. File selection dialog.
    3. Directory selection dialog.
    4. Color picker.

    I don't know if this is available when you're running another OS than Windows but let's hope that this be of some inspirational value to you.

    To get a description of what "widget" does check perldoc.

    C:\Documents and settings> perldoc widget

    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
Re: Directory and file selection with PERL/Tk
by BioLion (Curate) on Sep 25, 2009 at 10:30 UTC

    Hi chanklaus, being neither a windoze or Tk person, I am not sure if there is any wisdom in this, but I found this script for retreiving the list of mapped drives in a windows box - maybe it will help you answer your "and/or"?

    --------------------------------------------------------------- # Adapted from VBScript code contained in the book: # "Windows Server Cookbook" by Robbie Allen # ISBN: 0-596-00633-0 # --------------------------------------------------------------- use Win32::OLE qw(in); $Win32::OLE::Warn = 3; $strComputer = '.'; $objWMI = Win32::OLE->GetObject('winmgmts:\\\\' . $strComputer . '\\ro +ot\\cimv2'); $colDrives = $objWMI->ExecQuery('select * from Win32_MappedLogicalDisk +'); print "Mapped Drives:\n"; foreach my $objDrive (in $colDrives) { print ' Device ID: ' . $objDrive->DeviceID, "\n"; print ' Volume Name: ' . $objDrive->VolumeName, "\n"; print ' Session ID: ' . $objDrive->SessionID, "\n"; print ' Size: ' . $objDrive->Size, "\n"; print "\n"; }

    Although what you want to do sounds like it should be a common enough task that there would exist somewhere a more elegant ( and tested ) solution like you wanted!

    Just a something something...
Re: Directory and file selection with PERL/Tk
by Marshall (Abbot) on Sep 26, 2009 at 22:52 UTC
    I use ActiveState, currently on 5.10, but this also worked on 5.6. The ActiveState port and functionality of the getOpenFile() method is great! It would do everything you want and more.

    short demo program follows. Window will look like any other Windows application "file open", there is icon shortcut for Desktop, recently used, etc. All the drives on system are shown. You can filter by extension.I just put a .txt and .log button to show you how. It remembers where you were last time, so opening this window goes conveniently to last directory that you were in. I haven't used it for selecting multiple things but I'm sure it can do that too.

    #!/usr/bin/perl -w use strict; use Tk; my $mw = MainWindow->new; $mw->geometry("400x400+0+0"); my $menu_f = $mw->Frame()->pack(-side=>'top',-fill=>'x'); my $menu_file = $menu_f->Menubutton (-text=>'File',-tearoff=>'false') ->pack(-side=>'left'); $menu_file->command(-label=>'Open', -command=> \&get_file); #other menu buttons shown here as examples ... #$menu_file->command(-label=>'Save', # -command=> \&save_log); #$menu_file->command(-label=>'Close', # -command=> \&close_log); #$menu_file->command(-label=>'Exit',-command=>\&exit_msg); sub get_file { my @types = (["Log files", [qw/.txt .log/]], ["All files", '*'], ); my $filepath = $mw->getOpenFile(-filetypes => \@types) or return(); print "$filepath selected\n"; return($filepath); } MainLoop;
      I've been using getOpenFile and I like it a lot... now I need something like getOpenFile for folder selection.
      I could only find chooseDirectory, which is simple to use and works OK, but it doesn't look like the native folder picker in Windows, and it's not exactly intuitive for the user. It took me 10 minutes to figure out how to create a new folder at the desired location instead of picking an existing one. (You need to overtype the name of the lowest-level folder 'existing_folder' in the entry box; if you type existing_folder/newfolder in the box, it returns the path existing_folder/existing_folder/newfolder. You also have to add your own code for creating the new folder.)
      Anyone know of a better solution?
      Sample chooseDirectory code for reference:
      use strict; use warnings; require Tk; my $mw = Tk::MainWindow->new; my $dir = $mw->chooseDirectory(-initialdir => '~', -title => 'Choose a folder'); if (!defined $dir) { print "No directory selected"; } else { print "Selected $dir"; } Tk::MainLoop();

      I tried FileDialog as well, and got this bug:
      It would seem that FileDialog is buggy, and the best option is chooseDirectory... I can live with that, but it really needs a "Create new folder" button to be perfect.

        Hi elef. I'm trying to do something similar. I have a program that opens a directory and selects one of the subdirectories. However, I can't get it to create a new subdirectory if necessary. I tried typing over the name of the lowest subdirectory as you suggested, but that didn't work.

        Did you ever find a solution? If not, would you please re-explain how to create a new subdirectory using the chooseDirectory widget? Thanks.

Re: Directory and file selection with PERL/Tk
by lamprecht (Friar) on Sep 25, 2009 at 11:02 UTC

    you are writing, you need a widget which allows you to select files and directories. However, your example based on Tk::DirTree will handle directories only. If that's good enough, check out the following:

    perl -MTk -e"print tkinit->chooseDirectory"

    Cheers Christoph
Re: Directory and file selection with PERL/Tk
by planetscape (Chancellor) on Sep 26, 2009 at 08:55 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://797438]
Approved by broomduster
[Corion]: A good morning everybody ;)

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (7)
As of 2018-05-24 07:09 GMT
Find Nodes?
    Voting Booth?