试图理解为什么我的秒表代码什么都不做(Python)
我试图编写python代码,使用tkinter在输入框中显示秒表 我的想法是使用递归函数,使用time.sleep(1)每秒向框中添加1 我被难住了——当我按下任何一个按钮时都不会发生任何事情,而且我没有得到错误代码,所以我不知道为什么它不工作 我唯一一次从盒子里拿东西是在按下停止键之后,它总是“00:00:00”试图理解为什么我的秒表代码什么都不做(Python),python,tkinter,stopwatch,Python,Tkinter,Stopwatch,我试图编写python代码,使用tkinter在输入框中显示秒表 我的想法是使用递归函数,使用time.sleep(1)每秒向框中添加1 我被难住了——当我按下任何一个按钮时都不会发生任何事情,而且我没有得到错误代码,所以我不知道为什么它不工作 我唯一一次从盒子里拿东西是在按下停止键之后,它总是“00:00:00” 从tkinter导入* 导入时间 root=Tk() 根标题(“秒表”) #显示秒表的框 框=条目(根,宽度=20,边框宽度=5) box.grid(行=0,列=0) #在框中显示秒
从tkinter导入*
导入时间
root=Tk()
根标题(“秒表”)
#显示秒表的框
框=条目(根,宽度=20,边框宽度=5)
box.grid(行=0,列=0)
#在框中显示秒表
def show_timer():
全局小时、分钟、秒、计时器
计时器=str(小时)。zfill(2)+“:”+str(分钟)。zfill(2)+“:”+str(秒)。zfill(2)
框。删除(0,结束)
框。插入(0,计时器)
#check=1允许秒表运行
def设置检查(i):
全局检查
检查=i
退票
#秒表的实际功能
def秒表():
全局检查,小时、分钟、秒
如果检查==1:
时间。睡眠(1)
如果整数(秒)<59:
秒+=1
返回秒
elif分钟<59:
分钟+=1
秒=0
返回分钟,秒
其他:
小时+=1
分钟=0
秒=0
返回小时、分钟、秒
显示计时器()
秒表
其他:
显示计时器()
def start():
全球小时、分钟、秒
小时,分钟,秒=0,0,0
返回小时、分钟、秒
显示计时器()
设置检查(1)
秒表
def stop():
设置检查(0)
秒表
启动按钮=按钮(root,text=“start”,command=start)
停止按钮=按钮(root,text=“stop”,command=stop)
开始按钮网格(行=1,列=0)
停止按钮网格(行=2,列=0)
root.mainloop()
您的代码有几个问题
- 从回调函数调用
会中断time.sleep()
事件循环,使GUI无响应tkinter
- 不建议使用tkinter导入的
。为避免名称空间污染,请使用例如*
将tkinter导入为tk
- 您可以从
开始
返回
(=退出函数),而不做任何操作
- 您的函数不需要
语句;您似乎没有使用返回的值return
中的内部stopwatch
-语句的所有三个分支调用if
,因此不能递归调用return
。那可能不是你想要的stopwatch
- 这是一件好事,因为来自回调的递归调用也会中断事件循环
- 当您想要修改变量时,只需要使用
。例如,global
不需要show\u timer
。(顺便说一句,您可以修改容器类型的内容,如global
和list
,而无需使用dict
)global
- 全局上下文中不存在您指示为
的名称global
root.after()
使其在特定时间后执行回调,但不能保证这个时间是准确的
因此,我建议:
- 节省启动秒表的时间
- 使用每秒运行的
后
回调
- 在该回调中,获取当前时间并从中减去开始时间。显示差异
- 请注意,在回调之后的
结束时,您必须重新注册它以保持其运行。(除非按下停止按钮
types.SimpleNamespace
中,以明确这是程序状态。
以下是此更改的工作版本:
import time
import types
import tkinter as tk
def start():
state.starttime = time.time()
state.run = True
display()
root.after(1000, update)
def stop():
state.run = False
state.starttime = None
box.delete(0, tk.END)
def update():
if state.run:
display()
root.after(1000, update)
def display():
difference = int(time.time() - state.starttime)
minutes, seconds = divmod(difference, 60)
hours, minutes = divmod(minutes, 60)
display = "{:02d}:{:02d}:{:02d}".format(hours, minutes, seconds)
box.delete(0, tk.END)
box.insert(0, display)
if __name__ == '__main__':
# Create program state
state = types.SimpleNamespace()
state.starttime = None
state.run = False
# Create widgets.
root = tk.Tk()
root.title("Stopwatch")
root.attributes('-type', 'dialog')
# box to display stopwatch
box = tk.Entry(root, width=20, borderwidth=5)
box.grid(row=0, column=0)
start_button = tk.Button(root, text="Start", command=start)
stop_button = tk.Button(root, text="Stop", command=stop)
start_button.grid(row=1, column=0)
stop_button.grid(row=2, column=0)
# Run the GUI
root.mainloop()
编辑
如果您是Python新手,那么最好从可以从命令行调用的脚本开始(
cmd.exe
在ms windows上)在我的网站上,我有两个相当的程序,一个是简单的命令行脚本,另一个是tkinter
GUI。你可以看到后者比前者更复杂。return
留下了当前的乐趣Action调用,因此您的def start(…
什么都不做。仔细阅读《魔兽世界》,就会发现我几乎没有触及Python的表面。对于上下文,这是我尝试编写的第二件超过几行的东西(第一件是一个GUI计算器,它主要按照预期工作,可能可以简化).我非常感谢你花了这么多时间对我的问题做出如此详细的答复-在我完全理解之前,我还有很多事情要研究。
import time
import types
import tkinter as tk
def start():
state.starttime = time.time()
state.run = True
display()
root.after(1000, update)
def stop():
state.run = False
state.starttime = None
box.delete(0, tk.END)
def update():
if state.run:
display()
root.after(1000, update)
def display():
difference = int(time.time() - state.starttime)
minutes, seconds = divmod(difference, 60)
hours, minutes = divmod(minutes, 60)
display = "{:02d}:{:02d}:{:02d}".format(hours, minutes, seconds)
box.delete(0, tk.END)
box.insert(0, display)
if __name__ == '__main__':
# Create program state
state = types.SimpleNamespace()
state.starttime = None
state.run = False
# Create widgets.
root = tk.Tk()
root.title("Stopwatch")
root.attributes('-type', 'dialog')
# box to display stopwatch
box = tk.Entry(root, width=20, borderwidth=5)
box.grid(row=0, column=0)
start_button = tk.Button(root, text="Start", command=start)
stop_button = tk.Button(root, text="Stop", command=stop)
start_button.grid(row=1, column=0)
stop_button.grid(row=2, column=0)
# Run the GUI
root.mainloop()