Python'da hızlı ve kolay dosya diyaloğu?


105

Bir dosyayı ayrıştıran ve içeriğini bir veritabanına yükleyen basit bir komut dosyam var. Bir kullanıcı arayüzüne ihtiyacım yok, ancak şu anda kullanıcıdan dosyayı ayrıştırmasını istiyorum raw_inputki bu en düşmanca olanı, özellikle de kullanıcı yolu kopyalayıp yapıştıramadığı için. Kullanıcıya bir dosya seçimi diyalogu sunmanın hızlı ve kolay bir yolunu istiyorum, dosyayı seçebilirler ve sonra veritabanına yüklenir. (Benim kullanım durumumda, yanlış dosyayı seçerlerse, ayrıştırmada başarısız olur ve veritabanına yüklenmiş olsa bile sorun olmaz.)

import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()

Bu kod istediğim şeye yakın, ancak can sıkıcı boş bir çerçeve açık bırakıyor (muhtemelen kapatılamaz, çünkü bir yakın olay işleyicisi kaydetmemiştim).

TkInter kullanmak zorunda değilim, ancak Python standart kitaplığında olduğu için en hızlı ve en kolay çözüm için iyi bir aday.

Başka bir kullanıcı arayüzü olmadan bir komut dosyasında bir dosya veya dosya adı istemenin hızlı ve kolay yolu nedir?


Küçük düzeltme: Metin alanına sağ tıklayıp bağlam menüsünden "Yapıştır" ı seçerek bir terminale yapıştırabilirsiniz (Windows'taymışsınız gibi görünür).
Deestan

1
Python raw_input komut isteminde sağ tıklama menüsü yoktur.
Buttons840

2
raw_input, sağ tıklama menüsüne sahip terminalde gerçekleşir.
Deestan

Yanıtlar:


205

Başka bağımlılıklara sahip olmak istemiyorsanız Tkinter en kolay yoldur. Diğer GUI öğeleri olmadan yalnızca iletişim kutusunu göstermek için, withdrawyöntemi kullanarak kök pencereyi gizlemeniz gerekir :

import tkinter as tk
from tkinter import filedialog

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

file_path = filedialog.askopenfilename()

Python 2 çeşidi:

import Tkinter, tkFileDialog

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

file_path = tkFileDialog.askopenfilename()

3
Kabul edilen cevap bu olmalıdır. Bu basit, etkili ve defalarca yeni Tk kök pencereleri oluşturmadığınız sürece sorun değil (ve bu konuya rastladığımda tam olarak aradığım yanıtın bu olduğundan bahsetmiyorum bile).
Andrew

2
Bunu işim için de kullandım. Fedora'da iyi çalışıyor, ancak Ubuntu'da takip eden tüm matplotlib rakamlarını karıştırıyor. Pylab.show () işleminden hemen sonra kilitleniyor. Hala terminalde yazabiliyorum, ancak hiçbir şey olmuyor. Ayrıca programım için cpu% 0'a gidiyor. Herhangi bir tavsiye?
Diana

17
Python3'te:tkinter.filedialog.askopenfilename()
jfs

10
Python2 üzerinde: import Tkinter as tkve import tkFileDialogvefile_path = tkFileDialog.askopenfilename()
SaschaH

9
Bu, MacOS'ta iyi çalışmaz: iletişim kutusu açılır ancak yanıt vermez hale gelir ve tüm komut dosyası kilitlenir.
Periyodik Bakım

26

Easygui'yi kullanabilirsiniz :

import easygui

path = easygui.fileopenbox()

Yüklemek için easyguişunları kullanabilirsiniz pip:

pip3 install easygui

easygui.pyKullanan tek bir saf Python modülüdür ( ) tkinter.


6
easygui projesi kapandı, daha fazla sürdürülmedi - şu anda Python 3.5 üzerinde çalışırken bir hata / istisna atıyor, belki diğer seçenekleri göz önünde bulundurun
pepe

2
@pepe: Proje deposunda herhangi bir bildirim görmüyorum (son taahhüt 15 Mayıs)
jfs

bilmek güzel, thx, belki birisi onu aldı: bakınız easygui.wordpress.com/2013/03/06/easygui-project-shuts-down-2
pepe

@Zanam belli ki işe yarıyor. Ancak böcekler olabilir .
jfs

Eğer tkinter + matplotlib combo ile sorun yaşıyorsanız, gününüzü kurtarabilir!
Cuong Truong Huy

20

WxPython ile deneyin :

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

Kullanıcı arayüzüne ihtiyacınız yoksa veya programın bir CLI'de çalışmasını beklemiyorsanız, dosya yolunu bir bağımsız değişken olarak ayrıştırabilirsiniz. Bu, ihtiyacınız olan dosyayı hızlı bir şekilde bulmak için CLI'nizin otomatik tamamlama özelliğini kullanmanıza olanak tanır.

Bu, muhtemelen yalnızca komut dosyası dosya yolu girdisinin yanı sıra etkileşimli değilse kullanışlı olacaktır.


Bu geçerli bir çözüm, ancak Windows komut satırını her kullanmam gerektiğinde içimden üzülüyorum. Windows ortamındayım.
Buttons840

2
Anlıyorum. Windows'taki CLI, Unix'e kıyasla çok kötü. Bir dosya seçicinin neden harika olduğunu anlıyorum. Sanırım dosyayı betiğe sürükleyip bırakıp ardından dosya adını argüman olarak okumak? ( mindlesstechnology.wordpress.com/2008/03/29/… ) Dosyayı önce fiziksel olarak kopyalamayı içermiyorsa, bu çok daha kolay olacaktır. Windows kutu ATM'de değilim, bu yüzden nasıl davrandığını test edemiyorum. Birkaç makineye yüklemeniz gerekirse, kayıt defteri hackini bir .reg dosyasına kolayca dağıtabilirsiniz.
SQDK

Alternatif olarak, bir .bat dosyasının dosya adını betiğe argüman olarak iletmesini sağlayabilirsiniz. Bu, herhangi bir kayıt defteri hackini içermez.
SQDK

3

Tkinter (python 2) veya Tkinter (python 3) kullanarak dosya açma iletişim kutusunu görüntülemek gerçekten mümkündür (Diğer yanıtlara buradan bakın). Ancak, bu iletişim kutusunun kullanıcı arayüzünün güncel olmadığını ve Windows 10'da bulunan daha yeni dosya açma iletişim kutularına karşılık gelmediğini lütfen unutmayın.

Dahası - python desteğini kendi uygulamanıza yerleştirmenin yolunu arıyorsanız - yakında tkinter kitaplığının açık kaynak kod olmadığını ve hatta daha fazlasını - ticari kitaplık olduğunu göreceksiniz.

(Örneğin "activetcl fiyatlandırması" araması sizi şu web sayfasına götürecektir: https://reviews.financesonline.com/p/activetcl/ )

Bu nedenle tkinter kitaplığı, python'u gömmek isteyen herhangi bir uygulama için paraya mal olacaktır.

Kendi başıma pythonnet kitaplığı bulmayı başardım:

(MIT Lisansı)

Aşağıdaki komutu kullanarak pythonnet kurmak mümkündür:

pip3 install pythonnet

Ve burada açık dosya iletişim kutusunu kullanmak için bir çalışma örneği bulabilirsiniz:

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

Burada da bir örnek kopyalayayım:

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)

Daha karmaşık kullanıcı arayüzünü de kaçırırsanız - bkz . Pythonnet git içindeki Demo klasörü.

Diğer işletim sistemlerine taşınabilirlik konusunda emin değilim, denemedim, ancak .net 5'in birden çok işletim sistemine taşınması planlanıyor (Arama ".net 5 platformları", https://devblogs.microsoft.com/dotnet/introducing -net-5 / ) - bu nedenle bu teknoloji geleceğin de kanıtıdır.


2

pywin32GetOpenFileNamewin32 işlevine erişim sağlar . Gönderen Örneğin

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

Bu, mevcut çalışma dizinimi, dosyaların seçildiği dizine değiştirdi. Bu durumda ne yapmalı?
Mooncrater

Eklemek @Mooncrater |win32con.OFN_NOCHANGEDIRiçin Flags, ancak uyarı dikkat stackoverflow.com/questions/50468051/...
Kevin Smyth

Hey, öneri için teşekkürler. Sonunda yaptığım şey, her kullandığımda orijinal dizine geri dönmekti GetOpenFileNameW.
Mooncrater

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.