【问题标题】:tkinter: How to make timer run in a backgroundtkinter:如何让计时器在后台运行
【发布时间】:2022-01-09 10:11:01
【问题描述】:

我有一个游戏——把硬币抓到碗里。然而,其中一个标准是通过输入以秒为单位的时间来限制它——游戏将持续多长时间。用户输入的时间来自tkinter.Entry,我不知道如何同时执行一个定时器和一个函数。代码进度:

import tkinter, random, time
from threading import Thread

window = tkinter.Tk()
window.title("Dukaty")

canvas = tkinter.Canvas(window, height = 400, width = 800)
canvas.pack()


timeLabel = tkinter.Label(text = "Time:", font = "Helvetica 15")
timeLabel.pack()
timeEntry = tkinter.Entry(bd = 1)
timeEntry.pack()
mistakesLabel = tkinter.Label(text = "Allowed mistakes:", font = "Helvetica 15")
mistakesLabel.pack()
mistakesEntry = tkinter.Entry(bd = 1)
mistakesEntry.pack()

timeEntry.insert(0, "0")
mistakesEntry.insert(0, "0")

speed = 250
score = 0
mistakes = 0
allowedTime = ""


def countdown(t):
    while t:
        mins, secs = divmod(t, 60)
        timer = '{:02d}:{:02d}'.format(mins, secs)
        allowedTime = timer
        print(allowedTime)
        time.sleep(1)
        t -= 1

    print("Time's up!")


def timedGame():
    time = int(timeEntry.get())
    canvas.after(time * 1000)
    end()

def movingCoin():
    global speed, score, mistakes, allowedTime
    time = int(timeEntry.get())
    coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")

    canvas.create_text(700, 50, text = str(score), font = "Helvetica 20", fill = "green", tags = "score")
    canvas.create_text(700, 80, text = str(mistakes), font = "Helvetica 20", fill = "red", tags = "mistakes")
    # ENDLESS

    if timeEntry.get() == "0" and mistakesEntry.get() == "0":
        while True:
            if canvas.coords(coin)[1] < 360:
                canvas.move(coin, 0, 5)
                canvas.after(speed)
                canvas.update()
            elif canvas.coords(coin)[1] >= 360 and (canvas.coords(coin)[0] > (canvas.coords(bowl)[0] - 40) and canvas.coords(coin)[0] < (canvas.coords(bowl)[0] + 40)):
                canvas.delete("score")
                score += 1
                canvas.create_text(700, 50, text=str(score), font="Helvetica 20", fill="green", tags="score")
                canvas.delete(coin)
                coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
                speed -= 10
            else:
                canvas.delete("mistakes")
                mistakes += 1
                canvas.create_text(700, 80, text=str(mistakes), font="Helvetica 20", fill="red", tags="mistakes")
                canvas.delete(coin)
                coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
                speed -= 10

    # TIME - not done yet

    elif timeEntry.get() != "0" and mistakesEntry.get() == "0":
        while str(allowedTime) != "00:00":
            if canvas.coords(coin)[1] < 360:
                canvas.move(coin, 0, 5)
                canvas.after(speed)
                canvas.update()
            elif canvas.coords(coin)[1] >= 360 and (canvas.coords(coin)[0] > (canvas.coords(bowl)[0] - 40) and canvas.coords(coin)[0] < (canvas.coords(bowl)[0] + 40)):
                score += 1
                print(score)
                canvas.delete(coin)
                coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
                speed -= 10
            else:
                mistakes += 1
                print(mistakes)
                canvas.delete(coin)
                coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
                speed -= 10



    # MISTAKES

    elif timeEntry.get() == "0" and mistakesEntry != "0":

        allowedMistakes = int(mistakesEntry.get())
        print("Allowed mistakes: " + str(allowedMistakes))

        while True:
            if canvas.coords(coin)[1] < 360:
                canvas.move(coin, 0, 5)
                canvas.after(speed)
                canvas.update()
            elif canvas.coords(coin)[1] >= 360 and (canvas.coords(coin)[0] > (canvas.coords(bowl)[0] - 40) and canvas.coords(coin)[0] < (canvas.coords(bowl)[0] + 40)):
                canvas.delete("score")
                score += 1
                canvas.create_text(700, 50, text=str(score), font="Helvetica 20", fill="green", tags="score")
                canvas.delete(coin)
                coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
                speed -= 10
            else:
                if allowedMistakes > mistakes:
                    canvas.delete("mistakes")
                    mistakes += 1
                    canvas.create_text(700, 80, text=str(mistakes), font="Helvetica 20", fill="red", tags="mistakes")
                    canvas.delete(coin)
                    coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
                    speed -= 10

                elif allowedMistakes == mistakes:
                    print("ending the program")
                    break


def end():
    window.destroy()

def tap():
    Thread(target=countdown(int(timeEntry.get()))).start()
    Thread(target=movingCoin).start()

endButton = tkinter.Button(text = "End", command = end)
endButton.pack(side = "right")
startButton = tkinter.Button(text = "Start", command = tap)
startButton.pack(side = "left")


window.mainloop()

它的作用是启动计时器,当它结束时,它执行movingCoin函数。

我想要实现的是让计时器启动(当 Entry 中的值大于 0 时),同时执行movingCoin - 然后下降到时间部分,当时间到时,while 中断。

【问题讨论】:

    标签: python multithreading tkinter time timer


    【解决方案1】:

    你可以用这个方法

    window.after(1000,)

    表示 1 秒后的函数调用。如果你在这个方法中使用递归,那么你可以创建计时器。

    【讨论】:

    • 是的,但是命令 .after() 会停止整个程序,并在一段时间后执行该函数。我需要的是启动计时器,它不会中断同时调用的第二个函数——movingCoin——实际的游戏机制。
    • 但是,就我而言,它有效。我认为它可以帮助你。 geeksforgeeks.org/create-stopwatch-using-python/amp
    【解决方案2】:

    我希望它对你有用,加油。

    import time
    # time.time() return in second
    game_duration = float(input('duration: ')) + time.time() 
    
    game_is_running = True
    
    while game_is_running:
        if game_duration == time.time(): # this means: if now equal to game_duration
            game_is_running = False
    
    # note: it is quite critical where you place time.time()
    

    再举一个例子:

    # I used the following technique to build an explosion animation for 30 seconds, then it will do something else.
    class Explosion(pygame.sprite.Sprite):
        def __init__(self, center):
            pygame.sprite.Sprite.__init__(self)
            self.image = explosion_animation[0]
            self.rect = self.image.get_rect()
            self.rect.center = center
            self.frame = 0
            self.last_update = pygame.time.get_ticks()
            self.duration = 30
    
    
        def update(self):
            now = pygame.time.get_ticks()
            if now - self.last_update > self.duration:
                self.last_update = now
                self.frame += 1
                if self.frame == len(explosion_animation):
                    self.kill()
                else:
                    center = self.rect.center
                    self.image = explosion_animation[self.frame]
                    self.rect = self.image.get_rect()
                    self.rect.center = center
    
    

    【讨论】:

    • 我会将相等条件替换为:game_duration
    猜你喜欢
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多