กล่องโต้ตอบไฟล์ที่ง่ายและรวดเร็วใน Python?


105

ฉันมีสคริปต์ง่ายๆที่แยกวิเคราะห์ไฟล์และโหลดเนื้อหาลงในฐานข้อมูล ฉันไม่ต้องการ UI แต่ตอนนี้ฉันกำลังแจ้งให้ผู้ใช้ให้ไฟล์แยกวิเคราะห์โดยใช้raw_inputสิ่งที่ไม่เป็นมิตรที่สุดโดยเฉพาะอย่างยิ่งเนื่องจากผู้ใช้ไม่สามารถคัดลอก / วางเส้นทางได้ ฉันต้องการวิธีที่ง่ายและรวดเร็วในการนำเสนอกล่องโต้ตอบการเลือกไฟล์ให้กับผู้ใช้พวกเขาสามารถเลือกไฟล์จากนั้นโหลดไปยังฐานข้อมูล (ในกรณีการใช้งานของฉันหากพวกเขาเลือกไฟล์ผิดมันจะไม่สามารถแยกวิเคราะห์ได้และจะไม่มีปัญหาแม้ว่าจะโหลดไปยังฐานข้อมูลก็ตาม)

import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()

รหัสนี้ใกล้เคียงกับสิ่งที่ฉันต้องการ แต่ปล่อยให้เฟรมว่างเปล่าที่น่ารำคาญเปิดอยู่ (ซึ่งไม่สามารถปิดได้อาจเป็นเพราะฉันไม่ได้ลงทะเบียนตัวจัดการเหตุการณ์แบบปิด)

ฉันไม่จำเป็นต้องใช้ tkInter แต่เนื่องจากมันอยู่ในไลบรารีมาตรฐานของ Python จึงเป็นตัวเลือกที่ดีสำหรับวิธีแก้ปัญหาที่รวดเร็วและง่ายที่สุด

อะไรคือวิธีที่ง่ายและรวดเร็วในการขอไฟล์หรือชื่อไฟล์ในสคริปต์โดยไม่มี UI อื่น ๆ


การแก้ไขเล็กน้อย: คุณสามารถวางลงในเทอร์มินัล (ดูเหมือนว่าคุณใช้ Windows) โดยคลิกขวาในพื้นที่ข้อความแล้วเลือก "วาง" จากเมนูบริบท
Deestan

1
ไม่มีเมนูคลิกขวาในพรอมต์ Python raw_input
ปุ่ม 840

2
raw_input เกิดขึ้นในเทอร์มินัลซึ่งมีเมนูคลิกขวา
Deestan

คำตอบ:


205

Tkinter เป็นวิธีที่ง่ายที่สุดหากคุณไม่ต้องการมีการอ้างอิงอื่น ๆ หากต้องการแสดงเฉพาะกล่องโต้ตอบโดยไม่มีองค์ประกอบ GUI อื่น ๆ คุณต้องซ่อนหน้าต่างรูทโดยใช้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 ใหม่ซ้ำแล้วซ้ำเล่าก็ใช้ได้ (และไม่ต้องพูดถึงว่ามันเป็นคำตอบที่ฉันกำลังมองหาเมื่อฉันเจอหัวข้อนี้)
Andrew

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

9
สิ่งนี้ใช้งานได้ไม่ดีบน 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: ฉันไม่เห็นการแจ้งเตือนใด ๆ ในที่เก็บโครงการ (คอมมิตล่าสุดคือวันที่ 15 พฤษภาคม)
jfs

น่ารู้ขอบคุณบางทีอาจมีคนหยิบไป: ดู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

หากคุณไม่ต้องการ UI หรือคาดว่าโปรแกรมจะทำงานใน CLI คุณสามารถแยกวิเคราะห์ filepath เป็นอาร์กิวเมนต์ได้ วิธีนี้จะช่วยให้คุณใช้คุณสมบัติเติมข้อความอัตโนมัติของ CLI เพื่อค้นหาไฟล์ที่คุณต้องการได้อย่างรวดเร็ว

สิ่งนี้อาจมีประโยชน์ก็ต่อเมื่อสคริปต์ไม่โต้ตอบนอกเหนือจากอินพุตพา ธ ไฟล์


นี่เป็นวิธีแก้ปัญหาที่ถูกต้องแม้ว่าฉันจะรู้สึกเศร้าทุกครั้งที่ต้องใช้บรรทัดคำสั่งของ Windows ฉันอยู่ในสภาพแวดล้อม Windows
ปุ่ม 840

2
ฉันเห็น. CLI ใน Windows แย่มากเมื่อเทียบกับ Unix ฉันเห็นว่าเหตุใดตัวเลือกไฟล์จึงต้องเรียบร้อย ฉันเดาว่าอาจจะลากและวางไฟล์ลงในสคริปต์แล้วอ่านชื่อไฟล์เป็นอาร์กิวเมนต์? ( mindlesstechnology.wordpress.com/2008/03/29/… ) ซึ่งจะทำให้ง่ายขึ้นมากหากไม่เกี่ยวข้องกับการคัดลอกไฟล์ทางกายภาพก่อน ฉันไม่ได้อยู่บนตู้ ATM ของ Windows ดังนั้นฉันจึงไม่สามารถทดสอบได้ว่ามันทำงานอย่างไร คุณสามารถปรับใช้การแฮ็กรีจิสทรีในไฟล์. reg ได้อย่างง่ายดายหากคุณต้องการติดตั้งลงในเครื่องหลายเครื่อง
SQDK

หรือคุณสามารถให้ไฟล์. bat ส่งผ่านชื่อไฟล์ไปยังสคริปต์เป็นอาร์กิวเมนต์ สิ่งนี้ไม่เกี่ยวข้องกับการแฮ็กรีจิสทรีใด ๆ
SQDK

3

การใช้ 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

ฉันไม่แน่ใจเกี่ยวกับความสามารถในการพกพาไปยัง OS อื่นยังไม่ได้ลอง แต่. net 5 มีแผนที่จะย้ายไปยัง OS หลายระบบ (ค้นหา ".net 5 แพลตฟอร์ม", https://devblogs.microsoft.com/dotnet/introducing -net-5 / ) - ดังนั้นเทคโนโลยีนี้จึงเป็นข้อพิสูจน์ในอนาคต


2

pywin32ให้การเข้าถึงGetOpenFileNameฟังก์ชัน win32 จากตัวอย่าง

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

สิ่งนี้เปลี่ยนไดเร็กทอรีการทำงานปัจจุบันของฉันเป็นไดเร็กทอรีที่จะเลือกไฟล์ จะทำอย่างไรในกรณีนั้น?
Mooncrater

@Mooncrater เพิ่ม|win32con.OFN_NOCHANGEDIRให้Flagsแต่ระวังข้อแม้stackoverflow.com/questions/50468051/…
Kevin Smyth

สวัสดีขอบคุณสำหรับข้อเสนอแนะ GetOpenFileNameWสิ่งที่ฉันจบลงด้วยการทำคือการย้อนกลับไปยังไดเรกทอรีเดิมทุกครั้งที่ผมใช้
Mooncrater

2

ลองใช้ EasyGUI ซึ่งเป็นโมดูลที่ใช้งานง่ายมากที่ควรใช้งานได้ - http://easygui.sourceforge.net/

คุณจะใช้ฟังก์ชัน fileopenbox ที่มีรายละเอียดในหน้าเอกสาร api นี้ - https://easygui.readthedocs.io/en/latest/api.html


1
ขออภัย - ในโทรศัพท์ของฉันฉันจึงไม่สามารถยกตัวอย่างได้ คุณต้องการใช้ fileopenbox - ferg.org/easygui/easygui.html#-fileopenbox
timc

ลิงค์ที่สองเสีย
Thomas Andrews
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.