Python ткинтер, как вывести изображение в реальном времени? - PullRequest
0 голосов
/ 05 апреля 2019

Когда я пытаюсь отобразить изображение с моего диска, не загружая его из Интернета, все работает хорошо, и изображение отображается правильно. Но когда я пытаюсь загрузить изображение с моего сайта, изменить его расширение на .gif, чтобы работать с библиотекой PIL, и отобразить его после нажатия кнопки, ничего не отображается. Я уверен, что все операции в subprocess.call выполнены правильно. Как я могу заставить это работать?

from tkinter import *
from PIL import ImageTk, Image

root = Tk()
root.title("My app")
root.geometry("680x500+0+0")

def callback(event):
    subprocess.call("wget example.com/pic.png && mv pic.png pic.gif", shell = True)
    img = ImageTk.PhotoImage(Image.open("pic.gif"))
    la.configure(image = img)

b1 = Button(root, text = "b1", bg = "red")
b1.grid(row = 0, column = 0)

b2 = Button(root, text = "b2", bg = "blue")
b2.grid(row = 0, column = 1)

la = Label(root, text="hi")
la.grid(row = 1, column = 0)

b2.bind("<Button-1>", callback)

root.mainloop()

1 Ответ

0 голосов
/ 05 апреля 2019

Первое: Вы не можете изменить расширение .png на .gif, чтобы получить файл GIF.Вам придется использовать какую-то программу для его преобразования.Но Image.open может работать с файлами PNG, поэтому вам не нужно конвертировать его.

 img = ImageTk.PhotoImage(Image.open("furas.png"))

Второе: в PhotoImage есть ошибка, которая удаляет изображение из памяти, когда ононазначается локальной переменной в функции.Таким образом, вы должны назначить его глобальной переменной.Обычный метод назначает его метке, которая будет отображать егоВы можете использовать любое имя для переменной - т.е..image

 la.image = img

Подробнее в документации: PhotoImage на effbot.org

Третье: вы запустили код в терминале, чтобы увидеть ошибкуСообщения ?Вы забыли импортировать subprocess

Полный код с существующим изображением

from tkinter import *
from PIL import ImageTk, Image
import subprocess

def callback(event):
    subprocess.call("wget https://blog.furas.pl/theme/images/me/furas.png", shell=True)
    img = ImageTk.PhotoImage(Image.open("furas.png"))
    la.configure(image=img)
    la.image = img

root = Tk()
root.title("My app")
root.geometry("680x500+0+0")

b1 = Button(root, text="b1", bg="red")
b1.grid(row=0, column=0)

b2 = Button(root, text="b2", bg="blue")
b2.grid(row=0, column=1)

la = Label(root, text="hi")
la.grid(row=1, column=0)

b2.bind("<Button-1>", callback)

root.mainloop()

Кстати: вы можете использовать Button(..., command=callback), но удалить event из def callback()

from tkinter import *
from PIL import ImageTk, Image
import subprocess

def callback():
    subprocess.call("wget https://blog.furas.pl/theme/images/me/furas.png", shell=True)
    img = ImageTk.PhotoImage(Image.open("furas.png"))
    la.configure(image=img)
    la.image = img

root = Tk()
root.title("My app")
root.geometry("680x500+0+0")

b1 = Button(root, text="b1", bg="red")
b1.grid(row=0, column=0)

b2 = Button(root, text="b2", bg="blue", command=callback)
b2.grid(row=0, column=1)

la = Label(root, text="hi")
la.grid(row=1, column=0)

root.mainloop()

РЕДАКТИРОВАТЬ: вместо wget вы можете использовать стандартный модуль Python urllib и функцию urllib.request.urlretrive()

from tkinter import *
from PIL import ImageTk, Image
import urllib.request

def callback():
    urllib.request.urlretrieve("https://blog.furas.pl/theme/images/me/furas.png", "furas.png")
    img = ImageTk.PhotoImage(Image.open("furas.png"))
    la.configure(image=img)
    la.image = img

root = Tk()
root.title("My app")
root.geometry("680x500+0+0")

b1 = Button(root, text="b1", bg="red")
b1.grid(row=0, column=0)

b2 = Button(root, text="b2", bg="blue", command=callback)
b2.grid(row=0, column=1)

la = Label(root, text="hi")
la.grid(row=1, column=0)

root.mainloop()
...