Почему Tkinter getvar() возвращает строковые типы для Booleanvar?

Tkinter предлагает тип BooleanVar для логических значений, хранящихся в его виджетах. Однако использование метода getvar для именованной BooleanVar возвращает строковый тип. Для меня это не имеет смысла, поскольку геттер BooleanVar должен возвращать логическое значение.

Любое понимание того, почему Tkinter сделан таким образом?

Вот краткий пример кода, который показывает, что происходит:

# importing tkinter module 
from tkinter import *
  
# creating Tk() variable 
master = Tk() 
  
# Tkinter variables 
boolvar = BooleanVar(master, name  = "bool") 
Checkbutton(master, 
            text = "check", 
            variable=boolvar,
            command=lambda: printvar()).grid(row=0, sticky=W)
  
# Setting values of variables 
master.setvar(name  = "bool", value = False)
  
# getting values of each variables using getvar() method
def printvar():
    print("Value of BooleanVar()", master.getvar(name  = "bool"))
    print("Type of BooleanVar()", type(master.getvar(name  = "bool")))
mainloop()

Которые создают окно с флажком. Когда флажок установлен, этот вывод печатается на терминале:

Value of BooleanVar() 1
Type of BooleanVar() <class 'str'>
Value of BooleanVar() 0
Type of BooleanVar() <class 'str'>
Value of BooleanVar() 1
Type of BooleanVar() <class 'str'>
Value of BooleanVar() 0
Type of BooleanVar() <class 'str'>

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

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
1 158
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Чтобы получить значение, вы можете использовать саму переменную, а не получать значение экземпляра master.

# importing tkinter module 
from tkinter import *
  
# creating Tk() variable 
master = Tk() 
  
# Tkinter variables 
boolvar = BooleanVar(master, name  = "bool") 
x = Checkbutton(master, 
            text = "check", 
            variable=boolvar,
            command=lambda: printvar()).grid(row=0, sticky=W)
  
# Setting values of variables 
master.setvar(name  = "bool", value = False)
  
# getting values of each variables using get() method
def printvar():
    print("Value of BooleanVar()", boolvar.get())
    print("Type of BooleanVar()", type(boolvar.get()))
mainloop()

Выход:

Value of BooleanVar() True
Type of BooleanVar() <class 'bool'>
Value of BooleanVar() False
Type of BooleanVar() <class 'bool'>

Таким образом, он показывает тип переменной как логический.

Ответ принят как подходящий

Здесь происходит несколько интересных вещей.

Во-первых, встроенный интерпретатор Tcl, лежащий в основе Tkinter, не имеет концепции логических значений. Он использует значение 0 для представления false и любое другое число для представления true. BoolVar обрабатывает это в своем методе get, преобразуя все, что содержится во внутренней переменной Tcl, либо в True, либо в False.

Однако вы не вызываете метод get переменной. Вместо этого вы вызываете getvar, который возвращает необработанное непреобразованное значение, хранящееся в интерпретаторе tcl.

Еще больше усугубляя проблему, вы неправильно настраиваете файл Checkbutton. Поскольку вы не определяете параметры onvalue и offvalue, по умолчанию используются строки «1» и «0».

Если вы правильно установите onvalue и offvalue на True и False и вызовете метод get переменной вместо использования getvar, вы вернете правильное логическое значение.

Или, если вы хотите использовать getvar, вы должны сделать то, что делает BoolVar, и преобразовать значение в логическое значение, используя внутреннюю функцию tkinter getboolean.

Checkbutton(..., onvalue=True, offvalue=False)
...
def printvar():
    ...
    value = master.tk.getboolean(master.getvar(name = "bool"))
    print(f"value: {value} type of value: {type(value)}")

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

shimmer_flight 16.12.2020 03:17

@shimmer_flight: в основе tkinter лежит интерпретатор tcl. Весь язык основан на строках. Хотя он, конечно, поддерживает числа, его мантра гласит: «Все является строкой». Когда вы понимаете язык Tcl, совсем не странно, что по умолчанию он представляет собой строку.

Bryan Oakley 16.12.2020 05:07

Другие вопросы по теме