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.
Чтобы получить значение, вы можете использовать саму переменную, а не получать значение экземпляра 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: в основе tkinter лежит интерпретатор tcl. Весь язык основан на строках. Хотя он, конечно, поддерживает числа, его мантра гласит: «Все является строкой». Когда вы понимаете язык Tcl, совсем не странно, что по умолчанию он представляет собой строку.
Спасибо за подробное объяснение - мне довольно интересно, что флажки по умолчанию имеют строковые значения, но это имеет смысл с остальной частью вашего объяснения.