簡體   English   中英

如何在不等待循環結束的情況下並發運行同一方法?

[英]How to run the same method concurrently without waiting for loop to end?

如下面的代碼所示,我有一個函數,當用戶單擊窗口時,該函數會產生一個圓的動畫。 我的問題是,對於已經生成的另一個圓,我要使其出現並移動,我必須等待上一個圓完成其移動循環。 在降雪功能結束時,一個圓圈完成其“ i in range”循環后,我可以單擊以產生另一個圓圈。 我希望能夠隨時單擊,並且可以使任意多個圓圈同時移動(我知道我已將該函數下的代碼限制為10次)。 看來我需要同時運行多次相同的方法。

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

我的多線程嘗試失敗之一:

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

最新代碼:

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

一個問題是您試圖在啟動線程t1之后立即join它。 join一個線程是要等待它完成,因此您要先啟動然后再等待一個線程十次,而不是啟動十個線程。

但是,在這里線程化是錯誤的方法。 由於性能和流暢性的充分原因,大多數圖形包不允許多個線程繪制到相同的圖形上下文。 這意味着您需要將繪圖線程“由內而外”旋轉,將每個動畫對象的狀態放在“精靈”中,以便每個動畫對象的狀態都在其自己的實例中。 然后,而不是為每個子畫面使用單獨的線程,而是遍歷所有子畫面並在一個循環中更新它們,如下所示。

(請注意,我介紹了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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM