I roll my own.

sub handleClick { my ($listbox,$path,$label,$drives,$filename) = @_; #retrieve the item selected my $item = $listbox->get('active'); #If the item's first letter is not an allowed character if(!($item =~ m{^[\w\d\.\+\-\=\(\)\%\^\#\@\!\~\`\'\,]{1}})) { #Strip slashes if directory $item =~ s{\/}{}g; CLICK_OPTION: { #Move down a level $item =~ m{\.{2}} && do { #Remmove valid path characters fro +m the end of the file $$path =~ s{\/[\s\w\d\.\+\-\=\(\) +\%\^\#\@\!\~\`\'\,]*$}{}; #Add a slash if you're left with + only the drive letter and : $$path .= "/" if length($$path) +== 2; last CLICK_OPTION; }; #Change drives $item =~ m{^\<} && do { #Remove angle brackets $item =~ s{[<>]*}{}g; #Add a colon and / $$path = $item.":/"; last CLICK_OPTION; }; #Defaultly attempt to open it as a directory if(opendir TEST,$$path."/".$item) { #Close it if it suceeds closedir TEST; #Update $$path for use in populate() $$path = (length($$path) != 3 ? $$path."/".$item:$$p +ath.$item); } } #Reformat the label showing the path $label->configure(text=>'Browsing: ' . $$path); #Re-populate the listbox populate($path,$listbox,$drives); } else { #Delete the current value of the entry widget $filename->delete('0.0',length($filename->get())); #Add the selected path and filename to the entry widget $filename->insert('end',(length($$path) != 3 ? $$path."/".$it +em:$$path.$item)); } return; } sub getDrives { my @drives = (); #Loop through the alphabet for ('A'..'Z') { #Attempt to open the root of the drives if(opendir(TEST,$_.":/")) { #If successful close it closedir(TEST); #add to the list push @drives,$_; } } return @drives; } sub populate { my ($path,$listbox,$drives) = @_; #Delete the entries in the box $listbox->delete('end') for(0..$listbox->size); #Open the path that will populate the listbox opendir DATA, $$path or die "$! : Could not open directory!"; #Loop over each item foreach(readdir DATA) { #If the item can be opened as a file if(opendir(TEST,$$path."/".$_)) { closedir(TEST); #Insert the item with a prepending / #to denote that the item is a directory $listbox->insert('end',"/".$_); } else { #Insert it as returned by readdir $listbox->insert('end',$_); } } #Close the path that populates the listbox closedir DATA; $listbox->insert('end',"<".$_.">") for @{$drives}; return; } sub selectFile { my ($mw,$client,$login) = @_; #Create the DialogBox my $dlg = $mw->DialogBox(-title=>"Import Data: ".$$client, -buttons=>['OK','Cancel']); my ($filename,$tape,$path) = ('','','C:/'); #save the array of drive letters #returned by getDrives() in @drives my @drives = getDrives(); #Create the pwd label my $label = $dlg->Label(-text=>"Browsing: " .$path)->pack(); #Create the listbox that holds the directory listing my $list = $dlg->Scrolled('Listbox', -scrollbars=>'oe os', -background=>'black', -foreground=>'white', -width=>'50', -height=>'20')->pack(); #Create the LabEntry widget and bind its value to $filename my $fileEntry= $dlg->LabEntry(-label =>'Enter a Filename', -labelPack =>[qw{-side left -anch +or w}], -textvariable=>\$filename, -background =>'white', -width =>30)->pack(); #Create the LabEntry widget and bind its value to $tape $dlg->LabEntry(-label =>'Enter a Tape Number:', -labelPack =>[qw{-side left -anchor w}], -textvariable=>\$tape, -background =>'white', -width =>26)->pack(); #Bind the double-click event. $list->bind('<Double-1>'=>[\&handleClick,\$path,$label,\@drives,$f +ileEntry]); #Populate the scrolled listbox populate(\$path,$list,\@drives); #Show Dialog and save result in $result my $result = $dlg->Show(); #If the user clicked OK while($result eq 'OK' && (!$filename || !validTapeID(\$tape,$login +))) { errorDisplay($mw,'You must enter a valid filename, and tape nu +mber not already present in the data.'); $result = $dlg->Show(); } return ($result,$filename,$tape); }
It's an example from a program I did.. It's specifically for windows, as there are a great deal of windows caveats in the code. but it works like a charm. Not tryin to say this is the best solution by any means, there are devs far better than I, but this is just what has worked for me.

P.S. The DirTree widget does look nice (visually) if you can get it working

In reply to Re: How do i select a directory in Tk? by Grygonos
in thread How do i select a directory in Tk? by Elderian

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.