如何让程序知道两个项目相互接触?Python/tkinter
我希望能够在画布上添加许多门,但当它们触摸输出或输入行时,程序知道它们正在触摸并输出消息,例如“and gate连接到and gate”。 这是将门插入画布的代码。我曾尝试将输入/输出行制作成不同的标签,可以相互识别,但没有成功。有什么建议吗如何让程序知道两个项目相互接触?Python/tkinter,python,tkinter,Python,Tkinter,我希望能够在画布上添加许多门,但当它们触摸输出或输入行时,程序知道它们正在触摸并输出消息,例如“and gate连接到and gate”。 这是将门插入画布的代码。我曾尝试将输入/输出行制作成不同的标签,可以相互识别,但没有成功。有什么建议吗 from tkinter import * canvas=Canvas(width=600,height=600) canvas.grid() gate_id = 0 def andGATE(): global gate_id gate
from tkinter import *
canvas=Canvas(width=600,height=600)
canvas.grid()
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))
def gateSelected():
sf=var.get()
if sf=='AND':
andGATE()
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)
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()
从tkinter导入*
画布=画布(宽度=600,高度=600)
canvas.grid()
门id=0
def和gate():
全局门id
门id+=1
gate\u tag=“andgate-%s”%gate\u id
标签=(“andgate”,gate_标签)
画布。创建线(150,50,150,150,宽度=5,标签=标签)
canvas.create_弧(150,50,200,150,开始=90,范围=180,宽度=5,fill=“black”,tags=tags)
画布。创建线(150,75,120,75,宽度=5,标签=标签)
画布。创建线(150、120、120、120,宽度=5,标记=标记)
画布。创建线(200100250100,宽度=5,标签=tags)
画布。创建一个矩形(150,50,180,150,宽度=5,fill=“black”,tags=tags)
canvas.tag_bind(gate_tag,“”,lambda事件,tag=gate_tag:moveANDGate(事件,标记))
def gateSelected():
sf=var.get()
如果sf=='和':
andGATE()
def moveANDGate(事件、标记):
x=事件.x
y=事件。y
coords=canvas.coords(标记)
movex=x-coords[0]
movey=y坐标[1]
canvas.move(标记、movex、movey)
root=Tk()
根几何(“500x500”)
var=StringVar(根)
var.set('和')
选项=['和']
选项=选项菜单(根、变量、*选项)
选项包(side=“left”,padx=10,pady=10)
按钮=按钮(根,text=“添加门”,命令=门已选定)
按钮包(side=“left”,padx=10,pady=10)
clearButton=Button(root,text=“Clear”,command=lambda:clearScreen())
clearButton.pack(side=“left”,padx=30,pady=10)
root.mainloop()
这不是一个完整的答案,而是朝着正确方向迈出的可行的一步
from tkinter import *
gate_id = 0
def andGATE():
global gate_id
gate_id += 1
gate_tag = "andgate-%s" % gate_id
tags = ("andgate", gate_tag)
inputs = ("andgate", gate_tag, "input")
outputs = ("andgate", gate_tag, "output")
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)
#End of output
canvas.create_line(250,100,245,100, width=5, fill="red", tags=outputs)
#End of inputs
canvas.create_line(150, 75, 120, 75, width=5, tags=tags)
canvas.create_line(120, 75, 125, 75, width=5, fill="blue", tags=inputs)
canvas.create_line(120, 120, 125, 120, width=5, fill="blue", tags=inputs)
canvas.create_rectangle(150, 50, 180, 150, width=5, fill="black", tags=outputs)
canvas.tag_bind(gate_tag, "<B1-Motion>", lambda event, tag=gate_tag: moveANDGate(event, tag))
def gateSelected():
sf=var.get()
if sf=='AND':
andGATE()
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)
#print("Move")
#Determine if we have an overlap between an input and an output
for item in canvas.find_all():
tags = canvas.gettags(item)
if tag in tags:
if 'input' in tags:
#current item is an input of the moved object
#Get the items coordinates
coords = canvas.coords(item)
#Find if we overlap with other objects
closest = canvas.find_overlapping(coords[0],coords[1],coords[2],coords[3])
for closest_items in closest:
closest_tags = canvas.gettags(closest_items)
if 'output' in closest_tags:
#If we overlap with another object, print connected and the appropriate tags
print("connected", closest_tags, "-", tag)
root = Tk()
root.geometry("500x500")
canvas=Canvas(root,width=300,height=300)
canvas.pack()
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=calculate)
#clearButton.pack(side="left",padx=30,pady=10)
root.mainloop()
如果端口之间的距离在5像素以内,则它们将对齐。(对于超过两个闸门的情况,这一点目前并不十分有效。)我没有完整的答案,但我有一个可行的概念。在每个与门输入/输出端口的末端创建一个额外的画布行项目(1像素大小)。给这些项目一个类似“输入”“输出”的标记。移动闸门时,检查闸门的任何输入是否接近另一闸门的输出。如果两者之间的距离为零,则有一个连接。如果项目与另一个项目的距离在几个像素以内,也可以进行项目“捕捉”。
#Determine if we have an overlap between an input and an output
for item in canvas.find_all():
tags = canvas.gettags(item)
if tag in tags:
if 'input' in tags:
#current item is an input of the moved object
#Get the items coordinates
coords = canvas.coords(item)
#Find if we overlap with other objects
closest = canvas.find_overlapping(coords[0]-5,coords[1]-5,coords[2]+5,coords[3]+5)
for closest_item in closest:
closest_tags = canvas.gettags(closest_item)
if 'output' in closest_tags:
#If we overlap with another object, print connected and the appropriate tags
print("connected", closest_tags, "-", tag)
connected_coords = canvas.coords(closest_item)
snapx = coords[0] - connected_coords[0]
snapy = coords[1] - connected_coords[1]
canvas.move(tag, -snapx, -snapy)