Получить смещение от Tkinter ScrollBar и пересчитать положение элемента холста по клику - PullRequest
0 голосов
/ 07 января 2020

Мне удалось реализовать canvas и scrollBar горизонтального и вертикального типа. Я добавляю каждый раз, когда нажимаю на холст, новый объект. Если я прокручиваю холст в любом праве и не могу добавить какой-либо новый объект, или приложение добавляет новый объект в неправильную позицию (без позиции прокрутки).

Мне нужны дельта из hor и ver scrollBar для получения правильных входных параметров.

Часть реализации ScrollBars:

canvasFrame = tkinter.Frame(window,
                            width=screen_width - 110,
                            height=screen_height - 110,
                            background="#f3ffff")
canvasFrame.place(x=105, y=20, width=screen_width - 115, height=screen_height - 130)

canvas = tkinter.Canvas(
    canvasFrame,
    width=screen_width * initValues.canvasScreenCoeficientW,
    height=screen_height * initValues.canvasScreenCoeficientH,
    background=initValues.windowBackgroundColor,
    scrollregion=(0,0,
                  screen_width * initValues.canvasScreenCoeficientW,
                  screen_height * initValues.canvasScreenCoeficientH)
  )
# canvas.place(x=0, y=0, width= 2 *screen_width - 120, height=screen_height - 130)

canvas.bind("<Button-1>", collectMouseEventData)

# Scroll bars for canvas
hCanvasBar = tkinter.Scrollbar(canvasFrame,orient=tkinter.HORIZONTAL)
hCanvasBar.pack(side=tkinter.BOTTOM,fill=tkinter.X)
hCanvasBar.config(command=canvas.xview)
vCanvasBar = tkinter.Scrollbar(canvasFrame,orient=tkinter.VERTICAL)
vCanvasBar.pack(side=tkinter.RIGHT,fill=tkinter.Y)
vCanvasBar.config(command=canvas.yview)

canvas.config(xscrollcommand=hCanvasBar.set, yscrollcommand=vCanvasBar.set)

canvas.pack(side=tkinter.LEFT,expand=True,fill=tkinter.BOTH)

Добавление новой части элемента

Метод recalculateX и recalculateY просто привязывает точку щелчка к ближайшей линии сетки.

Мне нужно что-то вроде: + = deltax

 def collectMouseEventData(event):
  if event.y > 0 and event.x > 50:
    # print("clicked at", event.x, event.y)
    x = event.x
    y = event.y
    local = "x:" + str(event.x) + ", y:" + str(event.y)
    appCoordinate.configure(text=local)

    if initValues.stickler["enabledX"] == True:
      x = editorStickler.recalculateX(x)
      # print("Enabled X stickler.")

    if initValues.stickler["enabledY"] == True:
      y = editorStickler.recalculateY(y)
      # print(" Y ")

    localModel = 0
    #RESOURCE_INDENTITY
    filename = selectedTex.split('\\')
    filenameStr = "require('../../imgs/" + filename[len(filename) -2] + "/" +  filename[len(filename) -1] + "')"
    if insertBox.get() == "ground":
      localModel = StaticGrounds(x,
                                y,
                                initValues.ELEMENT_WIDTH,
                                initValues.ELEMENT_HEIGHT,
                                filenameStr,
                                initValues.tilesX,
                                initValues.tilesY)

1 Ответ

1 голос
/ 07 января 2020

У холста есть методы для преобразования координат из координат окна в координаты холста. Вы должны передать event.x и event.y методам canvasx и canvasy соответственно.

Вот простой пример:

import tkinter as tk

def handle_click(event):
    canvas = event.widget
    x = canvas.canvasx(event.x)
    y = canvas.canvasy(event.y)
    canvas.create_rectangle(x-2, y-2,x+1,y+2, fill="red")
    canvas.create_text(x,y+8, text=f"({x},{y})", anchor="n")
    canvas.configure(scrollregion=canvas.bbox("all"))

root = tk.Tk()
canvas = tk.Canvas(root, background='bisque')
ysb = tk.Scrollbar(root, orient="vertical", command=canvas.yview)
xsb = tk.Scrollbar(root, orient="horizontal", command=canvas.xview)
canvas.configure(yscrollcommand=ysb.set, xscrollcommand=xsb.set)

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

canvas.grid(row=0, column=0, sticky="nsew")
ysb.grid(row=0, column=1, sticky="ns")
xsb.grid(row=1, column=0, sticky="ew")

canvas.bind("<1>", handle_click)

root.mainloop()
...