Utilisez le module tkinter en Python pour dessiner un arbre

Le module tkinter ("interface Tk") est l'interface de la boîte à outils graphique standard Tk de Python. Tk et Tkinter peuvent être utilisés sur la plupart des plates-formes Unix et peuvent également être appliqués aux systèmes Windows et Mac. Les versions ultérieures de Tk8.0 peuvent être implémentées Style de fenêtre locale et fonctionne bien sur la plupart des plates-formes.

Étant donné que Tkinter est intégré au package d'installation de Python, tant que Python est installé, vous pouvez importer la bibliothèque Tkinter et IDLE est également écrit en Tkinter. Pour une interface graphique simple, Tkinter peut toujours y faire face.

Voyons comment utiliser le module tkinter en Python pour dessiner un bel arbre.

Le code peut être téléchargé à partir de la Linux Community Resource Station:

------------------------------------------ Ligne de division ------ ------------------------------------

Le répertoire de téléchargement spécifique se trouve dans / 2020 données / 13 avril / Dessinez un arbre en utilisant le module tkinter en Python /

------------------------------------------ Ligne de division ------ ------------------------------------

Le tableau des effets est le suivant:

Utilisez le module tkinter en Python pour dessiner un arbre

Code:

# -*- coding: utf-8 -*-

import Tkinter
import sys, random, math

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return "<Point>: (%f, %f)" % (self.x, self.y)

class Branch(object):
    def __init__(self, bottom, top, branches, level = 0):
        self.bottom = bottom
        self.top = top
        self.level = level
        self.branches = branches
        self.children = []

    def __str__(self):
        s = "Top: %s, Bottom: %s, Children Count: %d" % \
            (self.top, self.bottom, len(self.children))
        return s

    def nextGen(self, n = -1, rnd = 1):
        if n <= 0: n = self.branches
        if rnd == 1:
            n = random.randint(n / 2, n * 2)
            if n <= 0: n = 1
        dx = self.top.x - self.bottom.x
        dy = self.top.y - self.bottom.y
        r = 0.20 + random.random() * 0.2
        if self.top.x == self.bottom.x:
            # 如果是一条竖线
            x = self.top.x
            y = dy * r + self.bottom.y
        elif self.top.y == self.bottom.y:
            # 如果是一条横线
            x = dx * r + self.bottom.x
            y = self.top.y
        else:
            x = dx * r
            y = x * dy / dx
            x += self.bottom.x
            y += self.bottom.y
        oldTop = self.top
        self.top = Point(x, y)
        a = math.pi / (2 * n)
        for i in range(n):
            a2 = -a * (n - 1) / 2 + a * i - math.pi
            a2 *= 0.9 + random.random() * 0.2
            self.children.append(self.mkNewBranch(self.top, oldTop, a2))

    def mkNewBranch(self, bottom, top, a):
        dx1 = top.x - bottom.x
        dy1 = top.y - bottom.y
        r = 0.9 + random.random() * 0.2
        c = math.sqrt(dx1 ** 2 + dy1 ** 2) * r
        if dx1 == 0:
            a2 = math.pi / 2
        else:
            a2 = math.atan(dy1 / dx1)
            if (a2 < 0 and bottom.y > top.y) \
                or (a2 > 0 and bottom.y < top.y) \
                :
                a2 += math.pi
        b = a2 - a
        dx2 = 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 = root
        self.canvas = canvas
        self.bottom = bottom
        self.top = top
        self.branches = branches
        self.depth = depth
        self.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 = 0
        self.branch = Branch(self.bottom, self.top, self.branches)
        self.gen(self.depth)
        print "leaves count: %d" % self.leavesCount

    def chgDepth(self, d):
        self.depth += d
        if self.depth < 0: self.depth = 0
        if self.depth > 10: self.depth = 10
        self.new()

    def chgBranch(self, d):
        self.branches += d
        if self.branches < 1: self.branches = 1
        if self.branches > 10: self.branches = 10
        self.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 = newChildren

    def 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 += 1
            self.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, 0
    if dx != 0:
        r = float(dy) / dx
    c = math.sqrt(dx ** 2 + dy ** 2)
    n = int(c / d) + 1
    for i in range(n):
        if dx != 0:
            x = dx * i / n
            y = x * r
        else:
            x = dx
            y = dy * i / n
        if i > 0:
            x += d * (0.5 - random.random()) * 0.25
            y += d * (0.5 - random.random()) * 0.25
        x += x0
        y += y0
        dots.append(Point(x, y))
    dots.append(Point(x1, y1))
    return dots

if __name__ == "__main__":
    root = Tkinter.Tk()
    root.title("Tree")
    gw, gh = 800, 600
    canvas = 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()

Je suppose que tu aimes

Origine www.linuxidc.com/Linux/2020-04/162885.htm
conseillé
Classement