Вы можете создать подкласс ttk.Spinbox
, чтобы изменить его поведение, чтобы отобразить желаемый формат, вместе с единицей в записи spinbox:
import tkinter as tk
import tkinter.ttk as ttk
class FormattedSpinbox(ttk.Spinbox):
"""A ttk.Spinbox that displays a float with 2 decimals,
alongside a '%' character unit
"""
def __init__(self, master, **kwargs):
kwargs['command'] = self.command
super().__init__(master, **kwargs)
def set(self, value):
super().set(value)
self.command()
def get(self):
return float(super().get().strip().split()[0])
def command(self):
value = self.get()
self.delete(0, tk.END)
self.insert(0, f'{float(value): 10.2f} %')
root = tk.Tk()
spinoptions = {'from_': 0, 'to': 100, 'increment': 5}
spinbox = FormattedSpinbox(root, **spinoptions)
spinbox.set(0) # default value
spinbox.pack()
root.minsize(400, 100)
root.mainloop()
виджет выглядит так:
В качестве альтернативы, если вы хотите параметризовать формат, вы можете сделать это следующим образом. Обратите внимание, что str(value).format(format)
не полностью эквивалентен f'{float(value): 10.2f} %')
; первый не добавляет пробела для заполнения требуемой ширины, а число десятичных дробей равно как минимум одному, вплоть до требуемого числа, если значение несет достаточную точность.
import tkinter as tk
import tkinter.ttk as ttk
class FormattedSpinbox(ttk.Spinbox):
"""A ttk.Spinbox that displays a float with 2 decimals,
alongside a '%' character unit
"""
def __init__(self, master, **kwargs):
kwargs['command'] = self.command
super().__init__(master, **kwargs)
def set(self, value):
super().set(value)
self.command()
def get(self):
return float(super().get().strip().split()[0])
def command(self):
value = self.get()
self.delete(0, tk.END)
svalue = str(value).format(format)
self.insert(0, f'{svalue} %')
root = tk.Tk()
spinoptions = {'from_': 0, 'to': 100, 'increment': 5, 'format':'%10.2f'}
spinbox = FormattedSpinbox(root, **spinoptions)
spinbox.set(0) # default value
spinbox.pack()
root.minsize(400, 100)
root.mainloop()
виджет теперь выглядит так: