无法判断Python函数是否正在调用?

时间:2014-05-05 21:00:54

标签: python function tkinter fractals

我无法使用此代码。它应该从输入函数生成分形图像。它将完美运行,然后打印出单色帆布而不是分形。当我将分形函数从Mandelbrot切换到Newton-Raphson时出现问题。与Mandelbrot不同,Newton-Raphson需要为要调用的函数单独定义。这就是给我带来麻烦的一点。我输入了一个print语句,它似乎正在运行,但它运行不正常。它运行所有点到最大迭代(MaxIt),然后给我一个彩色画布,认为它们都逃到无限。以下是当前代码的副本:

from tkinter import *
from math 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):
        maxIt = 2
        ds = 0.2e-1
        eps = 5e-5
        #Replace non-input
        content = self.width.get()
        content2 = self.height.get()

        if content == "":
           content = 500

        if content2 == "":
           content2 = 500

        def f(z):
            return z**3 + 5
        print ('lalala')

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

         window = Toplevel()
        canvas = Canvas(window, width = WIDTH, height = HEIGHT, bg = "#000000")
        img = PhotoImage(width = WIDTH, height = HEIGHT)
        canvas.create_image((0, 0), image = img, state = "normal", anchor = NW)

        #The Newton-Raphson iteration
        h = HEIGHT
        for y in range(HEIGHT):
            print (h)
            h = h - 1
            zy = y * (yb - ya) / (HEIGHT - 1) + ya
            for x in range(WIDTH):
                zx = x * (xb - xa) / (WIDTH - 1) + xa
                z = complex(zx, zy)
                for i in range(maxIt):
                    dz = (f(z + complex(ds, ds)) - f(z)) / complex(ds, ds)
                    z0 = z - f(z) / dz
                    if abs(z0 - z) < eps:
                        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, (x, y))


        #Run GUI
        canvas.pack()
        mainloop()

#Run the class and everything else      
root = Tk()
root.title("Fractal GUI")
root.geometry("300x200")
app = Imagespecs(root)

root.mainloop()

1 个答案:

答案 0 :(得分:0)

虽然您的代码中存在错误,例如缺少z = z0行,这里的主要罪魁祸首是tkinter的PhotoImage的一个已知功能,它与不保存对图像和垃圾收集的引用有关:

Why do my Tkinter images not appear?

我已经重新编写代码以生成分形并尝试解决我注意到的那些问题:

from tkinter import *

MAX_ITERATIONS = 300
DS = 0.2e-1
EPS = 5e-5

# Create window specs
XA, XB = -1.0, 1.0
YA, YB = -1.0, 1.0

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

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

    # Y axis input
    def y_axis(self):
        instruction = Label(self, text="How many pixels high do you want the image?")
        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
        submit_button = Button(self, text="Submit", command=self.fractals)
        submit_button.grid(row=14, column=2, sticky=E)

    # X axis input
    def x_axis(self):
        instruction = Label(self, text="How many pixels wide do you want the image?")
        instruction.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):

        def f(z):
            return z**3 + 5

        # Replace non-input
        try:
            width = int(self.width.get())
        except ValueError:
            width = 500

        try:
            height = int(self.height.get())
        except ValueError:
            height = 500

        canvas = Canvas(Toplevel(), width=width, height=height, bg="#000000")
        img = PhotoImage(width=width, height=height)
        canvas.create_image((0, 0), image=img, state="normal", anchor=NW)

        # The Newton-Raphson iteration
        for y in range(height):
            zy = y * (YB - YA) / (height - 1) + YA

            for x in range(width):
                zx = x * (XB - XA) / (width - 1) + XA
                z = complex(zx, zy)

                i = 0  # avoid undefined variable after loop

                for i in range(MAX_ITERATIONS):
                    dz = (f(z + complex(DS, DS)) - f(z)) / complex(DS, DS)
                    z0 = z - f(z) / dz
                    if abs(z0 - z) < EPS:
                        break
                    z = z0

                red = i % 4 * 64
                green = i % 8 * 32
                blue = i % 16 * 16
                img.put("#%02x%02x%02x" % (red, green, blue), (x, y))

        # Run GUI
        canvas.pack()
        self.image = img  # save reference so image isn't GC'd!

# Run the class and everything else
root = Tk()
root.title("Fractal GUI")
root.geometry("400x150")

app = Imagespecs(root)

root.mainloop()

enter image description here