ebil
ebil

Reputation: 33

How to draw recursive tree on tkinter

I tried to draw recursive tree on python tkinter based on depth enter by user, here is my code so far:

from tkinter import * # Import tkinter
import math

#angleFactor = math.pi/5
#sizeFactor = 0.58

class Main:
    def __init__(self):
        window = Tk() # Create a window
        window.title("Recursive Tree") # Set a title

        self.width = 200
        self.height = 200
        self.canvas = Canvas(window, 
        width = self.width, height = self.height,bg="white")
        self.canvas.pack()

        # Add a label, an entry, and a button to frame1
        frame1 = Frame(window) # Create and add a frame to window
        frame1.pack()

        Label(frame1, 
        text = "Enter the depth: ").pack(side = LEFT)
        self.depth = StringVar()
        entry = Entry(frame1, textvariable = self.depth, 
                  justify = RIGHT).pack(side = LEFT)
        Button(frame1, text = "Display Recursive Tree", 
        command = self.display).pack(side = LEFT)

        self.angleFactor = math.pi/5
        self.sizeFactor = 0.58          

        window.mainloop() # Create an event loop

    def drawLine(self, x1,x2,y1,y2):
        self.canvas.create_line(x1,y1,x2,y2, tags = "line")    

    def display(self):
        self.canvas.delete("line")
        return self.paintBranch(int(self.depth.get()),self.width/2, self.height /2   , self.height/3, math.pi/2)

    def paintBranch(self,depth, x1, y1, length, angle):

        if depth >= 0:

            x2 = x1 +int( math.cos(angle) * length)
            y2 = y1 + int(math.sin(angle) * length)


            # Draw the line
            self.drawLine(x1,y1,x2,y2)


            # Draw the left branch
            self.paintBranch(depth - 1, x2, y2, length * self.sizeFactor, angle + self.angleFactor  )
            # Draw the right branch
            self.paintBranch(depth - 1, x2, y2, length * self.sizeFactor, angle - self.angleFactor )        


Main()

when the user enter depth=0 the code is working, but when recursive in depth >=1, the code fail to draw a tree, I need help for my code, thanks before

Upvotes: 2

Views: 3398

Answers (1)

PM 2Ring
PM 2Ring

Reputation: 55479

Your main problem is that you messed up the args to the drawLine method. You defined it as

drawLine(self, x1,x2,y1,y2)

but you call it as

self.drawLine(x1,y1,x2,y2)

so the y1 arg you pass it gets used for the x2 parameter, and the x2 arg gets used for the y1 parameter.

You also need to change your initial y1 value, and to change the sign when computing y2 from y1, because Y coordinates in Tkinter increase as you go down the screen.

Here's a repaired version of your code.

from tkinter import * # Import tkinter
import math

class Main:
    def __init__(self):
        window = Tk() # Create a window
        window.title("Recursive Tree") # Set a title

        self.width = 400
        self.height = 400
        self.canvas = Canvas(window, 
        width = self.width, height = self.height,bg="white")
        self.canvas.pack()

        # Add a label, an entry, and a button to frame1
        frame1 = Frame(window) # Create and add a frame to window
        frame1.pack()

        Label(frame1, 
            text = "Enter the depth: ").pack(side = LEFT)
        self.depth = StringVar()
        Entry(frame1, textvariable = self.depth, 
            justify = RIGHT).pack(side = LEFT)
        Button(frame1, text = "Display Recursive Tree", 
            command = self.display).pack(side = LEFT)

        self.angleFactor = math.pi/5
        self.sizeFactor = 0.58

        window.mainloop() # Create an event loop

    def drawLine(self, x1,y1, x2,y2):
        self.canvas.create_line(x1,y1, x2,y2, tags = "line")    

    def display(self):
        self.canvas.delete("line")
        depth = int(self.depth.get())
        return self.paintBranch(depth, self.width/2, self.height, self.height/3, math.pi/2)

    def paintBranch(self, depth, x1, y1, length, angle):
        if depth >= 0:
            depth -= 1
            x2 = x1 + int(math.cos(angle) * length)
            y2 = y1 - int(math.sin(angle) * length)

            # Draw the line
            self.drawLine(x1,y1, x2,y2)

            # Draw the left branch
            self.paintBranch(depth, x2, y2, length * self.sizeFactor, angle + self.angleFactor  )
            # Draw the right branch
            self.paintBranch(depth, x2, y2, length * self.sizeFactor, angle - self.angleFactor )        


Main()

Upvotes: 3

Related Questions