我试图创建一个程序,用户可以在其中添加某些逻辑门,并且可以单独移动。 我试图添加一个计数并连接标签,但它不起作用。 我的程序是我到目前为止所做的,即使在画布上添加相同的门,我也需要一些单独移动门的帮助。
from tkinter import *
canvas=Canvas(width=600,height=600)
canvas.grid()
def andGATE():
canvas.create_line(150,50,150,150,width=5,tag="andgate")
canvas.create_arc(150,50,200,150,start=90,extent=-180,width=5,fill="black",tag="andgate")
canvas.create_line(150,75,120,75,width=5,tag="andgate")
canvas.create_line(150,120,120,120,width=5,tag="andgate")
canvas.create_line(200,100,250,100,width=5,tag="andgate")
canvas.create_rectangle(150,50,180,150,width=5,fill="black",tag="andgate")
canvas.tag_bind("andgate","<B1-Motion>",moveANDGate)
def gateSelected():
sf=var.get()
if sf=='AND':
andGATE()
def moveANDGate(event):
x=event.x
y=event.y
coords=canvas.coords("andgate")
movex=x-coords[0]
movey=y-coords[1]
canvas.move("andgate",movex,movey)
root = Tk()
root.geometry("500x500")
var = StringVar(root)
var.set('AND')
choices = ['AND']
option = OptionMenu(root, var, *choices)
option.pack(side="left",padx=10,pady=10)
button = Button(root, text="Add Gate", command=gateSelected)
button.pack(side="left",padx=10,pady=10)
clearButton = Button(root,text="Clear",command=lambda:clearScreen())
clearButton.pack(side="left",padx=30,pady=10)
root.mainloop()
答案 0 :(得分:1)
您需要为构成单个门的每个画布项集合使用唯一标记。然后,您可以使用该唯一标记将所有项目移动到一起。
为了简化实现,我将通过使用全局变量来说明每个新门的id。使用全局变量不是最好的解决方案,但它肯定是最简单的。
为了使这个答案变得简单,我们将为每个标签添加一个绑定,将标签传递给move函数。也可以为画布设置单个绑定,首先确定单击哪个门。出于这个答案的目的,我们将保持简单并为每个门创建一个独特的绑定。
首先,我们需要修改moveANDgate
以接受唯一标记,以便它知道需要移动哪个标记:
def moveANDGate(event, tag):
x=event.x
y=event.y
coords=canvas.coords(tag)
movex=x-coords[0]
movey=y-coords[1]
canvas.move(tag, movex, movey)
接下来,我们需要创建一个可用于生成唯一标记的全局变量。然后我们可以在andGATE
内使用该变量来创建标记并将其添加到画布中的所有项目。然后,我们需要将函数绑定到新标记的<B1-Motion>
事件。:
gate_id = 0
def andGATE():
global gate_id
gate_id += 1
gate_tag = "andgate-%s" % gate_id
tags = ("andgate", gate_tag)
canvas.create_line(150, 50, 150, 150, width=5, tags=tags)
canvas.create_arc(150, 50, 200, 150, start=90, extent=-180, width=5, fill="black", tags=tags)
canvas.create_line(150, 75, 120, 75, width=5, tags=tags)
canvas.create_line(150, 120, 120, 120, width=5, tags=tags)
canvas.create_line(200, 100, 250, 100, width=5, tags=tags)
canvas.create_rectangle(150, 50, 180, 150, width=5, fill="black", tags=tags)
canvas.tag_bind(gate_tag, "<B1-Motion>", lambda event, tag=gate_tag: moveANDGate(event, tag))
在这个例子中,我给每个项目两个标签:一个是静态字符串“andgate”,另一个是id。这使得可以一次对所有的andgate对象执行某些操作,或者为特定的andgate执行某些操作。将"andgate"
视为类名,将"andgate-<number>"
视为实例名称。这不完全是它们,但从逻辑上讲,这就是它们的使用方式。