2012-02-11 13 views
30

Estoy trabajando por primera vez en la codificación de un botón Examinar para un programa en Python3. He estado buscando en Internet y en este sitio, e incluso en la biblioteca estándar de Python.filedialog, tkinter y archivos de apertura

He encontrado ejemplos de código y explicaciones muy superficiales de cosas, pero no he podido encontrar nada que resuelva el problema que tengo directamente, o una explicación suficientemente buena para poder personalizar el código a mis necesidades.

Aquí es el fragmento relevante:

Button(self, text = "Browse", command = self.load_file, width = 10)\ 
     .grid(row = 1, column = 0, sticky = W) ..... 


def load_file(self): 

    filename = filedialog.askopenfilename(filetypes = (("Template files", "*.tplate") 
                 ,("HTML files", "*.html;*.htm") 
                 ,("All files", "*.*"))) 
    if filename: 
     try: 
      self.settings["template"].set(filename) 
     except: 
      messagebox.showerror("Open Source File", "Failed to read file \n'%s'"%filename) 
      return 

El método es un híbrido de un cierto código que encontré en el camino con mis propias personalizaciones. Parece que finalmente lo hice funcionar (un poco), aunque no es exactamente como lo necesito.

Recibo este error cuando activo el botón 'Examinar': NameError: global name 'filedialog' is not defined.

He encontrado problemas bastante similares en el camino, pero todas las soluciones sugeridas que he cubierto. Entré en la sección de ayuda de 'archivo de diálogo' de IDLE pero tampoco obtuve nada de allí.

¿A alguien le importaría proporcionar un desglose y un poco de orientación sobre esto; ninguno de mis libros lo aborda específicamente, y he comprobado todas las soluciones proporcionadas a otros: estoy perdido.

+3

¿Lo ha importado? 'from tkinter import filedialog' –

Respuesta

50

La excepción se obtiene le está diciendo filedialog no está en el espacio de nombres. filedialog (y por cierto messagebox) es un módulo tkinter, por lo que no se importa simplemente con from tkinter import *

>>> from tkinter import * 
>>> filedialog 
Traceback (most recent call last): 
    File "<interactive input>", line 1, in <module> 
NameError: name 'filedialog' is not defined 
>>> 

se debe utilizar por ejemplo:

>>> from tkinter import filedialog 
>>> filedialog 
<module 'tkinter.filedialog' from 'C:\Python32\lib\tkinter\filedialog.py'> 
>>> 

o

>>> import tkinter.filedialog as fdialog 

o

>>> from tkinter.filedialog import askopenfilename 

Así que esto haría para su botón de exploración:

from tkinter import * 
from tkinter.filedialog import askopenfilename 
from tkinter.messagebox import showerror 

class MyFrame(Frame): 
    def __init__(self): 
     Frame.__init__(self) 
     self.master.title("Example") 
     self.master.rowconfigure(5, weight=1) 
     self.master.columnconfigure(5, weight=1) 
     self.grid(sticky=W+E+N+S) 

     self.button = Button(self, text="Browse", command=self.load_file, width=10) 
     self.button.grid(row=1, column=0, sticky=W) 

    def load_file(self): 
     fname = askopenfilename(filetypes=(("Template files", "*.tplate"), 
              ("HTML files", "*.html;*.htm"), 
              ("All files", "*.*"))) 
     if fname: 
      try: 
       print("""here it comes: self.settings["template"].set(fname)""") 
      except:      # <- naked except is a bad idea 
       showerror("Open Source File", "Failed to read file\n'%s'" % fname) 
      return 


if __name__ == "__main__": 
    MyFrame().mainloop() 

enter image description here

+2

Gracias. Ya sabes, me metí con la importación de los dos de tkinter (simplemente no lo entendía del todo bien), y como no estaba obteniendo exactamente lo correcto, estaba acreditando mi error en algún lugar donde no estaba cometiendo un error. Mi pregunta es: pensé que 'de tkinter import *' importó TODO de tkinter. Entonces, ¿por qué estos tienen que ser importados por separado? ¿Puede indicarme alguna documentación sobre esto? Gracias de nuevo – Icsilk

+0

No encontré ningún enlace con explicación simple, al punto. Quizás tengas más suerte. Verifique primero python [referencia] (http: // docs.python.org/reference/simple_stmts.html#the-import-statement) y [docs] (http://docs.python.org/tutorial/modules.html#packages) – joaquin

+0

La primera frase de esta solución te dice por qué necesito las dos declaraciones filedialog es un módulo, por lo que no se importa con "from tkinter import *" y se debe importar por separado. – RufusVS

3

¿Intentó agregar el prefijo automático al fileName y reemplazar el método que se encuentra sobre el botón? Con uno mismo, se vuelve visible entre los métodos.

... 

def load_file(self): 
    self.fileName = filedialog.askopenfilename(filetypes = (("Template files", "*.tplate") 
                ,("HTML files", "*.html;*.htm") 
                ,("All files", "*.*"))) 
... 
0

tuviera que especificar los comandos individuales primero y luego usar el * para llevar todo en orden.

from tkinter import filedialog 
from tkinter import * 
+0

"desde tkinter archivo de archivo de importación"
"desde tkinter import *" – James

Cuestiones relacionadas