¿Cómo puedo usar el mismo cuadro de diálogo en Tkinter para buscar y seleccionar archivos y directorios?

Estoy utilizando Tkinter para crear una GUI para un script de python. Necesito un botón que abre un cuadro de diálogo que me permite seleccionar archivos y directorios. Hasta ahora, me he encontrado

tkFileDialog.askdirectory(parent=root, title=dirtext1) 

que permite simplemente seleccionar directorios en el cuadro de diálogo y,

 tkFileDialog.askopenfilename(parent=root, title=filetext) 

lo que me permite simplemente seleccionar archivos. A partir de ahora, accedo a estos cuadros de diálogo utilizando botones separados, cada uno de los cuales llama a una de estas funciones. ¿Hay alguna forma de seleccionar un archivo o una carpeta usando un solo cuadro de diálogo?

No lo creo. No hay una clase incorporada para hacerlo fácilmente

Investigación

Si observa el código fuente del módulo tkFileDialog , las clases Open y Directory heredan de _Dialog , ubicado en tkCommonDialog .

Bien hasta ahora; Estas clases son simples y solo extienden dos métodos. _fixresult es un gancho que filtra según sus opciones (prometedoras), y _fixoptions agrega los parámetros tcl correctos (como el directorio inicial).

Pero cuando llegamos a la clase Dialog (padre de _Dialog), vemos que llama a un comando tcl por un nombre dado. Los nombres incorporados son “tk_getOpenFile” y “tk_chooseDirectory”. No tenemos mucha libertad de comando a nivel de python después de esto. Si vamos a ver qué otros scripts están disponibles, estamos decepcionados .

Parece que tus opciones son

  • ttk::getOpenFile
  • ttk::getSaveFile
  • ttk::chooseDirectory
  • ttk::getAppendFile

Conclusión

Ratas Afortunadamente, debería ser bastante fácil para usted crear su propio cuadro de diálogo utilizando los cuadros de lista, los campos de entrada, el botón (y otros elementos integrados) y el módulo OS.

Alternativa simple

A partir de sus comentarios, parece que una solución simple y viable podría ser utilizar

 directory = os.path.dirname(os.path.realpath(tkFileDialog.askopenfilename())) 

Tendrán que seleccionar un archivo, pero el botón “Abrir” “devolverá una ruta”, en el sentido de que la ruta se calcula desde la ubicación del archivo

¡Pero realmente lo quiero!

Si por alguna razón realmente desea este comportamiento pero no desea rehacer el widget, puede llamar a los scripts tcl directamente. Puede ser posible copiar el código de getOpenFile y proporcionar argumentos más sueltos que permitan seleccionar un objeto más genérico. Esta no es mi especialidad y parece una muy mala idea, pero aquí es cómo puede llamar directamente a tcl y aquí es donde puede obtener más información sobre los comandos subyacentes.

He tenido un problema similar. Al final, utilicé askopenfilename s () (plural) y dividí la ruta de los archivos. Luego, con un botón de radio, pídale al usuario que elija si desea procesar todos los archivos en el directorio, o solo los que seleccionó.

 filetypes = [('All files', '*.*'), ('CSV files', '*.csv'),] data_list = askopenfilenames(title='Select folder', filetypes=filetypes) data_dir = data_list[0].rsplit('/', 1)[0] 

Lo menciono porque askopenfilename s () no se sugiere mucho, pero está más cerca de seleccionar una carpeta, al igual que ctrl + A todos los archivos.