Can I ask Python to open the window that asks the path (for example, where to place the file?)?
Can I ask Python to open the window that asks the path (for example, where to place the file?) ?
[Re-Titled by Host]
Macbook (2016 or later)
Can I ask Python to open the window that asks the path (for example, where to place the file?) ?
[Re-Titled by Host]
Macbook (2016 or later)
You wanted an interactive dialog, and creating GUI in Python is code expensive. My first effort, without change, works on Python 2.7.10, Python 2.7.15, and Python 3.7.2. It does so because it uses Python version, independent AppleScript syntax for the dialogs. As soon as you stop using AppleScript, you then become exposed to other graphical user interface libraries which are Python version dependent.
You requested "shorter" code isn't really that much shorter, and instead of AppleScript, it uses the Tk library (8.6.8) that ships with Python 3.7.2. This code will not run on Python 2.7.10, or 2.7.15 without modification. Apple still persists in including Tcl/Tk 8.5.9 with OS X and macOS, and it is extremely outdated and tied to a carbon, not Cocoa interface. The following code was tested on macOS High Sierra 10.13.6 (17G4015).
#!/usr/bin/env python3
# coding: utf-8
from __future__ import print_function, absolute_import
import os
import sys
from tkinter import *
from tkinter.filedialog import askopenfilename, asksaveasfilename
root = Tk()
root.withdraw()
default_path = os.path.expanduser('~/Desktop')
valid_types = [("Text files", "*.txt"),
("Python files", "*.py"),
("Image files", "*.jpg")]
def user_action(apath, cmd):
if "Select" in cmd:
filename = askopenfilename(initialdir=apath,
message="Choose one or more files",
multiple=True,
title="File Selector",
filetypes=valid_types)
elif "Save As" in cmd:
filename = asksaveasfilename(initialdir=apath,
title="Select Filename to save",
filetypes=valid_types)
return filename
def main():
file_path = user_action(default_path, "Select")
if not file_path:
sys.exit("User cancelled")
print(*file_path, end='\n')
file_path = user_action(default_path, "Save As").strip()
if not file_path:
sys.exit("User cancelled")
print(file_path)
if os.path.exists(file_path):
write_flag = 'a'
else:
write_flag = 'w'
with open(file_path, write_flag) as fh:
outstr = "Filename: {}\n".format(file_path)
fh.write(outstr)
if __name__ == '__main__':
sys.exit(main())
You wanted an interactive dialog, and creating GUI in Python is code expensive. My first effort, without change, works on Python 2.7.10, Python 2.7.15, and Python 3.7.2. It does so because it uses Python version, independent AppleScript syntax for the dialogs. As soon as you stop using AppleScript, you then become exposed to other graphical user interface libraries which are Python version dependent.
You requested "shorter" code isn't really that much shorter, and instead of AppleScript, it uses the Tk library (8.6.8) that ships with Python 3.7.2. This code will not run on Python 2.7.10, or 2.7.15 without modification. Apple still persists in including Tcl/Tk 8.5.9 with OS X and macOS, and it is extremely outdated and tied to a carbon, not Cocoa interface. The following code was tested on macOS High Sierra 10.13.6 (17G4015).
#!/usr/bin/env python3
# coding: utf-8
from __future__ import print_function, absolute_import
import os
import sys
from tkinter import *
from tkinter.filedialog import askopenfilename, asksaveasfilename
root = Tk()
root.withdraw()
default_path = os.path.expanduser('~/Desktop')
valid_types = [("Text files", "*.txt"),
("Python files", "*.py"),
("Image files", "*.jpg")]
def user_action(apath, cmd):
if "Select" in cmd:
filename = askopenfilename(initialdir=apath,
message="Choose one or more files",
multiple=True,
title="File Selector",
filetypes=valid_types)
elif "Save As" in cmd:
filename = asksaveasfilename(initialdir=apath,
title="Select Filename to save",
filetypes=valid_types)
return filename
def main():
file_path = user_action(default_path, "Select")
if not file_path:
sys.exit("User cancelled")
print(*file_path, end='\n')
file_path = user_action(default_path, "Save As").strip()
if not file_path:
sys.exit("User cancelled")
print(file_path)
if os.path.exists(file_path):
write_flag = 'a'
else:
write_flag = 'w'
with open(file_path, write_flag) as fh:
outstr = "Filename: {}\n".format(file_path)
fh.write(outstr)
if __name__ == '__main__':
sys.exit(main())
The following code will "borrow" AppleScript dialogs to be run as subprocesses from Python 3. The AppleScript choose file dialog will return a UNIX filename path, and the choose file name dialog is essentially a Save As dialog. If a label is selected in this dialog, it will not be written to the selected filename, because Python is doing the writing, not AppleScript. Works equally well with macOS python 2.7.10, custom install of Python 2.7.15, or python 3.7.2 (as tested) from python.org.
Change the python3 to python as appropriate.
#!/usr/bin/env python3
# coding: UTF8
# example code borrowing AppleScript dialogs to
# 1. Choose a filename
# 2. Save a filename (Python code saves content, this just gets the filename)
# 3. Passing arguments to an AppleScript sub-process.
import sys
import os
import subprocess
default_path = os.path.expanduser('~/Desktop')
def user_action(apath, cmd):
ascript = '''
-- apath - default path for dialogs to open too
-- cmd - "Select", "Save"
on run argv
set userCanceled to false
if (count of argv) = 0 then
tell application "System Events" to display dialog "argv is 0" ¬
giving up after 10
else
set apath to POSIX file (item 1 of argv) as alias
set action to (item 2 of argv) as text
end if
try
if action contains "Select" then
set fpath to POSIX path of (choose file default location apath ¬
without invisibles, multiple selections allowed and ¬
showing package contents)
# return fpath as text
else if action contains "Save" then
set fpath to POSIX path of (choose file name default location apath)
end if
return fpath as text
on error number -128
set userCanceled to true
end try
if userCanceled then
return "Cancel"
else
return fpath
end if
end run
'''
try:
proc = subprocess.check_output(['osascript', '-e', ascript,
apath, cmd])
if 'Cancel' in proc.decode('utf-8'): # User pressed Cancel button
sys.exit('User Canceled')
return proc.decode('utf-8')
except subprocess.CalledProcessError as e:
print('Python error: [%d]\n%s\n' % e.returncode, e.output)
def main():
# opens AppleScript choose file dialog and returns UNIX filename
fname = user_action(default_path, "Select").strip()
print(fname)
# opens AppleScript Save As file dialog and returns UNIX filename
fname = user_action(default_path, "Save").strip()
print(fname)
# write data to filename returned from Save As dialog
with open(fname, 'w') as f:
outstr = "Filename: {}\n".format(fname)
f.write(outstr)
if __name__ == '__main__':
sys.exit(main())
Wow! Script is big! May there be a shorter script?
thanks
Can I ask Python to open the window that asks the path (for example, where to place the file?)?