невозможно удалить глобальную переменную - PullRequest
0 голосов
/ 08 мая 2020

У меня довольно длинная программа просмотра GUI изображений, "глобальные переменные" начали выходить из-под контроля, и я удалил их все, кроме одного. В упрощенном коде ниже показана глобальная переменная art. с ним на месте изображение отображается, без него - серый экран. Буду признателен за любую помощь в понимании происходящего

from tkinter import *
from PIL import ImageTk,Image

root = Tk()

def image():
    global art
    path="c:/Google Drive/Art Images/0030#Van Tromp, going about to please his Masters.jpg"
    image=Image.open(path)
    art = ImageTk.PhotoImage(image)
    label.grid()
    label.configure(image=art)

label=Label(root,bg="grey")
image()

root.mainloop()

Ответы [ 2 ]

1 голос
/ 08 мая 2020

Ваша проблема в том, что при создании Photoimage вам необходимо сохранить ссылку на это изображение, что означает, что вам нужно присвоить этому изображению имя переменной, к которой можно получить доступ в другом месте. В вашем случае переменная art без использования глобального остается в функции. Это означает, что по завершении функции art уничтожается. Простое исправление - вернуть переменную art, сделав вывод функции art и, таким образом, перенеся переменную в основной код. Вот что по этому поводу должен сказать effbot:

Когда вы добавляете PhotoImage или другой объект Image в виджет Tkinter, вы должны сохранять свою собственную ссылку на объект изображения. Если вы этого не сделаете, изображение не всегда будет отображаться.

Проблема в том, что интерфейс Tkinter / Tk не обрабатывает ссылки на объекты Image должным образом; виджет Tk будет содержать ссылку на внутренний объект, а Tkinter - нет. Когда сборщик мусора Python отбрасывает объект Tkinter, Tkinter говорит Tk освободить изображение. Но поскольку изображение используется виджетом, Tk его не уничтожает. Не полностью. Он просто очищает изображение, делая его полностью прозрачным. может сделать что-то вроде этого:

from tkinter import *
from PIL import ImageTk,Image

root = Tk()

def image():
    label.grid()
    path="c:/Google Drive/Art Images/0030#Van Tromp, going about to please his Masters.jpg"
    image=Image.open(path)
    art = ImageTk.PhotoImage(image)
    label.configure(image=art)
    return art

label=Label(root,bg="grey")
image()


root.mainloop()

В этом коде ваше изображение возвращается функцией и ему назначается переменная в основном коде, что делает «ссылку» без глобальных переменных.

Дополнительную информацию можно найти здесь

0 голосов
/ 08 мая 2020

Ваша функция image () используется для вывода вашего изображения, и для этого вы присваиваете ее переменной «art». Объект изображения создается, но когда ваша функция завершается, поскольку вы ничего не возвращаете, этот объект перестает существовать:

y = 5

def getx():
  x = 3

getx()
a = y + x

Этот код не будет работать, потому что x является локальным для функции getx (). Поскольку я ничего не делаю с этим, когда функция завершается, переменная тоже. Что я могу сделать, так это передать данные из функции, например:

y = 5

def getx():
  x = 3
  return x

x = getx()
a = y + x

В вашем коде tkinter необходимо, чтобы объект изображения существовал при его запуске, но пока вы создали его в своем функция, вы позволяете функции завершиться, ничего не делая с ней. Присвоение имени art глобальной переменной эффективно позволяет вашей функции возвращать ваш объект переменной вне функции. Другой способ сделать это:

root = Tk()

def image():
  path="c:/Google Drive/Art Images/0030#Van Tromp, going about Masters.jpg"
  image=Image.open(path)
  art = ImageTk.PhotoImage(image)
  label.grid()
  label.configure(image=art)
  return art

label=Label(root,bg="grey")
art = image()

root.mainloop()
...