Швидкий та простий діалог файлів у Python?


104

У мене простий скрипт, який аналізує файл і завантажує його вміст у базу даних. Мені не потрібен інтерфейс користувача, але зараз я спонукаю користувача до розбору файлу, використовуючи raw_inputякий є непривітним, тим більше, що користувач не може скопіювати / вставити шлях. Мені б хотілося, щоб швидкий і простий спосіб представити користувачеві діалогове вікно вибору файлів, він може вибрати файл, а потім завантажується в базу даних. (У моєму випадку використання, якщо вони трапили неправильний файл, він би не зміг розбору, і це не складе проблем, навіть якщо він був завантажений у базу даних.)

import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()

Цей код близький до того, що я хочу, але він залишає роздратованим порожній кадр відкритим (який неможливо закрити, можливо, тому, що я не зареєстрував обробника подій закриття).

Мені не потрібно використовувати tkInter, але оскільки він знаходиться в стандартній бібліотеці Python, це хороший кандидат для швидкого та найпростішого рішення.

Який швидкий та простий спосіб запросити файл чи ім’я файлу у сценарії без іншого інтерфейсу?


Незначне виправлення: Ви можете вставити термінал (це здається, що ви перебуваєте в Windows), клацнувши правою кнопкою миші в текстовій області та вибравши "Вставити" у контекстному меню.
Діестан

1
Немає меню правої кнопки миші в запиті Python raw_input.
Кнопки840

2
raw_input відбувається в терміналі, в якому є меню клацання правою кнопкою миші.
Діестан

Відповіді:


200

Tkinter - це найпростіший спосіб, якщо ви не хочете мати інших залежностей. Щоб показати лише діалогове вікно без будь-яких інших елементів графічного інтерфейсу, вам потрібно приховати кореневе вікно за допомогою withdrawметоду:

import tkinter as tk
from tkinter import filedialog

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

file_path = filedialog.askopenfilename()

Варіант Python 2:

import Tkinter, tkFileDialog

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

file_path = tkFileDialog.askopenfilename()

3
Це має бути прийнятою відповіддю. Це просто, ефективно, і поки ви не створюєте нові кореневі вікна Tk знову і знову, це добре (і не кажучи вже про те, що це саме відповідь, яку я шукав, коли натрапив на цю нитку).
Андрій

2
Я просто використав це для своєї роботи. Це добре працює на Fedora, але на Ubuntu він переплутує будь-які фігури matplotlib, які випливають за цим. Значно після pylab.show () він висить. Я все ще можу набрати термінал, але нічого не відбувається. Також процесор іде до 0% для моєї програми. Будь-яка порада?
Діана

17
На python3:tkinter.filedialog.askopenfilename()
jfs

10
На python2: import Tkinter as tkі import tkFileDialogіfile_path = tkFileDialog.askopenfilename()
SaschaH

8
Це не добре працює на MacOS: діалогове вікно відкривається, але стає невідповідальним і весь сценарій зависає.
Періодичне обслуговування

26

Ви можете використовувати easygui :

import easygui

path = easygui.fileopenbox()

Щоб встановити easygui, ви можете використовувати pip:

pip3 install easygui

Це єдиний чистий модуль Python ( easygui.py), який використовує tkinter.


6
Проект easygui закрився, не підтримується далі - він наразі видає помилку / виняток під час запуску на Python 3.5, можливо, врахуйте інші варіанти
pepe

2
@pepe: Я не бачу жодного повідомлення у сховищі проектів (остання
комісія

Добре знати, THX, можливо, хтось підхопив його: див. easygui.wordpress.com/2013/03/06/easygui-project-shuts-down-2
pepe

@Zanam очевидно, що це працює. Але можуть бути помилки .
jfs

Якщо у вас є проблеми з комбінацією tkinter + matplotlib, це може врятувати ваш день!
Cuong Truong Huy

20

Спробуйте з 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

Якщо вам не потрібен інтерфейс користувача або очікується, що програма запуститься в CLI, ви можете проаналізувати файловий шлях як аргумент. Це дозволить вам скористатися функцією автозаповнення вашого CLI для швидкого пошуку потрібного файлу.

Це, ймовірно, стане в нагоді лише в тому випадку, якщо сценарій не є інтерактивним, окрім вхідного файлу.


Це правильне рішення, хоча мені всередині все сумно, коли мені доводиться використовувати командний рядок Windows. Я в середовищі Windows.
Кнопки840

2
Я бачу. CLI в Windows настільки поганий порівняно з Unix. Я бачу, чому інструмент для вибору файлів був би акуратним. Я думаю, може перетягнути файл на сценарій, а потім прочитати ім'я файлу як аргумент? ( mindlesstechnology.wordpress.com/2008/03/29/… ) Це значно полегшить ситуацію, якщо спочатку це не буде фізично копіювати файл. Я не в банкоматі Windows box, тому не можу перевірити, як він себе веде. Ви можете легко розгорнути хак реєстру у файлі .reg, якщо вам потрібно встановити його на декількох машинах.
SQDK

Крім того, ви можете мати .bat файл передавати ім'я файлу в сценарій як аргумент. Це не передбачає жодних злому реєстру.
SQDK

2

Ознайомтеся з EasyGUI, дуже простим у користуванні модулем, який повинен зробити цю роботу - http://easygui.sourceforge.net/

Ви б використовували функцію fileopenbox, детально описану на цій сторінці документації api - https://easygui.readthedocs.io/en/latest/api.html


1
Вибачте - на своєму телефоні, тому я не можу навести приклад. Ви хочете , щоб використовувати fileopenbox - ferg.org/easygui/easygui.html#-fileopenbox
ТММК

Друга ланка розірвана.
Томас Ендрюс

1

pywin32забезпечує доступ до функції GetOpenFileNamewin32. З прикладу

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

За допомогою tkinter (python 2) або Tkinter (python 3) дійсно можливо відобразити діалогове вікно відкритого файлу (Див. Інші відповіді тут). Однак зауважте, що користувальницький інтерфейс цього діалогового вікна застарів і не відповідає більш новим діалогам відкриття файлів, доступним у Windows 10.

Більше того - якщо ви шукаєте спосіб вбудувати підтримку python у свій власний додаток - ви незабаром дізнаєтесь, що бібліотека tkinter не є відкритим вихідним кодом і навіть більше - це комерційна бібліотека.

(Наприклад, пошук "ціни на Activetcl" призведе вас до цієї веб-сторінки: https://reviews.financesonline.com/p/activetcl/ )

Тож бібліотека tkinter обійдеться за будь-яку програму, яка хоче вбудувати python.

Мені самому вдалося знайти бібліотеку pythonnet:

(Ліцензія MIT)

За допомогою наступної команди можна встановити pythonnet:

pip3 install pythonnet

І тут ви можете дізнатися робочий приклад використання діалогового вікна відкритого файлу:

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

Дозвольте скопіювати приклад також тут:

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)

Якщо ви також пропустите більш складний інтерфейс користувача - див. Демо папку в pythonnet git.

Я не впевнений у переносимості інших ОС, не пробував, але .net 5 планується перенести на кілька ОС (Пошук "платформ .net 5", https://devblogs.microsoft.com/dotnet/introducing -net-5 / ) - тому ця технологія також є підтвердженням у майбутньому.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.