python - Tkinter widget.cget('变量')
问题描述
如何使用cget('variable')
方法获取对小部件控制变量的引用?我正在寻找一种使用返回的对象cget('variable')
来查找关联tkinter.IntVar
对象的解决方案。
import tkinter as tk
root = tk.Tk()
var = tk.IntVar()
print('tkinter variable is of type', type(var)) # <class 'tkinter.IntVar'>
button = tk.Checkbutton(root, text='Checkbutton 1', variable=var)
button.pack(side=tk.TOP, padx=10, pady=10)
# Now I attempt to retrieve "var", using cget('variable').
var2 = button.cget('variable')
print('cget("variable") returns an object of type', type(var2)) # <class '_tkinter.Tcl_Obj'>
print(var is var2) # False
root.mainloop()
解决方案
为自己省去很多麻烦,只需将其存储IntVar
在按钮上
var = tk.IntVar()
button = tk.Checkbutton(root, text='Checkbutton 1', variable=var)
button.var = var # keep a reference on the button itself
或者像这样
button = tk.Checkbutton(root, text='Checkbutton 1')
button.var = tk.IntVar()
button.configure(variable=button.var)
除非您的真正目标是在不需要参考的情况下获得价值,否则您可以这样做:
value = button.getvar(str(button.cget("variable")))
print(value)
作为替代方案,您可以使用我很久以前制作的这个小类。它主要只是自动化一切,但它也允许您将一些任意数据与Checkbutton
.
class Checkbox(tk.Checkbutton):
@property
def var(self):
return self.__var
@property
def value(self) -> int:
return self.__var.get()
@value.setter
def value(self, value):
self.__var.set(int(bool(value)))
def __init__(self, master, data=None, on_change=None, on_read=None, **kwargs):
self.__var = tk.IntVar() if not 'variable' in kwargs else kwargs['variable']
tk.Checkbutton.__init__(self, master, **{**kwargs, 'variable':self.__var})
self.data = self['text'] if not data else data
if on_change:
self.__var.trace('w', lambda *a:on_change(self))
if on_read:
self.__var.trace('r', lambda *a:on_read(self))
以下是一些示例用法
#example 1
def on_change(checkbox):
print(checkbox.data, checkbox.value)
Checkbox(root, on_change=on_change, text='tester1').grid()
Checkbox(root, on_change=on_change, text='tester2').grid()
#-----------------------------------------------------------
#example 2
cbs = [
Checkbox(root, text='test1'),
Checkbox(root, text='test2'),
Checkbox(root, text='test3'),
Checkbox(root, text='test4'),
]
for i, cb in enumerate(cbs):
cb.grid(row=0, column=i)
def get_values():
print(*[f'{cb.data}:{cb.value}' for cb in cbs], sep='\n')
tk.Button(root, text="check", command=get_values).grid()
#-----------------------------------------------------------
#example 3
def on_read(checkbox):
if checkbox.data is True:
if checkbox.value:
pass
else:
pass
cb = Checkbox(root, on_read=on_read, data=(someCondition is True), text='tester1')
cb.grid()
#...
something = cb.value #triggers on_read
推荐阅读
- python - Tensorflow 2.3.0 未检测到 GPU
- java - 如何解决 java.lang.LinkageError:加载程序约束冲突
- jupyter-notebook - 无法在 jupyter 笔记本中导入 numpy
- node.js - 如何将文件从nodeJS上传到nodeJS
- css - AppBar 元素内的抽屉渲染
- php - 我正在尝试在我的 Wordpress 主题中添加一个可扩展的“阅读更多”标签(对于其他页面)
- arrays - 我应该通过引用将 int 数组传递给函数吗?
- swift - Swift 5:在 UICollectionView 类中未调用 scrollViewDidScroll
- python - 如何使用位置参数抓取 Google 购物
- c++ - 错误:ISO C++ 禁止在 Lambda 函数中比较指针和整数 [-fpermissive]