tkinter: управление переменными внутри tk.Label с помощью textvariable - PullRequest
1 голос
/ 15 марта 2012

Я только начал изучать tkinter и хотел бы знать, можно ли манипулировать переменными в ttk.Label на лету с помощью textvariable= или text=. Чтобы продемонстрировать, вот моя гениальная калькуляторная программа, которая умножает два числа и отображает продукт.

from tkinter import *
from tkinter import ttk

root = Tk()
root.title("Multiplier")

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

## Calculation

def multiply(*args):
    try:
       product.set(round(float(num1.get())*float(num2.get()),2))
    except ValueError:
        pass

## variables

num1 = StringVar()
num2 = StringVar()
product = DoubleVar()

## first number

ttk.Label(mainframe, text="First Number:").grid(column = 1, row = 1)
num1_entry = ttk.Entry(mainframe, width=4, textvariable=num1)
num1_entry.grid(column = 2, row = 1)
num1_entry.bind('<KeyPress>', multiply)
num1_entry.bind('<KeyRelease>', multiply)

## second number

ttk.Label(mainframe, text="Second Number:").grid(column = 1, row = 2)
num2_entry = ttk.Entry(mainframe, width=4, textvariable=num2)
num2_entry.grid(column = 2, row = 2)
num2_entry.bind('<KeyPress>',multiply)
num2_entry.bind('<KeyRelease>',multiply)

## display results

ttk.Label(mainframe, text = "Product:").grid(column = 1, row = 3)
ttk.Label(mainframe, textvariable=product).grid(column = 2, row = 3)

root.mainloop()

Я могу обновить результат всякий раз, когда product изменяется с помощью textvariable=product. Я могу обновлять product всякий раз, когда num1 или num2 изменяются путем привязки каждого к <KeyPress> и <KeyRelease>. Пока все хорошо.

Я хотел бы знать, возможно ли иметь еще один ttk.Label, который отображает мою переменную, но каким-то образом манипулирует. Допустим, я хотел сделать что-то сумасшедшее, например взять свой продукт и умножить его на 2.

Я знаю, что мог бы просто создать новую переменную:

newvariable = DoubleVar()

затем обновите мою multiply функцию таким образом:

def multiply(*args):
    try:
       product.set(round(float(num1.get())*float(num2.get()),2))
       newvariable.set(round(product.get()*2),2))
    except ValueError:
        pass

и добавьте мой новый ярлык:

ttk.Label(mainframe, textvariable=newvariable).grid(column=1, row = 5)

Это хорошо решает проблему. У меня есть новый ярлык, который показывает мне мой оригинальный продукт * 2, а также обновляется на лету, когда меняются мои записи. Это именно то, что я хочу.

В моем реальном проекте, однако, мне нужно выполнить это много раз с другими аргументами. Кажется утомительным добавлять тонну новых переменных, если мне это не нужно.

То, что я хотел бы сделать, это что-то вроде:

ttk.Label(mainframe, textvariable=product*2).grid(column=1, row = 5)

Это дает мне "TypeError: неподдерживаемые типы операндов для *: 'DoubleVar' и 'int'. Я понимаю, что textvariable хочет только 1 переменную и не хочет манипулировать ею.

Я тоже пробовал:

ttk.Label(mainframe, text=(product.get()*2)).grid(column=1, row = 5)

Это не ошибка, но также не обновляется автоматически. (Это и есть причина, по которой нам нужно textvariable, не так ли?)

Возможно ли вообще сделать это без создания новой переменной для каждого отдельного экземпляра, где я хочу манипулировать своими исходными переменными?

Спасибо за любую помощь!

1 Ответ

1 голос
/ 16 марта 2012

Вы не можете связать функцию или выражение с меткой.Однако то, что вы можете сделать, - это отследить ваши другие варианты.Трассировка будет вызывать функцию всякий раз, когда переменная изменяется.В этой функции вы можете выполнять любые вычисления и устанавливать значение переменной метки.

Для получения дополнительной информации о трассировке см. http://epydoc.sourceforge.net/stdlib/Tkinter.Variable-class.html#trace, среди других мест.

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