[英]How to run the same method concurrently without waiting for loop to end?
As seen in my code below, I have a function that produces an animation of a circle when the user clicks on the window. 如下面的代码所示,我有一个函数,当用户单击窗口时,该函数会产生一个圆的动画。 My problem is, for me to have another circle appear and move after one is already spawned, I have to wait for the previous one to finish its loop of movement.
我的问题是,对于已经生成的另一个圆,我要使其出现并移动,我必须等待上一个圆完成其移动循环。 After one circle has finished its "i in range" loop at the end of the snowfall function, then I can click and produce another circle.
在降雪功能结束时,一个圆圈完成其“ i in range”循环后,我可以单击以产生另一个圆圈。 I want to be able to click at any time and have as many circles moving simultaneously as I want (I'm aware I've limited it to 10 times in the code under the function).
我希望能够随时单击,并且可以使任意多个圆圈同时移动(我知道我已将该函数下的代码限制为10次)。 It looks like I need away to run the same method multiple times concurrently.
看来我需要同时运行多次相同的方法。
from graphics import*
from random import*
win = GraphWin("Graphics Practice", 500, 500)
colours = ["blue", "red", "orange", "purple", "green", "black", "brown", "yellow", "pink"]
def snowfall(randColour):
point = win.getMouse()
circle = Circle(point, 40)
circle.draw(win)
circle.setFill(colours[randColour])
for i in range(1000):
circle.move(0, 1)
time.sleep(0.002)
randColour = randint(0, 8)
for i in range (10):
repeatColour = randColour
snowfall(randColour)
randColour = randint(0, 8)
while randColour == repeatColour:
randColour = randint(0, 8)
win.getMouse()
win.close()
One of my failed attempts at multithreading this: 我的多线程尝试失败之一:
from graphics import*
from random import*
win = GraphWin("Graphics Practice", 500, 500)
colours = ["blue", "red", "orange", "purple", "green", "black", "brown", "yellow", "pink"]
def snowfall(randColour):
point = win.getMouse()
circle = Circle(point, 40)
circle.draw(win)
circle.setFill(colours[randColour])
for i in range(1000):
circle.move(0, 1)
time.sleep(0.002)
randColour = randint(0, 8)
t1 = threading.Thread(target = snowfall, args = randColour)
for i in range (10):
repeatColour = randColour
t1.start()
t1.join()
randColour = randint(0, 8)
while randColour == repeatColour:
randColour = randint(0, 8)
win.getMouse()
win.close()
Most recent code: 最新代码:
from graphics import*
from random import*
win = GraphWin("Graphics Practice", 500, 500)
colours = ["blue", "red", "orange", "purple", "green", "black", "brown", "yellow", "pink"]
class Snowflake(object):
def __init__(self, randColour):
self.circle = Circle(point, 40)
self.circle.draw(win)
self.circle.setFill(colours[randColour])
def next_frame(self):
self.circle.move(0, 1)
randColour = randint(0, 8)
sprites = []
for i in range (100):
repeatColour = randColour
point = win.getMouse()
sprites.append(Snowflake(randColour))
randColour = randint(0, 8)
while randColour == repeatColour:
randColour = randint(0, 8)
for s in sprites:
while True:
s.next_frame()
time.sleep(0.02)
win.getMouse()
randColour = randint(0, 8)
sprites.append(Snowflake(randColour, point))
win.getMouse()
win.close()
One problem is that you are attempting to join
thread t1
immediately after starting it. 一个问题是您试图在启动线程
t1
之后立即join
它。 To join
a thread is to wait for it to finish, so instead of starting ten threads, you are starting and then waiting for a thread ten times. join
一个线程是要等待它完成,因此您要先启动然后再等待一个线程十次,而不是启动十个线程。
However, threading is the wrong approach here. 但是,在这里线程化是错误的方法。 Most graphics packages do not allow multiple threads to draw to the same graphics context, for good reasons of performance and fluidity.
由于性能和流畅性的充分原因,大多数图形包不允许多个线程绘制到相同的图形上下文。 This means that you need to turn your drawing threads "inside out", putting the state of each animated object in a "sprite", so that the state of each animated object is in its own instance.
这意味着您需要将绘图线程“由内而外”旋转,将每个动画对象的状态放在“精灵”中,以便每个动画对象的状态都在其自己的实例中。 Then, instead of using separate threads for each sprite, you run through all your sprites and update them in a single loop, as shown below.
然后,而不是为每个子画面使用单独的线程,而是遍历所有子画面并在一个循环中更新它们,如下所示。
(Note that I introduced win.checkMouse()
, which does a non-blocking check for a mouse event, and therefore allows you to add a sprite per click, which is what I believe you intended.) (请注意,我介绍了
win.checkMouse()
,它对鼠标事件进行非阻塞检查,因此允许您为每次单击添加一个精灵,这就是我所希望的。)
from graphics import *
from random import *
win = GraphWin("Graphics Practice", 500, 500)
colours = ["blue", "red", "orange", "purple", "green", "black", "brown", "yellow", "pink"]
class Snowflake(object):
def __init__(self, randColour, point):
self.circle = Circle(point, 40)
self.circle.draw(win)
self.circle.setFill(colours[randColour])
def next_frame(self):
self.circle.move(0, 1)
randColour = randint(0, 8)
sprites = []
for i in range(100):
point = win.checkMouse()
if point:
randColour = randint(0, 8)
sprites.append(Snowflake(randColour, point))
for s in sprites:
s.next_frame()
time.sleep(0.1)
win.close()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.