mys*_*149 5 python locale tkinter
我有以下代码:
import Tkinter as tk
import locale
from Tkinter import *
#locale.setlocale(locale.LC_NUMERIC, 'pl_PL')
master = tk.Tk()
w = tk.Scale(master, from_=0.05, to=0.1, resolution=0.01)
w.pack()
tk.mainloop()
Run Code Online (Sandbox Code Playgroud)
滑块的工作方式应该如此.当我使用区域设置取消注释该行时,它不会滑动.这可能是因为pl_PLlocale使用逗号进行浮动分离.这可能是一个错误.我该如何解决它,以便我可以正确设置区域设置?
这里有一个稍微笨重的解决方法,使用Bryan Oakley对动态重新格式化tkinter规模值python 2.7的一些想法和代码,其中Bryan展示了如何用自定义格式的显示替换常用值显示.不幸的是,我们需要在这里做更多的工作,因为即使我们创建了Scale,showvalue=False它仍然被包含逗号的浮点数阻挡,即使它甚至没有显示它们!
解决方案是强制数字为整数.如果to和from_值是整数倍,那么这很容易做到resolution,如下所示.
import Tkinter as tk
import locale
locale.setlocale(locale.LC_NUMERIC, 'pl_PL.UTF8')
class NewScale(tk.Frame):
def __init__(self, master=None, **options):
tk.Frame.__init__(self, master)
# Disable normal value display...
options['showvalue'] = False
# ... and use custom display instead
options['command'] = self._on_scale
# Set resolution to 1 and adjust to & from value
self.res = options.get('resolution', 1)
from_ = int(options.get('from_', 0) / self.res)
to = int(options.get('to', 100) / self.res)
options.update({'resolution': 1, 'to': to, 'from_': from_})
# This could be improved...
if 'digits' in options:
self.digits = ['digits']
del options['digits']
else:
self.digits = 2
self.scale = tk.Scale(self, **options)
self.scale_label = tk.Label(self)
orient = options.get('orient', tk.VERTICAL)
if orient == tk.VERTICAL:
side, fill = 'right', 'y'
else:
side, fill = 'top', 'x'
self.scale.pack(side=side, fill=fill)
self.scale_label.pack(side=side)
def _on_scale(self, value):
value = locale.atof(value) * self.res
value = locale.format_string('%.*f', (self.digits, value))
self.scale_label.configure(text=value)
if __name__ == '__main__':
master = tk.Tk()
w = NewScale(master, from_=0.05, to=0.1, resolution=0.01)
w.pack(fill='both', expand=True)
master.mainloop()
Run Code Online (Sandbox Code Playgroud)
此代码已在Python 2.6.6和3.6.0上进行了测试.要在Python 3上运行它,请更改import Tkinter as tk为import tkinter as tk.
NewScale小部件支持两者tk.VERTICAL和tk.HORIZONTAL方向,tk.VERTICAL默认情况下(与normalScale小部件相同).它对该digits选项的支持目前相当原始.
以下是一些使NewScale更有用的方法:
def get(self):
return self.scale.get() * self.res
def set(self, value):
self.scale.set(int(0.5 + value / self.res))
Run Code Online (Sandbox Code Playgroud)
要测试这些方法,请将调用代码更改为:
if __name__ == '__main__':
master = tk.Tk()
w = NewScale(master, from_=0.05, to=0.1, resolution=0.01)
w.pack(fill='both', expand=True)
w.set(0.07)
tk.Button(master, text='Print', command=lambda: print(w.get())).pack()
master.mainloop()
Run Code Online (Sandbox Code Playgroud)
将调整后的值to和from_值四舍五入到最接近的整数,而不是截断它们可能是一个好主意.这可以通过将其初始化程序更改为:
from_ = int(0.5 + options.get('from_', 0) / self.res)
to = int(0.5 + options.get('to', 100) / self.res)
Run Code Online (Sandbox Code Playgroud)