我想單擊影像/視窗上的兩個點,為每個點畫一條水平線,它們都可以獨立移動,然后使用這兩個點/線來獲得它們的 Y 位置。
我目前正在考慮的方式是僅繪制兩條在創建程序中可拖動的線。一旦繪制了兩條線,就不應再繪制線了。還應該可以單擊一條線或另一條線來拖動和修改其位置。然后,一旦按下確認按鈕,我只需使用它們的標簽名稱從每個坐標中獲取 y 坐標。
到目前為止,我可以在創建時獲得可拖動的線條,但之后不能。
lines = []
def click(e):
lines.append(canvas.create_line(0, e.y, width, e.y))
def drag(e):
canvas.coords(lines[-1], 0, e.y, width, e.y,)
canvas.bind("<ButtonPress-1>", click)
canvas.bind("<B1-Motion>", drag)
這使您可以根據需要創建和拖動任意數量的線,并且在創建后沒有一條是可移動的。我一直在玩跟蹤索引并且只使用索引 0、1,但無法解決這個問題。
我也可以用它來拖動帶有標簽的預制線
canvas.create_line(0, 150, width, 150, tag="first_line")
canvas.create_line(0, 300, width, 300, tag="second_line")
def find_shape(e):
item = canvas.find_closest(e.x, e.y)
tags = canvas.gettags(item)
print(tags[0])
canvas.bind("<B1-Motion>", lambda event, arg=tags[0]: drag(event, arg))
def drag(e, tag):
canvas.coords(tag, 0, e.y, width, e.y)
canvas.bind("<ButtonPress-1>", find_shape)
def print_y():
print(f"line1 y: {canvas.coords(canvas.find_withtag('first_line'))[1]}")
button = tk.Button(text="print tag y coord", width=30, height=3,
command=print_y)
button.pack()
我的大問題是試圖將它們結合起來。我不確定如何跟蹤第一行是否已創建,以及如何避免用戶創建超過 2 行。處理重疊的<ButtonPress-1>提示也讓我有點困惑。
uj5u.com熱心網友回復:
此代碼canvas.move用于漂亮的物件移動控制。
select 函式通過 key-d 啟用線條繪制并限制物件的總數。
功函式執行線條繪制和物件移動。
在繪圖模式下,滑鼠鍵 1 將繪制線段,而滑鼠鍵 3 將完成繪制。
在移動模式下,滑鼠鍵 1 將剪切畫布物件(拾取),滑鼠鍵 3 將粘貼物件。
我在代碼中插入了有助于解釋各種操作的注釋。
import tkinter as tk
root = tk.Tk()
labelframe = tk.LabelFrame(root, labelanchor = tk.S, text = '0|0')
labelframe.grid(sticky = tk.NSEW)
canvas = tk.Canvas(labelframe, width = 640, height = 480)
canvas.grid(sticky = tk.NSEW)
# Variables
item = xd = yd = 0
# Preset to draw
flag = True
def select(event):
global flag
# limit number of canvas objects or allow object editing
flag = (len(canvas.find_all()) < 2 or item)
def work(event):
global item, xd, yd, flag
# capture mouse pointer position in canvas
xc, yc = canvas.canvasx(event.x), canvas.canvasx(event.y)
if not flag:
# 5 = mouse button release
if int(event.type) == 5:
# cut and move object
if event.num == 1:
item = canvas.find_closest(xc, yc)
if item:
item = item[0]
else:
item = 0
# paste object
elif event.num == 3:
item = 0
if item:
# Use previous and current mouse positions to move item
canvas.move(item, xc - xd, yc - yd)
elif item:
# draw line
bbox = canvas.coords(item)
if int(event.type) == 5:
# mouse button 1 release
if event.num == 1:
bbox.extend([xc, yc])
canvas.coords(item, *bbox)
# line drawing complete
elif event.num == 3:
flag = False
else:
# mouse movement controls line display
canvas.coords(item, bbox[:~1] [xc, yc])
# Make new line object
elif int(event.type) == 5:
if event.num == 1:
item = canvas.create_line(
xd, yd, xc, yc, fill = 'black', tag = 'piece')
labelframe['text'] = f'{xc} | {yc}'
# keep track of previous and current mouse positions
xd, yd = xc, yc
# Press 'd' key to Draw
canvas.bind('<KeyRelease-d>', select)
# handle many inputs via event_add
canvas.event_add('<<PICK>>', '<Motion>', '<ButtonPress>', '<ButtonRelease>')
canvas.bind('<<PICK>>', work)
# make sure canvas has the focus
canvas.focus_force()
root.mainloop()
uj5u.com熱心網友回復:
您可以檢查大小lines以確定是否應創建新行。還可以使用全域變數selected來參考當前選定的行:
lines = []
selected = None # item ID of selected line
def click(e):
global selected
if len(lines) < 2:
# create new line
selected = canvas.create_line(0, e.y, width, e.y)
lines.append(selected)
else:
# check whether a line is under current mouse position
selected = canvas.find_withtag(tk.CURRENT)
def drag(e):
if selected:
canvas.coords(selected, 0, e.y, width, e.y)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/413728.html
標籤:
