0

好吧,这一切都始于臭名昭著的浮点怪异。我正在制作一个简单的国际象棋时钟,由于国际象棋秒数通常变得很重要,我想每 0.01 秒更新一次时钟。这就是为什么我不使用 int 变量。我试过用浮点变量来做,但是对于一个玩家来说,看到 31.2899999999999999 而不仅仅是 31.29 真的很烦人。然后谷歌搜索这个问题把我带到了十进制模块,它看起来很酷,似乎是一个解决方案,但现在我收到以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/tkinter/__init__.py", line 1475, in __call__
return self.func(*args)
File "/Users/maciek/Documents/chessclock/chessclock2.py", line 8, in player1move
x=float(player2.get())
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/tkinter/__init__.py", line 313, in get
return getint(self._tk.globalgetvar(self._name))
ValueError: invalid literal for int() with base 10: '29.21'

我认为值得注意的是,第一步,当两个玩家都有 30 秒时,效果很好。我不包括 player2move 函数的代码,因为它是类比的。除了修复我的小数使用之外,我还对如何使浮动值正确显示的任何其他想法持开放态度(对于人眼,我猜对于计算机来说 31.2899999999999999正确的值)。这是我的代码:

from decimal import *
from tkinter import *
from tkinter import ttk
import time

def player1move(*args):
    getcontext().prec = 6
    x=float(player2.get())
    x=Decimal(x)
    while x>0:
        time.sleep(0.01)
        x=x-Decimal('0.01')
        player1.set(Decimal(x))
        root.update()

root = Tk()
root.title("Python Chessclock 2.0")

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

player1 = IntVar()
player1.set(Decimal(30))
ttk.Label(mainframe, textvariable=player1).grid(column=1, row=1, sticky=(W))
ttk.Label(mainframe, textvariable=player2).grid(column=3, row=1, sticky=(E))

root.bind('p', player1move)
root.mainloop()

谢谢你的时间!

4

1 回答 1

0

如果您更仔细地阅读回溯,您会注意到该异常与模块无关,而是与对indecimal的调用 有关。getinttkinter

decimal此外,如果您想要的只是一个很好的浮点字符串表示,那么您根本不必使用 FWIW - 只需使用 Python 的字符串格式化功能。

于 2013-07-11T11:24:33.433 回答