7

I'm a student from the outside world with no previous programming experience. I have been learning Python as an extension of my math class. I have been trying to create a program that generates fractals using Tkinter. The code works well on its own, but the inclusion of a user-input GUI causes it to give an error:

    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
        return self.func(*args)
      File "C:\Python33\FractalGUI.py", line 74, in fractals
        canvas.create_image((0, 0), image = img, state = "normal", anchor = tkinter.NW)
      File "C:\Python33\lib\tkinter\__init__.py", line 2319, in create_image
        return self._create('image', args, kw)
      File "C:\Python33\lib\tkinter\__init__.py", line 2310, in _create
        *(args + self._options(cnf, kw))))
    _tkinter.TclError: image "pyimage1" doesn't exist

The code itself is below. Please note that the error doesn't appear until the canvas.create_image line is run. If there is any other information that I can provide, please let me know. Thanks! :)

    import tkinter
    from tkinter import *

    #Creates widgets for user input
    class Imagespecs(Frame):

        def __init__(self,master):
            Frame.__init__(self,master)
             self.grid()
             self.y_axis()
             self.x_axis()

    #Y axis input
         def y_axis(self):
            self.instruction = Label(self,text = "How many pixels high do you want the image?")
            self.instruction.grid(row = 8, column = 0, columnspan = 2, sticky = N)

            self.height = Entry(self)
            self.height.grid(row = 10, column = 1, sticky = E)

    #Enters info to run fractal generation
            self.submit_button = Button(self,text = "Submit", command = self.fractals)
            self.submit_button.grid(row = 14, column = 2, sticky = E)

    #X axis input
         def x_axis(self):
             self.instruction2 = Label(self,text = "How many pixels wide do you want the image?")
             self.instruction2.grid(row = 4, column = 0, columnspan = 2, sticky = E)

            self.width = Entry(self)
            self.width.grid(row = 6, column = 1, sticky = E)

      #generates fractal
         def fractals(self):
             #Replace non-input
             content = self.width.get()
             content2 = self.height.get()

             if content == "":
                content = 500

             if content2 == "":
                content2 = 500

            #Create window specs
            WIDTH = int(content2); HEIGHT = int(content)
            xa = -2.0; xb = 1.0
            ya = -1.5; yb = 1.5
            maxIt = 256

             window = Tk()
             canvas = Canvas(window, width = WIDTH, height = HEIGHT, bg = "#000000")
             img = PhotoImage(width = WIDTH, height = HEIGHT)

             #The Newton-Raphson iteration
             h = HEIGHT
            for ky in range(HEIGHT):
                print (h)
                h = h - 1
                for kx in range(WIDTH):
                    c = complex(xa + (xb - xa) * kx / WIDTH, ya + (yb - ya) * ky / HEIGHT)
                    z = complex(0.0, 0.0)
                     for i in range(maxIt):
                        z = z * z + c
                        if abs(z) >= 2.0:
                            break
                     rd = hex(i % 4 * 64)[2:].zfill(2)
                     gr = hex(i % 8 * 32)[2:].zfill(2)
                     bl = hex(i % 16 * 16)[2:].zfill(2)
                     img.put("#" + rd + gr + bl, (kx, ky))

             canvas.create_image((0, 0), image = img, state = "normal", anchor = tkinter.NW)

             #Run GUI
             canvas.pack()
             mainloop()

     root = Tk()
     root.title("Fractal GUI")
     root.geometry("300x200")
     app = Imagespecs(root)

     root.mainloop()
Silmarillion101
  • 179
  • 1
  • 1
  • 6
  • 11
    Part of the problem is that you're creating more than once instance of `Tk`. Tkinter is designed such that there should only ever be exactly once instance of `Tk`. Your code also seems to have some indentation errors. – Bryan Oakley Apr 22 '14 at 16:07
  • Ok, thanks! I'll double check the indentation. Do you know a way to fix the Tk issue? Meanwhile I will try to fix it, but if you have a solution already, I'll be grateful. :) – Silmarillion101 Apr 22 '14 at 16:14
  • 6
    If you need more than one window, create your first one with `Tk`, then the rest need to be instances of `Toplevel`. – Bryan Oakley Apr 22 '14 at 16:35
  • Ok, thank you! :) The windows are both opening now, but it is telling me that the global name tkinter isn't defined... I'll work more on this after I finish Bio class. Thanks for all of your help and patience for a beginner. – Silmarillion101 Apr 22 '14 at 17:00
  • Possible duplicate of [cannot associate image to tkinter label](http://stackoverflow.com/questions/25460418/cannot-associate-image-to-tkinter-label) – unutbu Jan 28 '16 at 21:43

4 Answers4

16

Have a try and define a master:

PhotoImage(master = canvas, width = WIDTH, height = HEIGHT)

If you do not define a master then this image uses the first Tk() which is created and if that Tk is deleted there is no image to display.

Tell me if it works, I am guessing.

User
  • 14,131
  • 2
  • 40
  • 59
  • I faced the same problem when I tried to import a module inside a function call. The error message was displayed until I defined (master= canvas). Thanks for posting this answer. – Mohammed Dec 22 '14 at 17:26
  • I changed 'img = ImageTk.PhotoImage(my_img)' to 'img = ImageTk.PhotoImage(master=root, image=my_img)' and it worked! – Dgomn D Jun 11 '23 at 18:56
8

Okay, I thanks for the input, people! I managed to fix it by changing the window = Tk() into window = Toplevel and replacing anchor = tkinter.NW to anchor = NW. Now it runs exactly how I intended it. On to finish the input GUI! :D

Silmarillion101
  • 179
  • 1
  • 1
  • 6
1

I understand in this question is already answered but wanted to leave this in case anyone else encountered a problem like me. Had the same error message above -- I had a custom class that inherited from tk.Tk and tried to set the style before calling super().__init__(), put the line after the call and it fixed the issue.

Mitchnoff
  • 495
  • 2
  • 7
0

Solved it using

just do these

import tkinter as tk

window=tk.TK()

syed haris
  • 29
  • 1