¿Diálogo de archivo rápido y fácil en Python?

104

Tengo un script simple que analiza un archivo y carga su contenido en una base de datos. No necesito una interfaz de usuario, pero en este momento le estoy pidiendo al usuario que analice el archivo raw_inputque es más desagradable, especialmente porque el usuario no puede copiar / pegar la ruta. Me gustaría una manera rápida y fácil de presentar un cuadro de diálogo de selección de archivos al usuario, ellos pueden seleccionar el archivo y luego se carga en la base de datos. (En mi caso de uso, si eligieran el archivo incorrecto, fallaría el análisis y no sería un problema incluso si se cargara en la base de datos).

import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()

Este código está cerca de lo que quiero, pero deja un marco vacío molesto abierto (que no se puede cerrar, probablemente porque no he registrado un controlador de eventos de cierre).

No tengo que usar tkInter, pero como está en la biblioteca estándar de Python, es un buen candidato para la solución más rápida y sencilla.

¿Cuál es una forma rápida y fácil de solicitar un archivo o nombre de archivo en un script sin ninguna otra interfaz de usuario?

Botones840
fuente
Corrección menor: puede pegar en una terminal (parece que está en Windows) haciendo clic derecho en el área de texto y seleccionando "Pegar" en el menú contextual.
Deestan
1
No hay ningún menú contextual disponible en un indicador de entrada raw_input de Python.
Buttons840
2
raw_input ocurre en la terminal, que tiene un menú de clic derecho.
Deestan

Respuestas:

200

Tkinter es la forma más sencilla si no desea tener otras dependencias. Para mostrar solo el diálogo sin ningún otro elemento GUI, debe ocultar la ventana raíz usando el withdrawmétodo:

import tkinter as tk
from tkinter import filedialog

root = tk.Tk()
root.withdraw()

file_path = filedialog.askopenfilename()

Variante de Python 2:

import Tkinter, tkFileDialog

root = Tkinter.Tk()
root.withdraw()

file_path = tkFileDialog.askopenfilename()
tomvodi
fuente
3
Esta debería ser la respuesta aceptada. Es simple, efectivo y, siempre que no esté creando nuevas ventanas raíz de Tk una y otra vez, está bien (y sin mencionar que es exactamente la respuesta que estaba buscando cuando encontré este hilo).
Andrew
2
También usé esto para mi trabajo. Funciona bien en Fedora, pero en Ubuntu estropea las cifras de matplotlib que siguen. Mucho después de pylab.show () se cuelga. Todavía puedo escribir en la terminal, pero no pasa nada. También la CPU llega al 0% para mi programa. ¿Algún consejo?
Diana
17
En python3:tkinter.filedialog.askopenfilename()
jfs
10
En python2: import Tkinter as tky import tkFileDialogyfile_path = tkFileDialog.askopenfilename()
SaschaH
8
Esto no funciona bien en MacOS: el cuadro de diálogo se abre pero deja de responder y todo el script se bloquea.
Mantenimiento periódico
26

Puedes usar easygui :

import easygui

path = easygui.fileopenbox()

Para instalar easygui, puede utilizar pip:

pip3 install easygui

Es un solo módulo Python puro ( easygui.py) que usa tkinter.

jfs
fuente
6
El proyecto easygui se ha cerrado, no se ha mantenido más; actualmente arroja un error / excepción cuando se ejecuta en Python 3.5, quizás considere otras opciones
pepe
2
@pepe: No veo ningún aviso en el repositorio del proyecto (la última confirmación es el 15 de mayo)
jfs
es bueno saberlo, gracias, tal vez alguien lo haya recogido: consulte easygui.wordpress.com/2013/03/06/easygui-project-shuts-down-2
pepe
@Zanam obviamente funciona. Pero podría haber errores .
jfs
Si tienen problemas con el combo tkinter + matplotlib, ¡puede salvarles el día!
Cuong Truong Huy
20

Prueba con wxPython :

import wx

def get_path(wildcard):
    app = wx.App(None)
    style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
    dialog = wx.FileDialog(None, 'Open', wildcard=wildcard, style=style)
    if dialog.ShowModal() == wx.ID_OK:
        path = dialog.GetPath()
    else:
        path = None
    dialog.Destroy()
    return path

print get_path('*.txt')
FogleBird
fuente
5

Si no necesita la IU o espera que el programa se ejecute en una CLI, puede analizar la ruta del archivo como argumento. Esto le permitiría utilizar la función de autocompletar de su CLI para encontrar rápidamente el archivo que necesita.

Esto probablemente solo sea útil si el script no es interactivo además de la entrada de ruta de archivo.

SQDK
fuente
Esta es una solución válida, aunque me siento triste por dentro cada vez que tengo que usar la línea de comandos de Windows. Estoy en un entorno Windows.
Buttons840
2
Veo. La CLI en Windows es tan mala en comparación con Unix. Veo por qué un selector de archivos sería genial. Supongo que tal vez arrastrar y soltar el archivo en el script y luego leer el nombre del archivo como argumento. ( mindlesstechnology.wordpress.com/2008/03/29/… ) Eso lo haría mucho más fácil si no implica copiar físicamente el archivo primero. No estoy en un cajero automático de Windows, así que no puedo probar cómo se comporta. Puede implementar fácilmente el truco del registro en un archivo .reg si necesita instalarlo en varias máquinas.
SQDK
Alternativamente, puede hacer que un archivo .bat pase el nombre del archivo al script como argumento. Esto no implica ningún truco de registro.
SQDK
1

pywin32proporciona acceso a la GetOpenFileNamefunción win32. Del ejemplo

import win32gui, win32con, os

filter='Python Scripts\0*.py;*.pyw;*.pys\0Text files\0*.txt\0'
customfilter='Other file types\0*.*\0'
fname, customfilter, flags=win32gui.GetOpenFileNameW(
    InitialDir=os.environ['temp'],
    Flags=win32con.OFN_ALLOWMULTISELECT|win32con.OFN_EXPLORER,
    File='somefilename', DefExt='py',
    Title='GetOpenFileNameW',
    Filter=filter,
    CustomFilter=customfilter,
    FilterIndex=0)

print 'open file names:', repr(fname)
print 'filter used:', repr(customfilter)
print 'Flags:', flags
for k,v in win32con.__dict__.items():
    if k.startswith('OFN_') and flags & v:
        print '\t'+k
Kevin Smyth
fuente
1

Usando tkinter (python 2) o Tkinter (python 3), de hecho es posible mostrar el diálogo de apertura de archivos (vea otras respuestas aquí). Sin embargo, tenga en cuenta que la interfaz de usuario de ese cuadro de diálogo está desactualizada y no corresponde a los cuadros de diálogo de apertura de archivos más nuevos disponibles en Windows 10.

Además, si está buscando la forma de incrustar el soporte de Python en su propia aplicación, pronto descubrirá que la biblioteca tkinter no es código fuente abierto y más aún, es una biblioteca comercial.

(Por ejemplo, la búsqueda de "precios de activetcl" lo llevará a esta página web: https://reviews.financesonline.com/p/activetcl/ )

Entonces, la biblioteca tkinter costará dinero para cualquier aplicación que desee incrustar Python.

Yo solo logré encontrar la biblioteca pythonnet:

(Licencia MIT)

Con el siguiente comando es posible instalar pythonnet:

pip3 install pythonnet

Y aquí puede encontrar un ejemplo de trabajo para usar el diálogo de archivo abierto:

https://stackoverflow.com/a/50446803/2338477

Déjame copiar un ejemplo también aquí:

import sys
import ctypes
co_initialize = ctypes.windll.ole32.CoInitialize
#   Force STA mode
co_initialize(None)

import clr 

clr.AddReference('System.Windows.Forms')

from System.Windows.Forms import OpenFileDialog

file_dialog = OpenFileDialog()
ret = file_dialog.ShowDialog()
if ret != 1:
    print("Cancelled")
    sys.exit()

print(file_dialog.FileName)

Si también echa de menos una interfaz de usuario más compleja, consulte la demostración echas de carpeta en pythonnet git.

No estoy seguro acerca de la portabilidad a otros sistemas operativos, no lo he intentado, pero .net 5 está planeado para ser portado a múltiples sistemas operativos (busque "plataformas .net 5", https://devblogs.microsoft.com/dotnet/introducing -net-5 / ) - por lo que esta tecnología también está preparada para el futuro.

TarmoPikaro
fuente