简体   繁体   English

如何在不等待循环结束的情况下并发运行同一方法?

[英]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.

相关问题 如何使事件循环同时运行任务? - How to make event loop run task concurrently? 如何与asyncio同时运行无限循环? - How to concurrently run a infinite loop with asyncio? 如何保持for循环等待进程结束? - How to hold a for loop waiting for a process to end? 在 pyspark 中同时运行 for 循环,而不是按顺序运行 - Run a for loop concurrently and not sequentially in pyspark 如何与无限循环同时运行bottle? - How can I run bottle concurrently with an infinite loop? 如何指示 CuPy 在 GPU 中同时运行多个相同的作业? - How to instruct CuPy to run multiple number of the same job concurrently in a GPU? Python如何同时同时运行n次函数 - Python How to run a function n times concurrently at Same time 如何使用4对不同的参数同时运行同一函数? - How do I concurrently run the same function with 4 different pairs of arguments? (Python)如何在不使用 asyncio gather 的情况下并发(独立)运行任务? - (Python) How to run tasks concurrently (and independently) without using asyncio gather? Python-我正在尝试与asyncio start_server同时运行主逻辑(游戏服务器)循环,以等待TCP流量 - Python - I am trying to run a main logic (game server) loop concurrently with asyncio start_server waiting for TCP traffic
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM