Ткинтер создает уменьшающий круг при каждом щелчке мыши, как заставить его работать несколькими щелчками мыши? - PullRequest
0 голосов
/ 01 июня 2018

Я создаю простую программу, которая рисует уменьшающийся круг случайного цвета в каждом месте щелчка при каждом щелчке мыши.Каждый щелчок создает круг диаметром 50, который сразу начинает уменьшаться до 0.Каждый клик должен создать новый сокращающийся круг.

Однако моя программа останавливает сжатие первого круга после того, как я щелкну и создам другой круг.Это полностью сжимает только последний созданный круг.Все остальные остаются на месте.Я считаю, что проблема заключается в самой функции.Он вызывает ту же функцию, которая не завершена.Как заставить его запускаться несколько раз (на каждый клик отдельно)?Или я ошибаюсь с локальными и глобальными переменными?

Вот мой код:

import tkinter
import random
c = tkinter.Canvas(width = 400, height = 300)
c.pack()

def klik(event):
    global x, y, farba, circ, r
    r = 50      #circle diameter
    x, y = event.x, event.y     #clicked position
    color = '#{:06x}'.format(random.randrange(256 ** 3))        #random  color picker
    circ = c.create_oval(x - r, y - r, x + r, y + r, fill=color)         #print circle
    print(x, y, farba)      #check clicked coordinates, not important
    if r < 50:      #reset size after each circle
        r = 50
    shrink()

def shrink():
    global circ, x, y, r
    print(r)        #check if countdown runs correctly
    if r > 0:
        r -= 1      #diameter shrinking
        c.coords(circ, x-r, y-r, x+r, y+r)      #changing circle size
        c.after(100, shrink)        #timer, size 1pt smaller until size is 0

c.bind('<Button-1>', klik)
tkinter.mainloop()

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Как уже отмечалось, вам не нужны ни классы для решения этой, ни вложенные функции.Ключ, на который намекал @LioraHaydont, заключается в том, что вам нужно использовать локальные, а не глобальные переменные:

import tkinter as tk
from random import randrange

def klik(event):
    r = 50  # circle radius
    x, y = event.x, event.y  # clicked position
    color = '#{:06x}'.format(randrange(256 ** 3))  # random color picker
    c = canvas.create_oval(x - r, y - r, x + r, y + r, fill=color)  # print circle
    canvas.after(100, shrink, c, x, y, r)

def shrink(c, x, y, r):
    if r > 0:
        r -= 1  # radius shrinking
        canvas.coords(c, x - r, y - r, x + r, y + r)  # changing circle size
        canvas.after(100, shrink, c, x, y, r)  # timer, size 1pt smaller until size is 0

canvas = tk.Canvas(width=400, height=300)
canvas.pack()
canvas.bind('<Button-1>', klik)

tk.mainloop()
0 голосов
/ 01 июня 2018

Если вы переместите все в класс, то каждый круг будет его собственным экземпляром и не будет мешать друг другу.

Посмотрите на модифицированную ниже версию вашего кода.Возможно, он не идеален, но должен быть хорошим основанием для работы с вами.

import tkinter
import random


c = tkinter.Canvas(width = 400, height = 300)
c.pack()

class create_circles():
    def __init__(self, event):
        self.r = 50
        self.x, self.y = event.x, event.y
        self.color = '#{:06x}'.format(random.randrange(256 ** 3))
        self.circ = c.create_oval(self.x - self.r, self.y - self.r, self.x + self.r, self.y + self.r, fill=self.color)
        self.shrink()

    def shrink(self):
        if self.r > 0:
            self.r -= 1
            c.coords(self.circ, self.x-self.r, self.y-self.r, self.x+self.r, self.y+self.r)
            c.after(100, self.shrink)

c.bind('<Button-1>', create_circles)
tkinter.mainloop()

Есть еще один способ сделать это вне класса.

Вы можете использовать вложенныефункционировать и избегать глобальных.Ваши проблемы в вашем вопросе на самом деле вызваны тем, что все зависит от глобальных переменных.

Попробуйте этот код ниже для опции, не относящейся к классу.

import tkinter
import random


c = tkinter.Canvas(width = 400, height = 300)
c.pack()

def klik(event):
    r = 50
    x, y = event.x, event.y
    color = '#{:06x}'.format(random.randrange(256 ** 3))
    circ = c.create_oval(x - r, y - r, x + r, y + r, fill=color)

    def shrink(r, x, y, color, circ):
        if r > 0:
            r -= 1
            c.coords(circ, x-r, y-r, x+r, y+r)
            c.after(100, shrink, r, x, y, color, circ)

    shrink(r, x, y, color, circ)

c.bind('<Button-1>', klik)
tkinter.mainloop()
...