简体   繁体   English

Python:如何在函数内部停止循环函数?

[英]Python: How to stop a looping function inside a function?

I wrote this code which creates an oval in tkinter. 我写了这段代码,在tkinter中创建了一个椭圆形。 When clicked on by a mouse, the oval creates new coordinates for itself and then starts pulsating. 当用鼠标单击时,椭圆会为其自身创建新坐标,然后开始脉动。

It goes like this: 1.the oval is created by default 2.On click, a function "click" is called 3.The click function generates new coordinates, draws the oval and then starts the pulsating looping effect. 它是这样的:1.默认情况下创建椭圆形2.单击时,将调用函数“ click”。3.click函数生成新坐标,绘制椭圆形,然后启动脉动循环效果。 4.Now I should be able and can click again on the pulsating oval, to move the oval to a new location and then loop that new oval again(pulsate). 4.现在,我应该能够并且可以再次单击脉动的椭圆,将椭圆移动到新位置,然后再次循环该新椭圆(脉动)。

    def click(event):
        pick = 2
        counter = 0
        esimene_x1 = randint(0, w-100)
        esimene_y1 = randint(0, h-100)
        teine_x1 = esimene_x1
        teine_y1 = esimene_y1
        canvas.coords(circle1, esimene_x1, esimene_y1, teine_x1, teine_y1)
        pulsate(esimene_x1, esimene_y1, teine_x1, teine_y1, pick, counter)

    def pulsate(esimene_x1, esimene_y1, teine_x1, teine_y1, pick, counter):
        if pick % 2 == 0:
            esimene_x1 -= 1
            esimene_y1 -= 1
            teine_x1 += 1
            teine_y1 += 1
            counter += 1
            if counter == 40:
                pick += 1
        elif pick % 2 != 0:
            esimene_x1 += 1
            esimene_y1 += 1
            teine_x1 -= 1
            teine_y1 -= 1
            counter -=1
            if counter == 0:
                pick += 1
        s = esimene_x1, esimene_y1, teine_x1, teine_y1, pick, counter
        canvas.coords(circle1, esimene_x1,esimene_y1,  teine_x1,teine_y1)
        raam.after(50, pulsate, *s)

However, when I click again on the pulsating oval now, it kinda bugs and it looks like the previous function for the looping pulsating effect is still doing its thing and the new pulsating begins at different coordinates. 但是,当我现在再次单击脉动椭圆时,它似乎有点bug,并且看起来像以前的循环脉动效果功能仍在起作用,新的脉动始于不同的坐标。 So, my question is, how do I stop the function from looping(pulsating), when that function is in a function, and i want to start the first function again. 所以,我的问题是,当该函数在函数中时,如何停止该函数的循环(脉动),我想再次启动第一个函数。 (Create, new coordinates and start the pulsating over) (创建新坐标并开始脉动)

Here is the file that you can run and see exactly what seems to happen: 这是您可以运行的文件,可以确切地看到发生了什么:

https://mega.co.nz/#!e5pj0brC!QW6R4X9WTshOCh3FTybLrQu_oI0OOU6wL5QI61punUE https://mega.co.nz/#!e5pj0brC!QW6R4X9WTshOCh3FTybLrQu_oI0OOU6wL5QI61punUE

Also, if you see anything else that seems to be causing this bug, then let me know please. 另外,如果您发现其他可能导致此错误的原因,请告诉我。 I have not yet acquired knowledge of threading and classes in python, but if that is the only solution then please let me know! 我尚未掌握python中的线程和类知识,但是如果这是唯一的解决方案,请告诉我! Else would appreciate if it can be managed with some easier methods! 否则,如果可以使用一些更简单的方法来管理它,将不胜感激!

Thank you very much! 非常感谢你!

That's no bug. 那不是虫子。 Your click method triggers the pulsate method, which then triggers itself again. 您的click方法将触发pulsate方法,然后再次触发自身。 If you call click again, it triggers pulsate again, but that's a different "instance" of pulsate (in lack of a better term) with no reference to the other one, running simultaneously. 如果你打电话click一次,它会触发pulsate一次,但是这是一个不同的“实例” pulsate (在没有更好的术语的),没有提及另外一个,同时运行。

Instead, you should use a global variable to hold the oval coordinates. 相反,您应该使用global变量来保存椭圆坐标。 Your click method then sets those coordinates, like global oval; oval = esimene_x1, esimene_y1, teine_x1, teine_y1 然后,您的click方法将设置这些坐标,例如整体global oval; oval = esimene_x1, esimene_y1, teine_x1, teine_y1 global oval; oval = esimene_x1, esimene_y1, teine_x1, teine_y1 , but does not trigger pulsate . global oval; oval = esimene_x1, esimene_y1, teine_x1, teine_y1 ,但不会触发pulsate Instead, pulsate is called once when the application starts, and then triggers itself again, like in your code. 而是在应用程序启动时调用一次pulsate ,然后像在代码中一样再次触发自身。 The oval coordinates are not passed to pulsate as parameters, but read from the global variable. 椭圆坐标不作为参数传递为pulsate ,而是从全局变量读取。

I agree with @tobias_k on his assessment about what's going wrong. 对于他对问题的评估,我同意@tobias_k的观点。 You definitely need your coordinates to be global, so every click can set them. 您绝对需要全局坐标,以便每次单击都可以设置它们。 But you don't necessarily need to start the pulsating right away. 但是您不必立即开始脉动。 You could, in the first click, set the coordinates, then check if a global variable, "active", is set to true. 您可以在第一次单击中设置坐标,然后检查全局变量“活动”是否设置为true。 If it is NOT, then start the pulsating. 如果不是,则开始脉动。 Otherwise, just return. 否则,只需返回即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM