如何在标签结束时绘制箭头

时间:2017-04-04 14:16:57

标签: python tkinter label

我想画一个标签结束时开始的箭头。我写了一些代码: `     将Tkinter导入为tk

from Tkinter import *

methods=["m1","m2"]
results=["r1","r2"]
pos_x_of_image=100
pos_y_of_image=150
frame_size_x=850
frame_size_y=550

def main(): 
    root = Tk()
    canvas=Canvas(root)
    canvas.config(width=frame_size_x, height=frame_size_y)
    root.title("window")

    root.geometry('%dx%d'%(frame_size_x,frame_size_y))
    for i in range(0,len(methods)):
        create_label(canvas, methods[i], pos_x_of_image+100, 50 +i*int(frame_size_y/int(len(methods))))
        create_arrow(canvas, pos_x_of_image, pos_y_of_image+50, pos_x_of_image+100, 60 +i*int(frame_size_y/int(len(methods))))
        for j in range(0,2): 
            if j==0:  
                create_label(canvas, methods[i], pos_x_of_image+170+4*int(len(methods[i])), 30 +j*40+i*int(frame_size_y/int(len(methods))))
                create_arrow(canvas,label_width ,label_height , pos_x_of_image+170+4*int(len(methods[i])), 40 +j*40+i*int(frame_size_y/int(len(methods))))
                if j==1:
                    create_label(canvas, results[j], pos_x_of_image+170+4*int(len(methods[i])), 30 +j*40+i*int(frame_size_y/int(len(methods))))
                    create_arrow(canvas,label_width ,label_height, pos_x_of_image+170+4*int(len(methods[i])), 30 +j*40+i*int(frame_size_y/int(len(methods))))
    canvas.pack()

    root.mainloop()

def create_arrow(canvas,x_start,y_start,x_finish,y_finish):
    id = canvas.create_line(x_start,y_start,x_finish,y_finish,arrow=tk.LAST)

def create_label(canvas,method,x_start,y_start):
    w=Label(canvas,text=method)
    w.place(x=x_start,y=y_start)
    return w

if __name__ == '__main__':
    main()

问题在于行create_arrow(canvas,label_width ,label_height, pos_x_of_image+170+4*int(len(methods[i])), 30 +j*40+i*int(frame_size_y/int(len(methods)))),因为我不知道如何获得标签宽度和高度。

1 个答案:

答案 0 :(得分:1)

您面临的问题是窗口小部件的宽度在实际绘制之前是不确定的,因为宽度可能会受到添加到窗口的方式的影响。

但是,在您的情况下,您可以通过强制更新来计算宽度和高度。例如,将创建标签和箭头的代码更改为:

l = create_label(...)
canvas.update()
label_width = l.winfo_width()
label_height = l.winfo_height()

create_arrow(canvas,label_width ,label_height, ...)

如果您不想强制更新,您还可以执行其他操作。例如,您可以在画布上使用文本对象而不是标签小部件:

l = create_label(...)
bbox = canvas.bbox(l)
label_width = bbox[2]-bbox[0]
label_height = bbox[3]-bbox[1]
...
def create_label(canvas,method,x_start,y_start):
    w = canvas.create_text(x_start, y_start, text=method, anchor="nw")
    return w
...

第二种方法更为可取,因为添加到带有place的画布的对象不会随着画布对象一起滚动。