Finestra di dialogo file semplice e veloce in Python?


104

Ho un semplice script che analizza un file e carica il suo contenuto in un database. Non ho bisogno di un'interfaccia utente, ma in questo momento sto chiedendo all'utente di analizzare il file usando quello raw_inputche è più ostile, soprattutto perché l'utente non può copiare / incollare il percorso. Vorrei un modo semplice e veloce per presentare una finestra di dialogo per la selezione dei file all'utente, possono selezionare il file e quindi viene caricato nel database. (Nel mio caso d'uso, se gli fosse capitato di scegliere il file sbagliato, l'analisi non avrebbe avuto esito positivo e non sarebbe stato un problema anche se fosse stato caricato nel database.)

import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()

Questo codice è vicino a quello che voglio, ma lascia aperto un fastidioso frame vuoto (che non può essere chiuso, probabilmente perché non ho registrato un gestore di eventi di chiusura).

Non devo usare tkInter, ma poiché è nella libreria standard di Python è un buon candidato per la soluzione più rapida e semplice.

Qual è un modo semplice e veloce per richiedere un file o un nome file in uno script senza altre interfacce utente?


Correzione minore: puoi incollare in un terminale (sembra che tu sia su Windows) facendo clic con il pulsante destro del mouse nell'area di testo e selezionando "Incolla" dal menu contestuale.
Deestan

1
Nessun menu di scelta rapida è disponibile in un prompt raw_input di Python.
Buttons840

2
raw_input avviene nel terminale, che ha un menu di scelta rapida.
Deestan

Risposte:


200

Tkinter è il modo più semplice se non vuoi avere altre dipendenze. Per mostrare solo la finestra di dialogo senza altri elementi della GUI, devi nascondere la finestra principale utilizzando il withdrawmetodo:

import tkinter as tk
from tkinter import filedialog

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

file_path = filedialog.askopenfilename()

Variante Python 2:

import Tkinter, tkFileDialog

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

file_path = tkFileDialog.askopenfilename()

3
Questa dovrebbe essere la risposta accettata. È semplice, efficace e fintanto che non crei continuamente nuove finestre di root Tk, va bene (e per non parlare del fatto che è esattamente la risposta che stavo cercando quando mi sono imbattuto in questo thread).
Andrew

2
L'ho usato anche per il mio lavoro. Funziona bene su Fedora, ma su Ubuntu rovina tutte le figure matplotlib che seguono. Praticamente dopo pylab.show () si blocca. Sono ancora in grado di digitare nel terminale, ma non succede nulla. Anche la CPU va allo 0% per il mio programma. Qualche consiglio?
Diana

17
Su python3:tkinter.filedialog.askopenfilename()
jfs

10
Su python2: import Tkinter as tke import tkFileDialogefile_path = tkFileDialog.askopenfilename()
SaschaH

8
Questo non funziona bene su MacOS: la finestra di dialogo si apre ma non risponde e l'intero script si blocca.
Manutenzione periodica

26

Puoi usare easygui :

import easygui

path = easygui.fileopenbox()

Per installare easyguipuoi usare pip:

pip3 install easygui

È un singolo modulo Python puro ( easygui.py) che utilizza tkinter.


6
Il progetto easygui è stato chiuso, non ulteriormente mantenuto - attualmente genera un errore / eccezione durante l'esecuzione su Python 3.5, forse considera altre opzioni
pepe

2
@pepe: non vedo alcun avviso nel repository del progetto (l'ultimo commit è il 15 maggio)
jfs

Buono a sapersi, grazie, forse qualcuno l'ha preso: vedi easygui.wordpress.com/2013/03/06/easygui-project-shuts-down-2
pepe

@Zanam ovviamente funziona. Ma potrebbero esserci degli insetti .
jfs

Se avete problemi con la combinazione tkinter + matplotlib, può salvarvi la giornata!
Cuong Truong Huy

20

Prova 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')

5

Se non è necessaria l'interfaccia utente o si prevede che il programma venga eseguito in una CLI, è possibile analizzare il percorso del file come argomento. Ciò ti consentirebbe di utilizzare la funzione di completamento automatico della tua CLI per trovare rapidamente il file di cui hai bisogno.

Questo probabilmente sarebbe utile solo se lo script non è interattivo oltre all'input del percorso file.


Questa è una soluzione valida, anche se mi sento triste dentro ogni volta che devo usare la riga di comando di Windows. Sono in un ambiente Windows.
Buttons840

2
Vedo. La CLI in Windows è così pessima rispetto a Unix. Capisco perché un selettore di file sarebbe pulito. Immagino che forse trascini il file sullo script e poi leggi il nome del file come argomento? ( mindlesstechnology.wordpress.com/2008/03/29/… ) Ciò renderebbe molto più semplice se non implicasse prima la copia fisica del file. Non sono su un bancomat Windows box quindi non posso testare come si comporta. È possibile distribuire facilmente l'hack del registro in un file .reg se è necessario installarlo su più macchine.
SQDK

In alternativa puoi fare in modo che un file .bat passi il nome del file allo script come argomento. Ciò non comporta alcun hack del registro.
SQDK

2

Dai un'occhiata a EasyGUI, un modulo molto facile da usare che dovrebbe fare il lavoro - http://easygui.sourceforge.net/

Dovresti utilizzare la funzione fileopenbox descritta in questa pagina di documentazione api: https://easygui.readthedocs.io/en/latest/api.html


1
Mi dispiace, sul mio telefono quindi non posso fare un esempio. Si desidera che l'all'utilizzo fileopenbox - ferg.org/easygui/easygui.html#-fileopenbox
TimC

Il secondo collegamento è interrotto.
Thomas Andrews,

1

pywin32fornisce l'accesso alla GetOpenFileNamefunzione win32. Dal esempio

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

1

Utilizzando tkinter (python 2) o Tkinter (python 3) è effettivamente possibile visualizzare la finestra di dialogo di apertura dei file (vedere altre risposte qui). Si noti tuttavia che l'interfaccia utente di quella finestra di dialogo è obsoleta e non corrisponde alle nuove finestre di dialogo di apertura dei file disponibili in Windows 10.

Inoltre, se stai cercando di incorporare il supporto python nella tua applicazione, scoprirai presto che la libreria tkinter non è un codice open source e, ancora di più, è una libreria commerciale.

(Ad esempio, la ricerca di "activetcl pricing" ti porterà a questa pagina web: https://reviews.financesonline.com/p/activetcl/ )

Quindi la libreria tkinter costerà denaro per qualsiasi applicazione che desideri incorporare python.

Da solo sono riuscito a trovare la libreria di pythonnet:

(Licenza MIT)

Utilizzando il seguente comando è possibile installare pythonnet:

pip3 install pythonnet

E qui puoi trovare un esempio funzionante per l'utilizzo della finestra di dialogo Apri file:

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

Fammi copiare un esempio anche qui:

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)

Se ti manca anche un'interfaccia utente più complessa, consulta la cartella Demo in pythonnet git.

Non sono sicuro della portabilità su altri sistemi operativi, non ho provato, ma .net 5 è pianificato per essere trasferito su più sistemi operativi (Cerca "piattaforme .net 5", https://devblogs.microsoft.com/dotnet/introducing -net-5 / ) - quindi questa tecnologia è anche a prova di futuro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.