Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » Tkinter canvas определение координат [RSS Feed]

#1 Ноя. 15, 2012 00:37:27

Ubhra
От:
Зарегистрирован: 2009-03-04
Сообщения: 133
Репутация: +  2  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

Добрый день.
Создаю окно, на нем холст. Нужно что бы по клику выпадало контекстное меню. Получилось, левый верхний угол меню там где кликнул. Но при попытке создать по тем же координатам примитив, оказывается что это координаты экрана, а не холста.

Это клик

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")
И этот примитив смещается далеко вниз и вправо. Так как координаты клика на экране, а рисует по координатам холста.



Офлайн

#2 Ноя. 15, 2012 01:07:38

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

Ну вот, другое дело. Завтра напишу ответ, потому как уже очень поздно…



Отредактировано 4kpt (Ноя. 15, 2012 01:07:57)

Офлайн

#3 Ноя. 15, 2012 01:28:31

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

Напишу сегодня. По причине исправления спрашивающего и размещения им темы там, где ей положено находиться…

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 - это дурной тон программирования.



Отредактировано 4kpt (Ноя. 15, 2012 01:32:21)

Офлайн

#4 Ноя. 15, 2012 02:08:38

Ubhra
От:
Зарегистрирован: 2009-03-04
Сообщения: 133
Репутация: +  2  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

Проблема в том что меню я уже вызвал, и по тем же координатам нужно создать примитив.
Клик по холсту, выпадает меню, я выбираю что создать.
Тоесть функция с вызовом меню отдельна и независима.



Офлайн

#5 Ноя. 15, 2012 06:53:20

sp3
От:
Зарегистрирован: 2010-01-12
Сообщения: 405
Репутация: +  18  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

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()



Отредактировано sp3 (Ноя. 15, 2012 06:54:41)

Офлайн

#6 Ноя. 15, 2012 09:23:16

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

4kpt
Забыл сказать. Никого не слушай. Старайся не использовать global - это дурной тон программирования.
Ты это так говоришь как-будто я ему этот дурной тон навязал. Глобальные переменные могут быть очень полезны если писать в процедурном стиле.
Никого не слушай.
Старайся не использовать global
/0

Офлайн

#7 Ноя. 15, 2012 09:55:50

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

sergeek
global вредны в любой ситуации уже тем, что неизвестно с какого места они были изменены…
Напримермер, был у меня случай, когда большая программа должна была сохранять в глобал список, а получалось число. Я никак не мог найти, с какого перепугу. Оказалось, что я менял такую же переменную в наследуемом классе. Если бы я ее не глобализировал, то она была бы мной обнаружена быстрее (да и не заменялась бы вообще). Это критично в больших программах…
Кроме того global негативно влияет на работу зборщика мусора ибо это один из видов корневых объектов, с которых происходит поиск зациклившихся ссылок (ищется достижимость объектов)…



Отредактировано 4kpt (Ноя. 15, 2012 10:59:28)

Офлайн

#8 Ноя. 15, 2012 10:33:23

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

Ну это еще проще…

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()



Отредактировано 4kpt (Ноя. 15, 2012 10:35:50)

Офлайн

#9 Ноя. 15, 2012 11:38:25

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

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

4kpt
Оказалось, что я менял такую же переменную в наследуемом классе

я же говорил про процедурный стиль, в ООП они не нужны.
А сборщик, не знаю, я думал он удалит из память любой объект на который закончились ссылки, какая разница глобальная переменная или нет

Отредактировано sergeek (Ноя. 15, 2012 11:47:31)

Офлайн

#10 Ноя. 15, 2012 11:56:59

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Tkinter canvas определение координат

Счетчик ссылок - это не сборщик. Я тоже раньше думал, что счетчик ссылок - один из режимов работы сборщика. Ан нет. Рекомендую почитать пост про открытие файла. Там мне подсказали, где почитать информацию о сборщике и о методах его работы… Счетчик ссылок работает всегда, а вот сборщик…



Отредактировано 4kpt (Ноя. 15, 2012 12:00:45)

Офлайн

  • Начало
  • » GUI
  • » Tkinter canvas определение координат[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version