2

您好,我想在子程序中创建一个倒数计时器,然后将其显示在画布上。我不完全确定从哪里开始我已经对其进行了一些研究,并且能够使用 time.sleep(x) 函数制作一个,但该方法冻结了整个程序,这不是我想要的. 我还在这里查找了有关计时器的其他问题,并尝试将它们合并到我的程序中,但我还没有取得任何成功。

TLDR;我想创建一个倒计时计时器,它从 60 秒开始倒计时并显示在画布上,然后让它在计时器达到 0 时执行某些操作。

有人能指出我正确的方向吗?

提前致谢。

编辑:根据提供的建议,我试图将它们放入程序中,但运气不佳。

不确定此代码中是否存在重大错误,或者只是一个简单的错误。我运行它时得到的错误位于代码下方。

这是我想要计时器的代码部分:

def main(): #First thing that loads when the program is executed.
   global window
   global tkinter
   global canvas
   global cdtimer
   window = Tk()
   cdtimer = 60
   window.title("JailBreak Bob")

   canvas = Canvas(width = 960, height = 540, bg = "white")
   photo = PhotoImage(file="main.gif")
   canvas.bind("<Button-1>", buttonclick_mainscreen)
   canvas.pack(expand = YES, fill = BOTH)
   canvas.create_image(1, 1, image = photo, anchor = NW)
   window.mainloop()

def buttonclick_mainscreen(event):
   pressed = ""

   if event.x >18 and event.x <365 and event.y > 359 and event.y < 417 : pressed = 1 
   if event.x >18 and event.x <365 and event.y > 421 and event.y < 473 : pressed = 2 
   if event.x >18 and event.x <365 and event.y > 477 and event.y < 517 : pressed = 3 

   if pressed == 1 :
     gamescreen()
   if pressed == 2 :
     helpscreen()
   if pressed == 3 :
     window.destroy()

def gamescreen():
  photo = PhotoImage(file="gamescreen.gif")
  canvas.bind("<Button-1>", buttonclick_gamescreen)
  canvas.pack(expand = YES, fill = BOTH)
  canvas.create_image(1, 1, image = photo, anchor = NW)
  game1 = PhotoImage(file="1.gif")
  canvas.create_image(30, 65, image = game1, anchor = NW)
  e1 = Entry(canvas, width = 11)
  e2 = Entry(canvas, width = 11) 
  canvas.create_window(390, 501, window=e1, anchor = NW)
  canvas.create_window(551, 501, window=e2, anchor = NW)
  canvas.after(1, gamescreen)
  window.mainloop()

def cdtimer():
  canvas.delete(ALL)
  global cdtimer
  cdtimer -= 1
  canvas.create_text(510, 6, text=cdtimer, font="Ubuntu 29 bold", anchor = NW) 
  if cdtimer == 0:
    scorescreen()
  else:
    canvas.after(1000, gamescreen)

main()

错误信息:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__
    return self.func(*args)
  File "/usr/lib/python3.2/tkinter/__init__.py", line 490, in callit
    func(*args)
  File "/home/ppppwn3d/workspace/Python/JailBreakBob/JailBreakBob.py", line 50, in     gamescreen
    e1 = Entry(canvas, width = 11)
  File "/usr/lib/python3.2/tkinter/__init__.py", line 2372, in __init__
    Widget.__init__(self, master, 'entry', cnf, kw)
  File "/usr/lib/python3.2/tkinter/__init__.py", line 1952, in __init__
    cnf = _cnfmerge((cnf, kw))
  File "/usr/lib/python3.2/tkinter/__init__.py", line 71, in _cnfmerge
    if isinstance(cnfs, dict):
RuntimeError: maximum recursion depth exceeded while calling a Python object
4

3 回答 3

3

这是奥克利答案的扩展。它演示了如何在画布中显示时间以及启动整个过程:

from tkinter import *
root = Tk()
canvas = Canvas(root)
canvas.pack()
time = 60
def tick():
    # You have to clear the canvas each time the clock updates 
    # (otherwise it writes on top of the old time).  Since the
    # time is the only thing in the canvas, delete(ALL) works
    # perfectly (if it wasn't however, you can delete the id
    # that goes with the clock).
    canvas.delete(ALL)
    # I have to declare time as a global because I'm not using
    # a class (otherwise, I could do something like self.time -= 1)
    global time
    time -= 1
    # You can place the time wherever in the canvas
    # (I chose 10,10 for the example)
    canvas.create_text(10, 10, text=time)
    if time == 0:
        do_something()
    else:
        canvas.after(1000, tick)
canvas.after(1, tick)
root.mainloop()

脚本从 60 秒开始倒计时(显示剩余时间),当它到达 0 时,它调用 do_something。

于 2013-07-09T01:25:19.240 回答
2

您想使用该after方法。逻辑是这样的:

def update_clock(self):
    self.counter -= 1
    if self.counter == 0 :
        do_something()
    else:
        self.after(1000, self.update_clock)

以上将从计数器中减一。如果计数器为零,它会做一些特别的事情。否则,它会安排自己在一秒钟内再次运行。

于 2013-07-09T00:33:26.193 回答
-1

您可能想尝试线程?

import thread
import time

def myFunct():
    sec = 60
    n = 1
    for i in range(sec/n):
        updateClock()
        time.sleep(n)
    finalFunct()

thread.start_new_thread(myFunct, ())

只需更改sec为初始数量(以秒为单位),以及n您希望它更新的时间间隔(以秒为单位)。

于 2013-07-09T00:34:54.223 回答