2012-07-22 1286 views
5

Nguyên nhân của vấn đề là, tôi đang làm gì sai trong đoạn mã sau?Làm cách nào để hiển thị hình ảnh trong Python 3 bằng 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() 

Thông báo lỗi tôi nhận được từ idle3 là như sau:

>>> 
    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) 
    >>> 

Thông báo lỗi này đã cho tôi bối rối, tôi chỉ đơn giản là không hiểu những gì nó đang cố gắng để nói. Ý tưởng nào?

tôi cũng sẽ đánh giá cao đề nghị cho thay đổi ...

+0

BTW Tôi đã kiểm tra tham chiếu này http://effbot.org/tkinterbook/photoimage.htm - bạn sẽ thấy đoạn mã của tôi trông rất giống nhau! – Bobble

+0

Lỗi dường như trỏ đến đối số 'myButton' được chuyển đến' PhotoImage() '. Tôi không tin rằng 'PhotoImage()' có một tham chiếu đến một đối tượng widget, vì vậy điều này có thể gây ra lỗi. Hãy thử dòng đó mà không có nó, chẳng hạn như 'myImage = PhotoImage (file = 'myPicture.gif')' – gary

+1

@Gary, điều đó dường như làm điều đó. Tôi đã bị lừa bởi một số tài liệu (và một số lỗi khác mà tôi đã tạo) để suy nghĩ 'PhotoImage' cần một tham chiếu rõ ràng đến cửa sổ gốc.Sau khi một số fiddling hơn tôi thấy tham chiếu đến một trong hai gốc hoặc nút chính nó có thể được cung cấp bởi một tùy chọn cấu hình trên constructor 'PhotoImage' như thế này,' PhotoImage (master = myButton, file = 'myFile.gif') ', nhưng theo cách tôi đã viết, có vẻ như Tkinter giống như một cái tên, được cho là một chuỗi, ofc. – Bobble

Trả lời

7

Lỗi này có vẻ để trỏ đến myButton tranh luận truyền cho PhotoImage. Như bạn đã lưu ý trong nhận xét của mình, PhotoImage đang xử lý đối tượng tiện ích dưới dạng chuỗi (có một số tùy chọn loại chuỗi; xem danh sách tùy chọn PhotoImage here).

Mã của bạn sẽ làm việc nếu bạn thực hiện dòng đó mà không tham khảo đối tượng myButton:

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

Tôi không chắc chắn mình cần phải thay đổi các nhà xây dựng PhotoImage. Xem tài liệu PhotoImage để xác định các tùy chọn hợp lệ (nghĩa là tên tài nguyên) cho lớp đó. Trích dẫn tập tin giúp đỡ:

Trợ giúp về lớp PhotoImage trong mô-đun Tkinter:

lớp PhotoImage (Hình ảnh)

| 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: Cách đơn giản nhất để có được các tài liệu từ Python tại dòng lệnh hoặc từ IDLE:

from tkinter import PhotoImage 
help(PhotoImage) 

Và cuối cùng, một liên kết hữu ích khác về lớp học này là http://tkinter.unpythonic.net/wiki/PhotoImage.

+1

Rất cám ơn Gary! Bạn cũng đúng về tham chiếu 'chính'. Đó là một hang-over từ một số thí nghiệm tôi đã làm với nhiều chủ đề (tốt nhất không hỏi!). – Bobble

+0

@Bobble BTW, nếu điều này đã trả lời câu hỏi, vui lòng đánh dấu câu hỏi đó là câu trả lời được chấp nhận (có vẻ như bạn có thể làm gì đó cho một số câu hỏi của mình). – gary

-1

Tôi đã thử nghiệm ví dụ với python 2.7.9, 3.2.5, 3.3.5, 3.4.3 trong 32bit và 64bit. (Win 8.1 64bit)

Mã hoạt động.

(trong python 3.4.3 64bit tôi đã lần đầu tiên một thông báo lỗi.

Tôi đã hoàn toàn gỡ bỏ cài đặt 3.4.3 và sau đó cài đặt lại.

Bây giờ, ví dụ cũng làm việc với 3.4.3 64 bit)

# 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

Bạn có chắc đó là câu trả lời và cụ thể hơn là câu trả lời cho python-3.x? – Deduplicator

+0

Câu trả lời hay không chỉ là câu trả lời làm việc mà còn là một câu trả lời được ghi lại. Không có điểm cung cấp mã nếu OP không hiểu nó. Anh/cô ấy nên học điều gì đó từ câu trả lời thay vì chỉ sao chép dán nó, theo cách đó anh ta/cô ấy sẽ lại hỏi cùng một câu hỏi lần sau, chỉ trong một ngữ cảnh khác. – ShellFish

+0

vấn đề là phản hồi từ gary và Tkinter Wiki đối với tôi không hoạt động trong Python 3.4.3 –