Python + Tkinter画树

来源:互联网 发布:织梦cms模板使用手册 编辑:程序博客网 时间:2024/04/29 18:50

[转]http://bbs.csdn.net/topics/320088140

# -*- coding: utf-8 -*-import Tkinterimport sys, random, mathclass Point(object):def __init__(self, x, y):self.x = xself.y = ydef __str__(self):return "<Point>: (%f, %f)" % (self.x, self.y)class Branch(object):def __init__(self, bottom, top, branches, level = 0):self.bottom = bottomself.top = topself.level = levelself.branches = branchesself.children = []def __str__(self):s = "Top: %s, Bottom: %s, Children Count: %d" % \(self.top, self.bottom, len(self.children))return sdef nextGen(self, n = -1, rnd = 1):if n <= 0: n = self.branchesif rnd == 1:n = random.randint(n / 2, n * 2)if n <= 0: n = 1dx = self.top.x - self.bottom.xdy = self.top.y - self.bottom.yr = 0.20 + random.random() * 0.2if self.top.x == self.bottom.x:# 如果是一条竖线x = self.top.xy = dy * r + self.bottom.yelif self.top.y == self.bottom.y:# 如果是一条横线x = dx * r + self.bottom.xy = self.top.yelse:x = dx * ry = x * dy / dxx += self.bottom.xy += self.bottom.yoldTop = self.topself.top = Point(x, y)a = math.pi / (2 * n)for i in range(n):a2 = -a * (n - 1) / 2 + a * i - math.pia2 *= 0.9 + random.random() * 0.2self.children.append(self.mkNewBranch(self.top, oldTop, a2))def mkNewBranch(self, bottom, top, a):dx1 = top.x - bottom.xdy1 = top.y - bottom.yr = 0.9 + random.random() * 0.2c = math.sqrt(dx1 ** 2 + dy1 ** 2) * rif dx1 == 0:a2 = math.pi / 2else:a2 = math.atan(dy1 / dx1)if (a2 < 0 and bottom.y > top.y) \or (a2 > 0 and bottom.y < top.y) \:a2 += math.pib = a2 - adx2 = c * math.cos(b)dy2 = c * math.sin(b)newTop = Point(dx2 + bottom.x, dy2 + bottom.y)return Branch(bottom, newTop, self.branches, self.level + 1)class Tree(object):def __init__(self, root, canvas, bottom, top, branches = 3, depth = 3):self.root = rootself.canvas = canvasself.bottom = bottomself.top = topself.branches = branchesself.depth = depthself.new()def gen(self, n = 1):for i in range(n):self.getLeaves()for node in self.leaves:node.nextGen()self.show()def new(self):self.leavesCount = 0self.branch = Branch(self.bottom, self.top, self.branches)self.gen(self.depth)print "leaves count: %d" % self.leavesCountdef chgDepth(self, d):self.depth += dif self.depth < 0: self.depth = 0if self.depth > 10: self.depth = 10self.new()def chgBranch(self, d):self.branches += dif self.branches < 1: self.branches = 1if self.branches > 10: self.branches = 10self.new()def getLeaves(self):self.leaves = []self.map(self.findLeaf)def findLeaf(self, node):if len(node.children) == 0:self.leaves.append(node)def show(self):for i in self.canvas.find_all():self.canvas.delete(i)self.map(self.drawNode)self.canvas.tag_raise("leaf")def exit(self, evt):sys.exit(0)def map(self, func = lambda node: node):# 遍历树children = [self.branch]while len(children) != 0:newChildren = []for node in children:func(node)newChildren.extend(node.children)children = newChildrendef drawNode(self, node):self.line2(#self.canvas.create_line(node.bottom.x,node.bottom.y,node.top.x,node.top.y,fill = "#100",width = 1.5 ** (self.depth - node.level),tags = "branch level_%d" % node.level,)if len(node.children) == 0:# 画叶子self.leavesCount += 1self.canvas.create_oval(node.top.x - 3,node.top.y - 3,node.top.x + 3,node.top.y + 3,fill = "#090",tag = "leaf",)self.canvas.update()def line2(self, x0, y0, x1, y1, width = 1, fill = "#000", minDist = 10, tags = ""):dots = midDots(x0, y0, x1, y1, minDist)dots2 = []for i in range(len(dots) - 1):dots2.extend([dots[i].x,dots[i].y,dots[i + 1].x,dots[i + 1].y])self.canvas.create_line(dots2,fill = fill,width = width,smooth = True,tags = tags,)def midDots(x0, y0, x1, y1, d):dots = []dx, dy, r = x1 - x0, y1 - y0, 0if dx != 0:r = float(dy) / dxc = math.sqrt(dx ** 2 + dy ** 2)n = int(c / d) + 1for i in range(n):if dx != 0:x = dx * i / ny = x * relse:x = dxy = dy * i / nif i > 0:x += d * (0.5 - random.random()) * 0.25y += d * (0.5 - random.random()) * 0.25x += x0y += y0dots.append(Point(x, y))dots.append(Point(x1, y1))return dotsif __name__ == "__main__":root = Tkinter.Tk()root.title("Tree")gw, gh = 800, 600canvas = Tkinter.Canvas(root,width = gw,height = gh,)canvas.pack()tree = Tree(root, canvas, Point(gw / 2, gh - 20), Point(gw / 2, gh * 0.2), \branches = 2, depth = 8)root.bind("n", lambda evt: tree.new())root.bind("=", lambda evt: tree.chgDepth(1))root.bind("+", lambda evt: tree.chgDepth(1))root.bind("-", lambda evt: tree.chgDepth(-1))root.bind("b", lambda evt: tree.chgBranch(1))root.bind("c", lambda evt: tree.chgBranch(-1))root.bind("q", tree.exit)root.mainloop()

原创粉丝点击