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 43 from tkCommonDialog import Dialog 44 45 class _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 74 class 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 94 class 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. 101 class 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 122 def askopenfilename(**options): 123 "Ask for a filename to open" 124 125 return Open(**options).show() 126 127 def asksaveasfilename(**options): 128 "Ask for a filename to save as" 129 130 return SaveAs(**options).show() 131 132 def 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 143 def 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 151 def 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 168 def 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 176 def askdirectory (**options): 177 "Ask for a directory, and return the file name" 178 return Directory(**options).show() 179 180 # -------------------------------------------------------------------- 181 # test stuff 182 183 if __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