如何在tkinter画布上绘制弧线? [英] How to draw an arc on a tkinter canvas?

查看:447
本文介绍了如何在tkinter画布上绘制弧线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习自动机理论,并被要求编写一个自动机的图形(树),看起来或多或少像这样:



到目前为止,我得到了这个(我'使用 tkinter 画布绘制):

<$从tkinter导入T pre $ code> Tk,Canvas,mainloop

def circle(canvas,x,y,r,width):
id = canvas.create_oval xr,yr,x + r,y + r,width = width)
返回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 =画布(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, (w,10,300,80,300,3)
circle(w,73,300,5,6)
line(w, (w,293,300,5,6)
line(w,440,300,570,300,3)
circle(w,293,300,5,6)
circle $
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)
文本(w,910,300,q3)

w.pack()
mainloop()

其中显示:



我不需要箭头,因为我会用点代替。问题是我需要画一条从圆圈q3到圆圈q0,从圆圈q0到圆圈q0的线条(一个bucle)。我尝试了 canvas.create_arc()方法,但我无法得到它的句柄。有其他选择吗?关于如何绘制bucle的任何想法?

解决方案

这里有一些实用函数提供了一种替代方法, code> tkinter.Canvas 。代替通常的两点指定(x0,y0)和(x1,y1)来定义一个圆弧函数在 [0..360)度的开放范围内接受起始和终止角度

它还说明了如何在绘制直线的末端绘制箭头(但不是圆弧),因为您也询问了这一点。

  from tkinter import Canvas,mainloop,Tk 

def circle(canvas,x,y,r,width):
return canvas.create_oval( x + r,y + r,xr,yr,width = width)

def circular_arc(canvas,x,y,r,t0,t1,width):
return canvas.create_arc (xr,yr,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):
返回canvas.creat e_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
arrow = {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 =画布(Tk(),width = 1000,height = 600,bg ='white')

circle(w, (w,150,300,70,3)#q0外边缘
circle(w,150,300,50,3)#q0内边缘
circle(w,370,300,70,3)#q1
circle(w,640,300,70,3)#q2
circle(w,910,300,70,3)#q3

#从圆弧画出圆弧q3到q0。
midx,midy =(150 + 910)/ 2,300
r1,r2 = 910-midx,70 + 70
elliptical_arc(w,midx,midy,r1,r2,30, (w,10,300,80,300,3,end_arrow = 1)
line(w,220,300,300,300,300)3

line
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()

这就是它所画的:



它并没有像你想要的那样画出一个扣,部分原因是画从圆圈q3到圆圈q0,从圆圈q0到圆圈q0不是像在你的问题开始的插图是两个圈子之间绘制的(如果我在下面)然而,它确实为您在画布上绘制圆弧提供了另一种方式


I'm studying automata theory and I was requested to program the graph (tree) of an automaton that looks more or less like:

So far I got this (I'm using tkinter and canvas to draw):

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()

Which displays this:

I don't need the arrows, because I will use dots instead. The problem is that I need to draw a line from circle q3 to circle q0, and from circle q0 to circle q0, too (a "bucle"). I tried the canvas.create_arc() method, but I can't get the handle of it. Is there an alternative? Any ideas on how to draw the "bucle"?

解决方案

Here's some utility functions that provide an alternative way draw arcs on a tkinter.Canvas. Instead of the usual specification of two-points, (x0, y0) and (x1, y1) to define an enclosing rectangle, the arc functions accept a starting and stopping angle in the open range of [0..360) degrees.

It also illustrates how to have arrowheads drawn at the ends of straight lines (but not arcs) since you asked about that, too.

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()

This is what it draws:

It doesn't draw a "buckle" like you want partly because drawing "a line from circle q3 to circle q0, and from circle q0 to circle q0" isn't like the illustration at the beginning of your question which is one drawn between two circles (if I understand correctly what you meant by the term).

However, it does provide another way for you to draw arcs on a canvas.

这篇关于如何在tkinter画布上绘制弧线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆