1# 2# Instant Python 3# $Id: tkFileDialog.py 36560 2004-07-18 06:16:08Z tim_one $ 4# 5# tk common file dialogues 6# 7# this module provides interfaces to the native file dialogues 8# available in Tk 4.2 and newer, and the directory dialogue available 9# in Tk 8.3 and newer. 10# 11# written by Fredrik Lundh, May 1997. 12# 13 14# 15# options (all have default values): 16# 17# - defaultextension: added to filename if not explicitly given 18# 19# - filetypes: sequence of (label, pattern) tuples. the same pattern 20# may occur with several patterns. use "*" as pattern to indicate 21# all files. 22# 23# - initialdir: initial directory. preserved by dialog instance. 24# 25# - initialfile: initial file (ignored by the open dialog). preserved 26# by dialog instance. 27# 28# - parent: which window to place the dialog on top of 29# 30# - title: dialog title 31# 32# - multiple: if true user may select more than one file 33# 34# options for the directory chooser: 35# 36# - initialdir, parent, title: see above 37# 38# - mustexist: if true, user must pick an existing directory 39# 40# 41 42 43from tkCommonDialog import Dialog 44 45class _Dialog(Dialog): 46 47 def _fixoptions(self): 48 try: 49 # make sure "filetypes" is a tuple 50 self.options["filetypes"] = tuple(self.options["filetypes"]) 51 except KeyError: 52 pass 53 54 def _fixresult(self, widget, result): 55 if result: 56 # keep directory and filename until next time 57 import os 58 # convert Tcl path objects to strings 59 try: 60 result = result.string 61 except AttributeError: 62 # it already is a string 63 pass 64 path, file = os.path.split(result) 65 self.options["initialdir"] = path 66 self.options["initialfile"] = file 67 self.filename = result # compatibility 68 return result 69 70 71# 72# file dialogs 73 74class Open(_Dialog): 75 "Ask for a filename to open" 76 77 command = "tk_getOpenFile" 78 79 def _fixresult(self, widget, result): 80 if isinstance(result, tuple): 81 # multiple results: 82 result = tuple([getattr(r, "string", r) for r in result]) 83 if result: 84 import os 85 path, file = os.path.split(result[0]) 86 self.options["initialdir"] = path 87 # don't set initialfile or filename, as we have multiple of these 88 return result 89 if not widget.tk.wantobjects() and "multiple" in self.options: 90 # Need to split result explicitly 91 return self._fixresult(widget, widget.tk.splitlist(result)) 92 return _Dialog._fixresult(self, widget, result) 93 94class SaveAs(_Dialog): 95 "Ask for a filename to save as" 96 97 command = "tk_getSaveFile" 98 99 100# the directory dialog has its own _fix routines. 101class Directory(Dialog): 102 "Ask for a directory" 103 104 command = "tk_chooseDirectory" 105 106 def _fixresult(self, widget, result): 107 if result: 108 # convert Tcl path objects to strings 109 try: 110 result = result.string 111 except AttributeError: 112 # it already is a string 113 pass 114 # keep directory until next time 115 self.options["initialdir"] = result 116 self.directory = result # compatibility 117 return result 118 119# 120# convenience stuff 121 122def askopenfilename(**options): 123 "Ask for a filename to open" 124 125 return Open(**options).show() 126 127def asksaveasfilename(**options): 128 "Ask for a filename to save as" 129 130 return SaveAs(**options).show() 131 132def askopenfilenames(**options): 133 """Ask for multiple filenames to open 134 135 Returns a list of filenames or empty list if 136 cancel button selected 137 """ 138 options["multiple"]=1 139 return Open(**options).show() 140 141# FIXME: are the following perhaps a bit too convenient? 142 143def askopenfile(mode = "r", **options): 144 "Ask for a filename to open, and returned the opened file" 145 146 filename = Open(**options).show() 147 if filename: 148 return open(filename, mode) 149 return None 150 151def askopenfiles(mode = "r", **options): 152 """Ask for multiple filenames and return the open file 153 objects 154 155 returns a list of open file objects or an empty list if 156 cancel selected 157 """ 158 159 files = askopenfilenames(**options) 160 if files: 161 ofiles=[] 162 for filename in files: 163 ofiles.append(open(filename, mode)) 164 files=ofiles 165 return files 166 167 168def asksaveasfile(mode = "w", **options): 169 "Ask for a filename to save as, and returned the opened file" 170 171 filename = SaveAs(**options).show() 172 if filename: 173 return open(filename, mode) 174 return None 175 176def askdirectory (**options): 177 "Ask for a directory, and return the file name" 178 return Directory(**options).show() 179 180# -------------------------------------------------------------------- 181# test stuff 182 183if __name__ == "__main__": 184 # Since the file name may contain non-ASCII characters, we need 185 # to find an encoding that likely supports the file name, and 186 # displays correctly on the terminal. 187 188 # Start off with UTF-8 189 enc = "utf-8" 190 import sys 191 192 # See whether CODESET is defined 193 try: 194 import locale 195 locale.setlocale(locale.LC_ALL,'') 196 enc = locale.nl_langinfo(locale.CODESET) 197 except (ImportError, AttributeError): 198 pass 199 200 # dialog for openening files 201 202 openfilename=askopenfilename(filetypes=[("all files", "*")]) 203 try: 204 fp=open(openfilename,"r") 205 fp.close() 206 except: 207 print "Could not open File: " 208 print sys.exc_info()[1] 209 210 print "open", openfilename.encode(enc) 211 212 # dialog for saving files 213 214 saveasfilename=asksaveasfilename() 215 print "saveas", saveasfilename.encode(enc) 216