2012-07-22 21 views
5

El quid de la cuestión es, ¿qué estoy haciendo mal en el siguiente fragmento de código?¿Cómo puedo mostrar una imagen en Python 3 usando tkinter/ttk?

from tkinter import * 
    from tkinter.ttk import * 

    root = Tk() 

    myButton = Button(root) 
    myImage = PhotoImage(myButton, file='myPicture.gif') 
    myButton.image = myImage 
    myButton.configure(image=myImage) 

    root.mainloop() 

El mensaje de error que recibo de idle3 es el siguiente:

>>> 
    Traceback (most recent call last): 
     File "/home/bob/Documents/Python/tkImageTest.py", line 9, in <module> 
     myButton.configure(image=myImage) 
     File "/usr/lib/python3.2/tkinter/__init__.py", line 1196, in configure 
     return self._configure('configure', cnf, kw) 
     File "/usr/lib/python3.2/tkinter/__init__.py", line 1187, in _configure 
     self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) 
    TypeError: __str__ returned non-string (type Button) 
    >>> 

Este mensaje de error me tiene perplejo, simplemente no entiendo lo que está tratando de decir. ¿Algunas ideas?

También agradecería sugerencias de cambios ...

+0

BTW Ya he comprobado esta referencia http://effbot.org/tkinterbook/photoimage.htm - Verás que mi fragmento de código es muy similar. – Bobble

+0

El error parece apuntar al argumento 'myButton' pasado a' PhotoImage() '. No creo que 'PhotoImage()' tome una referencia a un objeto widget, por lo que puede estar causando el error. Pruebe esa línea sin ella, como 'myImage = PhotoImage (file = 'myPicture.gif')' – gary

+1

@Gary, eso parece hacerlo. Una parte de la documentación (y algunos otros errores que había generado) me indujo a pensar que 'PhotoImage' necesita una referencia explícita a la ventana raíz.Después de un poco más de violín, encontré que la referencia a la raíz o al botón en sí puede ser proporcionada por otra opción de configuración en el constructor 'PhotoImage',' PhotoImage (master = myButton, file = 'myFile.gif') ', pero tal como lo escribí, a Tkinter le parece un nombre, que se supone que es una cadena, ofc. – Bobble

Respuesta

7

El error parece apuntar al argumento myButton pasado a PhotoImage. Como notó en su comentario, PhotoImage estaba tratando el objeto widget como una cadena (hay varias opciones de tipo cadena; vea una lista de opciones de PhotoImage here).

su código funcionará si la aplicación de esa línea sin hacer referencia al objeto myButton:

myImage = PhotoImage(file='myPicture.gif') 

No estoy seguro de que es necesario modificar el constructor PhotoImage. Mire los documentos PhotoImage para determinar las opciones válidas (es decir, nombres de recursos) para esa clase. Citando el archivo de ayuda:

Ayuda en PhotoImage clase en el módulo tkinter:

PhotoImage la clase (imagen)

| Widget which can display colored images in GIF, PPM/PGM format. 
|  
| Method resolution order: 
|  PhotoImage 
|  Image 
|  builtins.object 
|  
| Methods defined here: 
|  
| __getitem__(self, key) 
|  # XXX config 
|  
| __init__(self, name=None, cnf={}, master=None, **kw) 
|  Create an image with NAME. 
| 
|  Valid resource names: data, format, file, gamma, height, palette, 
|  width. 

FYI: La forma más fácil de llegar a los documentos desde Python en la línea de comando o desde IDLE:

from tkinter import PhotoImage 
help(PhotoImage) 

Y, por último, otro enlace útil sobre esta clase está en http://tkinter.unpythonic.net/wiki/PhotoImage.

+1

Muchas gracias Gary! También tiene razón acerca de la referencia 'maestra'. Eso fue un rezago de algunos experimentos que estaba haciendo con múltiples hilos (¡mejor no preguntar!). – Bobble

+0

@Bobble BTW, si esto responde la pregunta, márquelo como la respuesta aceptada (esto parece algo que puede hacer para algunas de sus preguntas). – gary

-1

He probado el ejemplo con python 2.7.9, 3.2.5, 3.3.5, 3.4.3 en 32 bits y 64 bits. (Win 8.1 64bit)

El código funciona.

(en Python 3.4.3 de 64 bits que tenían primero un mensaje de error.

He desinstalado por completo 3.4.3 y luego reinstalado.

Ahora, el ejemplo también funciona con 3.4.3 de 64 bits)

# basic code from >> 
# http://tkinter.unpythonic.net/wiki/PhotoImage 

# extra code ------------------------------------------------------------------------- 
from __future__ import print_function 

try: 
    import tkinter as tk 
except: 
    import Tkinter as tk 

import sys 
import platform 

print() 
print ('python ', sys.version) 
print ('tkinter ', tk.TkVersion) 
print() 
print (platform.platform(),' ',platform.machine()) 
print() 


# basic code ------------------------------------------------------------------------- 

root = tk.Tk() 

def create_button_with_scoped_image(): 
    # "w6.gif" >> 
    # http://www.inf-schule.de/content/software/gui/entwicklung_tkinter/bilder/w6.gif 
    img = tk.PhotoImage(file="w6.gif") # reference PhotoImage in local variable 
    button = tk.Button(root, image=img) 
    # button.img = img # store a reference to the image as an attribute of the widget 
    button.image = img # store a reference to the image as an attribute of the widget 
    button.grid() 

create_button_with_scoped_image() 

tk.mainloop() 
+0

¿Estás seguro de que es una respuesta, y más específicamente una respuesta para python-3.x? – Deduplicator

+0

Una buena respuesta no es solo una respuesta activa sino también documentada. No tiene sentido suministrar código si el OP no lo comprende. Él/ella debería aprender algo de la respuesta en lugar de solo copiar y pegar, de esa manera él/ella terminaría haciendo la misma pregunta la próxima vez, solo en un contexto diferente. – ShellFish

+0

El punto es que la respuesta de Gary y la Wiki de Tkinter para mí no funciona en Python 3.4.3 –

Cuestiones relacionadas