Tkinter会在每次点击鼠标时创建缩小的圆圈,如何通过多次点击使其工作?

时间:2018-05-31 21:10:04

标签: python-3.x function tkinter bind tkinter-canvas

我正在创建一个简单的程序,通过每次单击鼠标在每个单击的位置绘制一个缩小的随机颜色圈。每次单击都会创建一个直径为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 :(得分:4)

如果你将所有内容都移到一个类中,那么每个圆圈都将是它自己的实例,并且不会相互干扰。

查看以下修改后的代码版本。它可能并不完美,但应该是你工作的良好基础。

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

答案 1 :(得分:1)

如上所述,您不需要类来解决此问题,也不需要嵌套函数。正如@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()