Проблема с кодом Python, приложение было уничтожено Ошибка Tcl - PullRequest
0 голосов
/ 26 мая 2011

Я создаю графический интерфейс Tkinter, который ничего не делает, кроме изображений вызовов - и, конечно, я изо всех сил пытался найти приличную документацию по tkinter.

Существует строка моего кода, которая не может выглядеть какспросил - я хочу вызвать все значения в словаре и отдельно распечатать и вытащить изображение с тем же именем для каждого из них перед вызовом следующего значения.Я попробовал dict.itervalues ​​() и dict.values ​​() и, похоже, ничего не могу понять ...

В любом случае, вот фрагмент:

for key in ansDict.iterkeys(): #using the iterkeys function... kind of
    x=key

    root = tk.Tk() # root window created (is this in the right place?)
    root.title('C H E M I S T R Y   A B C\'s')

    frameAns=tk.Frame(root)
    frameAns.grid(row=0, column=0, sticky=tk.NW)

    for i in range(len(ansDict[x])):
        print '-->' + ansDict[x][i]

    for value in ansDict.itervalues(): #This is the most important part

        for i in range(len(value)): #pulls value list from dictionary named ansDict
            picRef1 = Image.open(value[i] + '.jpg') #calls image file by the same name using PIL
            photo1 = ImageTk.PhotoImage(picRef1, master=root)

            button1 = tk.Button(frameAns, compound=tk.TOP, image=photo1, text=str(value[i]) + '\nClose me!', bg='white') #pulls up button onto which the image is pasted
            button1.grid(sticky=tk.NW, padx=2, pady=2) #places button on grid
            button1.image=photo1

            root.mainloop()

Наконецв конце он вытягивает одно или два изображения, а затем я получаю следующую ошибку:

TclError: не могу вызвать команду «изображение»: приложение было уничтожено

, и я могуне понять, что не так.Я не могу переместить команду изображения, и каким-то образом мне нужно «сохранить» ее, чтобы она не была уничтожена.Я знаю, что здесь есть другие ошибки кода, но я думаю, что, если я выясню, что получаю TclError, я могу исправить все остальное.

Если есть более простой способ сделать все это, пожалуйста, сообщите!

Ответы [ 3 ]

2 голосов
/ 21 сентября 2011

Я искал хорошее решение для этого, но пока не нашел правильного решения. Глядя на класс Tkinter.py, он выглядит так: значение Image del равно:

def __del__(self):
    if self.name:
        try:
            self.tk.call('image', 'delete', self.name)
        except TclError:
            # May happen if the root was destroyed
            pass

Это означает, что если вы хотите взломать BRUTAL , вы можете настроить PhotoImage, как описано в ссылке jtp.

photo = tk.PhotoImage(file="C:/myimage.gif")
widget["image"] = photo
widget.image = photo

Тогда вы могли бы незадолго до выхода из программы сделать следующее:

photo.name = None

Это предотвратит попытку очистки в удалении PhotoImage и не вызовет исключение в методе del . Я действительно не рекомендую вам делать это, если вы не прислонились спиной к стене, и у вас нет альтернативы.

Я буду продолжать изучать это, и если я найду лучшее решение, отредактирую этот пост с лучшим (надеюсь, кто-то даст правильное решение до этого).

0 голосов
/ 26 мая 2011

Похоже, вы не поняли Событийное программирование .Вы должны создать целый графический интерфейс один раз, заполнить его виджетами, настроить события и затем войти в бесконечный цикл.GUI должен вызывать функции обратного вызова, основанные на привязке вашего события к функции.Таким образом, эти части вашей программы должны определенно вызываться только один раз: root = tk.Tk(), root.mainloop().

Редактировать: Добавлен «пример идеи» управляемого событиями программирования.

from Tkinter import *

master = Tk()

def callback():
    print "click!"

b = Button(master, text="OK", command=callback)
b.pack()

mainloop()
0 голосов
/ 26 мая 2011

Вот одна из возможностей, хотя она структурирована иначе, чем ваш пример.Он накладывает четыре квадрата размером 100 пикселей друг на друга.Я считаю, что вам нужно хранить отдельную ссылку на каждый объект Image, поэтому я спрятал их в словаре изображений.

from Tkinter import *
import os
from PIL import Image, ImageTk

image_names = { '1':'one','2':'two','3':'three','4':'four' }
images = {}

root = Tk()
root.title("HELLO")
frm = Frame(root)

for v in image_names.itervalues():
   images[v] = {}
   images[v]['i']  = Image.open("%s%s.jpg" % (os.path.dirname(__file__), v))
   images[v]['pi'] = ImageTk.PhotoImage(images[v]['i'])
   images[v]['b']  = Button(frm, image=images[v]['pi'])
   images[v]['b'].pack()

frm.pack()

mainloop()

Вот хорошая ссылка, обсуждающая класс PhotoImage.

http://effbot.org/tkinterbook/photoimage.htm

...