abh*_*era 5 python graphics tree canvas tkinter
我正在学习自动机理论,我被要求编写一个看起来或多或少类似于的自动机的图(树):
到目前为止,我得到了这个(我正在使用tkinter并canvas绘制):
from tkinter import Tk, Canvas, mainloop
def circle(canvas, x, y, r, width):
id = canvas.create_oval (x-r, y-r, x+r, y+r, width = width)
return id
def line (canvas, x1, y1, x2, y2, width):
canvas.create_line (x1, y1, x2, y2, width = width)
def text (canvas, x, y, text):
canvas.create_text (x, y, text = text, font = ("bold", 20))
w = Canvas(Tk (), width=1000, height=600, bg = "white")
circle (w , 150, 300, 70, 3)
circle (w , 150, 300, 50, 3)
circle (w , 370, 300, 70, 3)
circle (w , 640, 300, 70, 3)
circle (w , 910, 300, 70, 3)
line (w, 10, 300, 80, 300, 3)
circle (w, 73, 300, 5, 6)
line (w, 220, 300, 300, 300, 3)
circle (w, 293, 300, 5, 6)
line (w, 440, 300, 570, 300, 3)
circle (w, 567, 300, 5, 6)
line (w, 710, 300, 840, 300, 3)
circle (w, 837, 300, 5, 6)
text (w, 150, 300, "q0")
text (w, 370, 300, "q1")
text (w, 640, 300, "q2")
text (w, 910, 300, "q3")
w.pack()
mainloop()
Run Code Online (Sandbox Code Playgroud)
显示这个:
我不需要箭头,因为我会用点代替。问题是我需要从圆 q3 到圆 q0,以及从圆 q0 到圆 q0(一个“bucle”)画一条线。我试过这个canvas.create_arc()方法,但我无法掌握它。有替代方案吗?关于如何绘制“bucle”的任何想法?
下面是一些实用函数,它们提供了在tkinter.Canvas. 代替通常的两点指定,(x0, y0)并(x1, y1)定义一个封闭的矩形,arc 函数接受在开放度数范围内的开始和停止角度[0..360)。
它还说明了如何在直线(但不是圆弧)的末端绘制箭头,因为你也问过这个问题。
from tkinter import Canvas, mainloop, Tk
def circle(canvas, x, y, r, width):
return canvas.create_oval(x+r, y+r, x-r, y-r, width=width)
def circular_arc(canvas, x, y, r, t0, t1, width):
return canvas.create_arc(x-r, y-r, x+r, y+r, start=t0, extent=t1-t0,
style='arc', width=width)
def ellipse(canvas, x, y, r1, r2, width):
return canvas.create_oval(x+r1, y+r2, x-r1, y-r2, width=width)
def elliptical_arc(canvas, x, y, r1, r2, t0, t1, width):
return canvas.create_arc(x-r1, y-r2, x+r1, y+r2, start=t0, extent=t1-t0,
style='arc', width=width)
def line(canvas, x1, y1, x2, y2, width, start_arrow=0, end_arrow=0):
arrow_opts = start_arrow << 1 | end_arrow
arrows = {0b10: 'first', 0b01: 'last', 0b11: 'both'}.get(arrow_opts, None)
return canvas.create_line(x1, y1, x2, y2, width=width, arrow=arrows)
def text(canvas, x, y, text):
return canvas.create_text(x, y, text=text, font=('bold', 20))
w = Canvas(Tk(), width=1000, height=600, bg='white')
circle(w, 150, 300, 70, 3) # q0 outer edge
circle(w, 150, 300, 50, 3) # q0 inner edge
circle(w, 370, 300, 70, 3) # q1
circle(w, 640, 300, 70, 3) # q2
circle(w, 910, 300, 70, 3) # q3
# Draw arc from circle q3 to q0.
midx, midy = (150+910) / 2, 300
r1, r2 = 910-midx, 70+70
elliptical_arc(w, midx, midy, r1, r2, 30, 180-30, 3)
line(w, 10, 300, 80, 300, 3, end_arrow=1)
line(w, 220, 300, 300, 300, 3, end_arrow=1)
line(w, 440, 300, 570, 300, 3, end_arrow=1)
line(w, 710, 300, 840, 300, 3, end_arrow=1)
text(w, 150, 300, 'q0')
text(w, 370, 300, 'q1')
text(w, 640, 300, 'q2')
text(w, 910, 300, 'q3')
w.pack()
mainloop()
Run Code Online (Sandbox Code Playgroud)
这是它画的:
它没有像你想要的那样画一个“扣”,部分原因是画“从圈 q3 到圈 q0,从圈 q0 到圈 q0”不像你的问题开头的插图,它是在两者之间画的两个圆圈(如果我理解正确的话)。
但是,它确实为您提供了另一种在canvas.