将图片加载到tkinter

时间:2016-10-23 10:52:05

标签: python json image tkinter

我想在弹出窗口中显示一张图片。但我无法让它发挥作用。我想我在def apiraadplegen(x)做错了。我访问API并显示口袋妖怪的名称(输入=数字)。我也想要一张照片。如何正确显示图像?

#importception
import requests
import json
import sys
from tkinter import *
from tkinter.messagebox import showinfo
import urllib
from PIL import Image, ImageTk
import PIL

#import poke api
api_url = 'http://pokeapi.co/api/v2/'

#api url dingen
def apiraadplegen(x):
    try:
        r = requests.get(x)
    except requests.exceptions.RequestException as error:
        print(error)
        sys.exit(1)
    else:
       # Geen probleem =)
       # decoderen zodat python het kan lezen
        json_data = r.json()
        img = Image.open(json_data['sprites']['front_default'])
        img_1 = ImageTk.PhotoImage(img)
        bericht = showinfo(title='Informatie', message='Naam: ' + json_data['name'] + '\n' + img_1)
        return bericht




# def klikken op een knop
def klikkenpokemon():
    try:
        pokenaamurl = api_url + 'pokemon/' + invoer1.get()
        return apiraadplegen(pokenaamurl)
    except:
        showinfo(title='Error!', message='Er is iets fout gegaan.')
        sys.exit(1)

#het programma window
root = Tk()
label = Label(master=root,
              text='Welkom op de Pokewiki!',
              background='white',
              foreground='red',
              font=('Times New Roman', '14'),
              width=40,
              height=5)
label.pack()
#invoer pokemon nummer / naam
invoer1 = Entry(master=root)
invoer1.pack(padx=10, pady=10)
#magische resolve knop
pokeknop = Button(master=root, text='Klik hier', command=klikkenpokemon)
pokeknop.pack(pady=20)

root.mainloop()

1 个答案:

答案 0 :(得分:2)

  1. Image()只能读取本地文件,因此您必须使用requests下载图片(r.content)。

  2. 您可以在磁盘上下载文件并将其与Image()一起使用,或者您必须在内存中创建类似文件的对象(包含来自请求的数据 - r.content)并将其与{{Image()一起使用1}}。 Image()无法直接处理来自请求Image(r.content)

    的数据
    import io
    
    fp = io.BytesIO(r.content) # <-- file-like object
    
    image = Image(fp)
    
  3. PhotoImagegarbage-collector存在问题。它删除在函数中创建并分配给局部变量的PhotoImage对象 - 您必须将其分配给全局/外部变量: http://effbot.org/tkinterbook/photoimage.htm

    即。

    image = Image(fp)
    photo = PhotoImage(image)
    
    image.photo = photo # <-- solution 
    
  4. 您需要Label才能显示图片。我在主窗口中创建了Label

  5. 最后:

    #importception
    import requests
    import json
    import sys
    from tkinter import *
    from tkinter.messagebox import showinfo
    import urllib
    from PIL import Image, ImageTk
    import PIL
    
    import io # <-- to create file-like object in memory
    
    # --- constants --- (UPPER_CASE)
    
    # import poke api
    API_URL = 'http://pokeapi.co/api/v2/'
    
    # --- functions --- (lower_case)
    
    #api url dingen
    def apiraadplegen(x):
        try:
            r = requests.get(x)
        except requests.exceptions.RequestException as error:
            print(error)
            root.destroy() # <-- close window
            sys.exit(1)
    
        # Geen probleem =)
        # decoderen zodat python het kan lezen
        json_data = r.json()
    
        try:
            r = requests.get(json_data['sprites']['front_default'])
    
        except requests.exceptions.RequestException as error:
            print(error)
            root.destroy() # <-- close window
            sys.exit(1)
    
        fp = io.BytesIO(r.content)  # <-- create file-like object in memory
    
        image = Image.open(fp)  # <-- use file-like object in memory
        photo = ImageTk.PhotoImage(image)
    
        label_image.config(image=photo) # <-- show image in label
        label_image.image=photo # <-- solution for problem with garbage-collector & PhotoImage
    
        bericht = showinfo(title='Informatie', message='Naam: ' + json_data['name']) # + '\n' + photo) # <-- you can't display image this way
    
        return bericht
    
    # def klikken op een knop
    def klikkenpokemon():
        try:
            pokenaamurl = API_URL + 'pokemon/' + invoer1.get()
            return apiraadplegen(pokenaamurl)
        except Exception as error:
            print(error) # <-- always print error - on screen or in log file
            showinfo(title='Error!', message='Er is iets fout gegaan.')
            root.destroy() # <-- close window
            sys.exit(1)
    
    # --- main ---
    
    #het programma window
    root = Tk()
    
    label = Label(master=root,
                  text='Welkom op de Pokewiki!',
                  background='white',
                  foreground='red',
                  font=('Times New Roman', '14'),
                  width=40,
                  height=5)
    label.pack()
    
    #invoer pokemon nummer / naam
    invoer1 = Entry(master=root)
    invoer1.pack(padx=10, pady=10)
    
    #magische resolve knop
    pokeknop = Button(master=root, text='Klik hier', command=klikkenpokemon)
    pokeknop.pack(pady=20)
    
    label_image = Label(master=root) # <-- place for image
    label_image.pack()
    
    invoer1.focus() # <-- set focus on Entry so you can quickly type text
    
    root.mainloop()
    

    enter image description here