Уведомления

Группа в Telegram: @pythonsu

#1 Март 12, 2010 07:31:26

Cover Story
От:
Зарегистрирован: 2008-08-26
Сообщения: 192
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter: Экземпляр класса

Всем доброго времени суток.
Пытаюсь написать класс, но столкнулся с некоторыми проблемами:
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()



Python 2.7.3
Pyside 1.1.2

Офлайн

#2 Март 13, 2010 10:39:33

Cover Story
От:
Зарегистрирован: 2008-08-26
Сообщения: 192
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter: Экземпляр класса

Второй вопрос остается открытым. С третьим пунктом вроде разобрался. По первому пункту получилось так(привожу полный код):

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()
Только почему я должен добавлять уникальный тег, если это два разных объекта? Где-то ошибка :( Или я чего-то не понимаю.



Python 2.7.3
Pyside 1.1.2

Офлайн

#3 Март 22, 2010 05:49:38

Cover Story
От:
Зарегистрирован: 2008-08-26
Сообщения: 192
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter: Экземпляр класса

В продолжении темы :). Написал метод 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()



Python 2.7.3
Pyside 1.1.2

Офлайн

#4 Март 23, 2010 13:32:00

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

Tkinter: Экземпляр класса

Уже давно смотрю на этот топик. И что бы не возникало мысли о том что это никому не интересно напишу.

Для начала немного обобщенно:
Как вы получите доступ к любому другому элементу в этих функциях? Да так же само. Если вы сделаете класс главного окна то это будет свойство класса, а не глобал, но суть та же.

Попробуем просто функцию.
Есть пробелы в моём понимании того что вы хотите сделать. Но!…
# На код наложены особенности версии 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()
Единственное что процесс растяжения я бы вынес в поток. Ибо если быстро нажать на первую а потом на вторую кнопку то эффект будет очевиден. Попробуйте.

Если же надо хранить информацию о стрелках, пожалуйста. Просто запомните тэг.

upd: Конечно не люблю когда окна пишут вот как вот вряд, а не классом окна, но на работе только блокнот. Поэтому просто подредактировал.



Отредактировано (Март 23, 2010 13:36:19)

Офлайн

#5 Март 23, 2010 19:46:57

Cover Story
От:
Зарегистрирован: 2008-08-26
Сообщения: 192
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter: Экземпляр класса

Griffon Спасибо за разъяснение. Видимо тут подход с использованием класса был ошибочным. Я думал при рисовании стрелок на холсте сам холст полностью не перерисовывается.
Не могли бы Вы дать разъяснение по поводу следующего отрывка:

    items = root.find_withtag(tag)
if items:
root.delete(*items)
root.update()



Python 2.7.3
Pyside 1.1.2

Офлайн

#6 Март 24, 2010 08:22:57

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

Tkinter: Экземпляр класса

По задумке тэг является уникальным идентификатором стрелки. Соответственно если я рисую новую стрелку с таким же тегом то старую надо удалить.

find_withtag(tag)
Ищет все элементы с заданным тэгом и возвращает кортеж с номерами (id) найденных элементов.
Дальше если кортеж не пуст, элементы удаляются. В принципе это было на скорую руку. Можно и без if, просто root.delete(items). Следовательно можно и без items.

root.delete(root.find_withtag(tag))
Как видите я добавил тэг ко всем элементам стрелки. А изменение размера выполняю по идентификатору (id) возвращаемому функцией create_line.

Соответственно если по ходу программы надо удалить стрелку с заданным тэгом, то выполняете canvas_object.delete(canvas_object.find_withtag(tag)).



Отредактировано (Март 24, 2010 11:14:19)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version