Найти - Пользователи
Полная версия: Tkinter: Экземпляр класса
Начало » GUI » Tkinter: Экземпляр класса
1
Cover Story
Всем доброго времени суток.
Пытаюсь написать класс, но столкнулся с некоторыми проблемами:
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()
Cover Story
Второй вопрос остается открытым. С третьим пунктом вроде разобрался. По первому пункту получилось так(привожу полный код):
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()
Только почему я должен добавлять уникальный тег, если это два разных объекта? Где-то ошибка :( Или я чего-то не понимаю.
Cover Story
В продолжении темы :). Написал метод 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()
Griffon
Уже давно смотрю на этот топик. И что бы не возникало мысли о том что это никому не интересно напишу.

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

Попробуем просто функцию.
Есть пробелы в моём понимании того что вы хотите сделать. Но!…
# На код наложены особенности версии 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: Конечно не люблю когда окна пишут вот как вот вряд, а не классом окна, но на работе только блокнот. Поэтому просто подредактировал.
Cover Story
Griffon Спасибо за разъяснение. Видимо тут подход с использованием класса был ошибочным. Я думал при рисовании стрелок на холсте сам холст полностью не перерисовывается.
Не могли бы Вы дать разъяснение по поводу следующего отрывка:
    items = root.find_withtag(tag)
if items:
root.delete(*items)
root.update()
Griffon
По задумке тэг является уникальным идентификатором стрелки. Соответственно если я рисую новую стрелку с таким же тегом то старую надо удалить.

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