Tkinter: управление приращением ttk.Scale как с tk.Scale и tk.DoubleVar - PullRequest
0 голосов
/ 14 января 2019

Я использовал свойство digits для tk.Scale, чтобы убедиться, что числа в Label или Spinbox показывают фиксированное количество десятичных цифр при перемещении ползунка. Как 3.456, 4444.567, 5555555.678, ...

Однако, с ttk.Scale digits и resolution ушли. У меня остается длинное десятичное число, если в качестве переменной масштаба используется tk.DoubleVar. Итак, согласно этому сообщению:

Как заставить ttk.Scale вести себя больше как tk.Scale?

Я должен был бы написать свою собственную схему отображения чисел для метки, что кажется сумасшедшим, когда я уже работаю с классом виджетов. Я еще не видел, как сохранить DoubleVar для этого, потому что мне нужно будет изменить его строковое представление.

Есть ли более простой способ добиться того, чего я хочу?

UPDATE:

Вот код:

import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()
mainframe = tk.Frame(root)

# Model

input = tk.DoubleVar(value=0.)

spin = tk.Spinbox(mainframe, textvariable=input, wrap=True, width=10)
slide = ttk.Scale(mainframe, variable=input, orient='horizontal', length=200)
spin['to'] = 1.0
spin['from'] = 0.0
spin['increment'] = 0.01
slide['to'] = 1.0
slide['from'] = 0.0
# slide['digits'] = 4
# slide['resolution'] = 0.01

# Layout

weights = {'spin': 1, 'slide': 100}

mainframe.grid_rowconfigure(0, weight=1)
mainframe.grid_columnconfigure(0, weight=weights['spin'])
mainframe.grid_columnconfigure(1, weight=weights['slide'])
spin.grid(row=0, column=0, sticky='news')
slide.grid(row=0, column=1, sticky='news')

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
mainframe.grid(row=0, column=0)

root.mainloop()

Когда я перетаскиваю Шкалу, десятичное число внезапно выходит из-под контроля.

enter image description here

1 Ответ

0 голосов
/ 23 января 2019

Вот лучшее решение, чем то, что было в моем первом (теперь удаленном) ответе, который, на мой взгляд, намного чище и эффективнее для реализации функциональности более объектно-ориентированным способом - поэтому не требует взлома, как мой оригинал один сделал.

Вместо этого он выполняет то, что необходимо, определяя ttk.Scale подкласс Я назвал "Limiter", который поддерживает дополнительный аргумент ключевого слова с именем precision.

import tkinter as tk
import tkinter.ttk as ttk


root = tk.Tk()
mainframe = tk.Frame(root)


# Model

class Limiter(ttk.Scale):
    """ ttk.Scale sublass that limits the precision of values. """

    def __init__(self, *args, **kwargs):
        self.precision = kwargs.pop('precision')  # Remove non-std kwarg.
        self.chain = kwargs.pop('command', lambda *a: None)  # Save if present.
        super(Limiter, self).__init__(*args, command=self._value_changed, **kwargs)

    def _value_changed(self, newvalue):
        newvalue = round(float(newvalue), self.precision)
        self.winfo_toplevel().globalsetvar(self.cget('variable'), (newvalue))
        self.chain(newvalue)  # Call user specified function.


# Sample client callback.
def callback(newvalue):
    print('callback({!r})'.format(newvalue))

input_var = tk.DoubleVar(value=0.)
spin = tk.Spinbox(mainframe, textvariable=input_var, wrap=True, width=10)
slide = Limiter(mainframe, variable=input_var, orient='horizontal', length=200,
                command=callback, precision=4)

spin['to'] = 1.0
spin['from'] = 0.0
spin['increment'] = 0.01
slide['to'] = 1.0
slide['from'] = 0.0
# slide['digits'] = 4
# slide['resolution'] = 0.01

# Layout

weights = {'spin': 1, 'slide': 100}

mainframe.grid_rowconfigure(0, weight=1)
mainframe.grid_columnconfigure(0, weight=weights['spin'])
mainframe.grid_columnconfigure(1, weight=weights['slide'])
spin.grid(row=0, column=0, sticky='news')
slide.grid(row=0, column=1, sticky='news')

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
mainframe.grid(row=0, column=0)

root.mainloop()

screenshot of widget

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...