Форум сайта python.su
Всем доброго времени суток.
Пытаюсь написать класс, но столкнулся с некоторыми проблемами:
1. Как сделать возможность использования нескольких объектов(создать две и более стрелки)
2. Как создать метод удаления объекта
3. Что такое *coords. Что это работа с координатами я понимаю, но почему поставлена впереди звезда.
Вот пример кода:
from Tkinter import *
import time
class arrowgrow:
def __init__(self, root, height, place):
self.clplace = place
self.clheight = height
self.clroot = root
begy = int(height/2) + place[1]+3
delta = 9
self.m1 = self.clroot.create_line(self.clplace[0]-15, self.clplace[1], self.clplace[0]+15, self.clplace[1])
self.m2 = self.clroot.create_line(self.clplace[0]-15, self.clplace[1]+self.clheight+5, self.clplace[0]+15, self.clplace[1]+self.clheight+5)
self.growline = self.clroot.create_line(self.clplace[0], begy+delta, self.clplace[0], begy-delta, arrow="both", tags="to_r1")
coords = self.clroot.coords("to_r1")
self.clcoords = coords
mmm = int((self.clheight-delta)/2)
for i in range(mmm):
time.sleep(0.01)
self.clcoords[3] = self.clcoords[3] - 1
self.clcoords[1] = self.clcoords[1] + 1
self.clroot.coords("to_r1", *coords)
self.clroot.update()
if __name__ == '__main__':
root = Tk()
c = Canvas(root, width=600, height=600, bg="white")
c.pack()
aa = arrowgrow(c, 200, [50, 10])
bb = arrowgrow(c, 346, [250, 110])
mainloop()
Офлайн
Второй вопрос остается открытым. С третьим пунктом вроде разобрался. По первому пункту получилось так(привожу полный код):
from Tkinter import *
import time
class arrowgrow:
def __init__(self, root, f, height, place):
self.clf = f
self.clplace = place
self.clheight = height
self.clroot = root
begy = int(height/2) + place[1]+3
delta = 9
self.m1 = self.clroot.create_line(self.clplace[0]-15, self.clplace[1], self.clplace[0]+15, self.clplace[1])
self.m2 = self.clroot.create_line(self.clplace[0]-15, self.clplace[1]+self.clheight+5, self.clplace[0]+15, self.clplace[1]+self.clheight+5)
self.growline = self.clroot.create_line(self.clplace[0], begy+delta, self.clplace[0], begy-delta, arrow="both", tags=self.clf)
coords = self.clroot.coords(self.clf)
self.clcoords = coords
mmm = int((self.clheight-delta)/2)
for i in range(mmm):
time.sleep(0.01)
self.clcoords[3] = self.clcoords[3] - 1
self.clcoords[1] = self.clcoords[1] + 1
self.clroot.coords(self.clf, *self.clcoords)
self.clroot.update()
if __name__ == '__main__':
root = Tk()
c = Canvas(root, width=600, height=600, bg="white")
c.pack()
aa = arrowgrow(c, "a", 200, [50, 10])
bb = arrowgrow(c, "b", 346, [250, 110])
mainloop()
Офлайн
В продолжении темы :). Написал метод kill для удаления экземпляра. Но теперь хочу чтобы стрелки рисовались по переменно, т.е. предыдущая стрелка стиралась единственно, насколько мне позволяют мои знания это использование переменной global. Хотя считается что это не совсем правильно. Теперь вопрос, как сделать свой скрипт без использования global?
from Tkinter import *
import time
class arrowgrow:
def __init__(self, root, f, height, place):
self.clf = f
self.clplace = place
self.clheight = height
self.clroot = root
begy = int(height/2) + place[1]+3
delta = 9
self.m1 = self.clroot.create_line(self.clplace[0]-15, self.clplace[1], self.clplace[0]+15, self.clplace[1])
self.m2 = self.clroot.create_line(self.clplace[0]-15, self.clplace[1]+self.clheight+5, self.clplace[0]+15, self.clplace[1]+self.clheight+5)
self.growline = self.clroot.create_line(self.clplace[0], begy+delta, self.clplace[0], begy-delta, arrow="both", tags=self.clf)
coords = self.clroot.coords(self.clf)
self.clcoords = coords
mmm = int((self.clheight-delta)/2)
for i in range(mmm):
time.sleep(0.01)
self.clcoords[3] = self.clcoords[3] - 1
self.clcoords[1] = self.clcoords[1] + 1
self.clroot.coords(self.clf, *self.clcoords)
self.clroot.update()
def kill(self):
self.clroot.delete(self.growline)
self.clroot.delete(self.m1)
self.clroot.delete(self.m2)
if __name__ == '__main__':
def arr1():
global arrovar
if arrovar <> False:
arrovar.kill()
aa = arrowgrow(c, "a", 200, [50, 10])
arrovar = aa
def arr2():
global arrovar
if arrovar <> False:
arrovar.kill()
bb = arrowgrow(c, "b", 346, [250, 110])
arrovar = bb
def arr3():
global arrovar
if arrovar <> False:
arrovar.kill()
cc = arrowgrow(c, "c", 146, [200, 150])
arrovar = cc
arrovar = False
root = Tk()
c = Canvas(root, width=600, height=600, bg="white")
c.pack()
fr = Frame(root)
fr.pack()
bt1 = Button(fr, text = "arr1", command=arr1)
bt1.pack(side = LEFT)
bt2 = Button(fr, text = "arr2", command=arr2)
bt2.pack(side = LEFT)
bt3 = Button(fr, text = "arr3", command=arr3)
bt3.pack(side = LEFT)
mainloop()
Офлайн
Уже давно смотрю на этот топик. И что бы не возникало мысли о том что это никому не интересно напишу.
Для начала немного обобщенно:
Как вы получите доступ к любому другому элементу в этих функциях? Да так же само. Если вы сделаете класс главного окна то это будет свойство класса, а не глобал, но суть та же.
Попробуем просто функцию.
Есть пробелы в моём понимании того что вы хотите сделать. Но!…
# На код наложены особенности версии 3.1. (нет возможности на работе управлять компьютером)
from tkinter import *
import time
def arrowgrow(root, tag, height, place):
items = root.find_withtag(tag)
if items:
root.delete(*items)
root.update()
begy = int(height/2) + place[1]+3
delta = 9
top_line = root.create_line(place[0] - 15, place[1], place[0] + 15, place[1], tags=tag)
bottom_line = root.create_line(place[0] - 15, place[1] + height+5, place[0] + 15, place[1] + height+5, tags=tag)
growline = root.create_line(place[0], begy + delta, place[0], begy - delta, arrow="both", tags=tag)
coords = list(root.coords(growline))
mmm = int((height - delta) // 2)
for i in range(mmm):
time.sleep(0.01)
coords[3] = coords[3] - 1
coords[1] = coords[1] + 1
try:
root.coords(growline, *coords)
except:
break
root.update()
if __name__ == '__main__':
def arr1():
arrowgrow(c, "a", 200, [50, 10])
def arr2():
arrowgrow(c, "b", 346, [250, 110])
def arr3():
arrowgrow(c, "b", 146, [200, 150])
arrovar = False
root = Tk()
c = Canvas(root, width=600, height=600, bg="white")
c.pack()
fr = Frame(root)
fr.pack()
bt1 = Button(fr, text = "arr1", command=arr1)
bt1.pack(side = LEFT)
bt2 = Button(fr, text = "arr2", command=arr2)
bt2.pack(side = LEFT)
bt3 = Button(fr, text = "arr3", command=arr3)
bt3.pack(side = LEFT)
mainloop()
Отредактировано (Март 23, 2010 13:36:19)
Офлайн
Griffon Спасибо за разъяснение. Видимо тут подход с использованием класса был ошибочным. Я думал при рисовании стрелок на холсте сам холст полностью не перерисовывается.
Не могли бы Вы дать разъяснение по поводу следующего отрывка:
items = root.find_withtag(tag)
if items:
root.delete(*items)
root.update()
Офлайн
По задумке тэг является уникальным идентификатором стрелки. Соответственно если я рисую новую стрелку с таким же тегом то старую надо удалить.
find_withtag(tag)
Ищет все элементы с заданным тэгом и возвращает кортеж с номерами (id) найденных элементов.
Дальше если кортеж не пуст, элементы удаляются. В принципе это было на скорую руку. Можно и без if, просто root.delete(items). Следовательно можно и без items.
root.delete(root.find_withtag(tag))
Отредактировано (Март 24, 2010 11:14:19)
Офлайн