Найти - Пользователи
Полная версия: Tkinter canvas определение координат
Начало » GUI » Tkinter canvas определение координат
1 2
Ubhra
Добрый день.
Создаю окно, на нем холст. Нужно что бы по клику выпадало контекстное меню. Получилось, левый верхний угол меню там где кликнул. Но при попытке создать по тем же координатам примитив, оказывается что это координаты экрана, а не холста.

Это клик
canv.bind("<Button-3>", activate_flash_menu)
Это вызов контекстного меню (print добавил для наглядности)
def activate_flash_menu(event):
    global click_x, click_y
    click_x, click_y = canv.winfo_pointerxy()
    flash_menu.tk_popup(click_x, click_y)
    print(click_x, click_y)
А тут создаю примитив
def obj_srv():
    img_srv_x = click_x
    img_srv_y = click_y
    canv.create_rectangle(img_srv_x,img_srv_y,img_srv_x+20,img_srv_y+30,fill="white",outline="blue")
И этот примитив смещается далеко вниз и вправо. Так как координаты клика на экране, а рисует по координатам холста.
4kpt
Ну вот, другое дело. Завтра напишу ответ, потому как уже очень поздно…
4kpt
Напишу сегодня. По причине исправления спрашивающего и размещения им темы там, где ей положено находиться…

import Tkinter

root = Tkinter.Tk()
root.geometry("400x400+100+100")

def activate_flash_menu(event):
posx = event.x_root
posy = event.y_root
posrootx = root.winfo_rootx()
posrooty = root.winfo_rooty()
microcanvas = Tkinter.Canvas(root, height = 40, width = 40, bg = "black")
microcanvas.place(x = posx - posrootx, y = posy - posrooty, anchor = "nw")

canv = Tkinter.Canvas(root, height = 200, width = 200, bg = "red")
canv.place(relx = 0.5, rely = 0.5, anchor = "center")
canv.bind("<Button-3>", activate_flash_menu)

root.mainloop()
Надеюсь общий принцип понятен. Будут еще воросы - смело задавай, но только в нужной ветке…
Забыл сказать. Никого не слушай. Старайся не использовать global - это дурной тон программирования.
Ubhra
Проблема в том что меню я уже вызвал, и по тем же координатам нужно создать примитив.
Клик по холсту, выпадает меню, я выбираю что создать.
Тоесть функция с вызовом меню отдельна и независима.
sp3
from Tkinter import *
 
def foo(event):
    click_x, click_y = w.winfo_pointerxy()
    print "\n click_x, click_y",click_x, click_y
    print " event.x,event.y", event.x,event.y
    x,y = event.x,event.y
    w.create_line(x-10, y+10, x+10, y-10)
    w.create_line(x+10, y+10, x-10, y-10)
     
master = Tk()
 
w = Canvas(master, width=500, height=500)
w.pack()
 
  
w.bind("<Button-3>", foo)
master.mainloop()
sergeek
4kpt
Забыл сказать. Никого не слушай. Старайся не использовать global - это дурной тон программирования.
Ты это так говоришь как-будто я ему этот дурной тон навязал. Глобальные переменные могут быть очень полезны если писать в процедурном стиле.
Никого не слушай.
Старайся не использовать global
/0
4kpt
sergeek
global вредны в любой ситуации уже тем, что неизвестно с какого места они были изменены…
Напримермер, был у меня случай, когда большая программа должна была сохранять в глобал список, а получалось число. Я никак не мог найти, с какого перепугу. Оказалось, что я менял такую же переменную в наследуемом классе. Если бы я ее не глобализировал, то она была бы мной обнаружена быстрее (да и не заменялась бы вообще). Это критично в больших программах…
Кроме того global негативно влияет на работу зборщика мусора ибо это один из видов корневых объектов, с которых происходит поиск зациклившихся ссылок (ищется достижимость объектов)…
4kpt
Ну это еще проще…

import Tkinter

root = Tkinter.Tk()
root.geometry("400x400+100+100")

def create_obj(event = None):
if event[2] == "oval":
ov = canv.create_oval(event[0], event[1], event[0] + 40, event[1] + 40)
if event[2] == "pol":
pol = canv.create_rectangle(event[0], event[1], event[0] + 40, event[1] + 40)


def activate_flash_menu(event = None):
posx = event.x_root
posy = event.y_root
x = event.x
y = event.y

menu = Tkinter.Menu(root, tearoff = 0)
menu.add_command(label = "Кружочек", command = lambda pos = (x, y, "oval"): create_obj(pos))
menu.add_command(label = "Квадратик", command = lambda pos = (x, y, "pol"): create_obj(pos))
menu.tk_popup(posx, posy)

canv = Tkinter.Canvas(root, height = 200, width = 200, bg = "red")
canv.place(relx = 0.5, rely = 0.5, anchor = "center")
canv.bind("<Button-3>", activate_flash_menu)

root.mainloop()
sergeek
4kpt
ну не знаю, все это фиксится правильной организацией кода я думаю. Что делать, например, если нужно дать возможность двум функциям, одна из которых глубоко вложена в другие а вторая нет иметь доступ к одной переменной? Не таскать же ее в качестве аргумента по этим вложенным функциям, а если еще нужно и изменять эту переменную в обоих функциях, то уже никак по-другому не сделаешь, кроме как заинлайнить все эти вложенные функции в один большой кусок говнокода
4kpt
Оказалось, что я менял такую же переменную в наследуемом классе

я же говорил про процедурный стиль, в ООП они не нужны.
А сборщик, не знаю, я думал он удалит из память любой объект на который закончились ссылки, какая разница глобальная переменная или нет
4kpt
Счетчик ссылок - это не сборщик. Я тоже раньше думал, что счетчик ссылок - один из режимов работы сборщика. Ан нет. Рекомендую почитать пост про открытие файла. Там мне подсказали, где почитать информацию о сборщике и о методах его работы… Счетчик ссылок работает всегда, а вот сборщик…
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB