Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

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)

Posted on Jan 6, 2019 2:37 AM

Reply
Question marked as Best reply

Posted on Jan 6, 2019 2:30 PM

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())


4 replies
Question marked as Best reply

Jan 6, 2019 2:30 PM in response to ShevaKadu

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())


Jan 6, 2019 7:11 AM in response to ShevaKadu

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())


Can I ask Python to open the window that asks the path (for example, where to place the file?)?

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.