丑陋:从 python2.7/Tk 中的 Boolean 设置 CheckBox 的值
Ugly: Set value of CheckBox from Boolean in python2.7/Tk
我想在我的程序中有一个布尔标志,它可以在启动时从命令行设置,也可以在程序运行时从 GUI 设置 运行。
我使用 OptParser
从命令行解析选项并将其作为变量提供给表示 GUI 的 class。问题似乎是 CheckBox 需要 Tkinter.BooleanVar
才能正常工作。
这是一个最小的工作示例
#!/usr/bin/python
# -*- coding: UTF-8 -*
from __future__ import print_function
from Tkinter import *
from optparse import OptionParser
class CheckBox:
def __init__(self, parent, verbose):
self.verbose = BooleanVar()
if verbose:
self.verbose.set(True)
else:
self.verbose.set(False)
myParent = parent
menubar = Menu(myParent)
myParent.config(menu=menubar)
menubar.add_checkbutton(label="Toggle Verbose",
variable=self.verbose,
)
menubar.add_command(label="Check Verbose", command=self.checkVerbose)
checkVerbose = Button(text="Check Verbose", command=self.checkVerbose)
checkVerbose.pack()
chk = Checkbutton(text="Toggle Verbose",
variable=self.verbose,
onvalue=TRUE,
offvalue=FALSE,
)
chk.pack()
def checkVerbose(self):
print(self.verbose.get())
if __name__ == '__main__':
usage = "usage: %prog [options]"
parser = OptionParser(usage=usage, version="%prog v0.1.x")
parser.add_option('-v', '--verbose',
action='store_true',
dest='verbose',
help='enables output to command line'
)
parser.set_defaults(verbose=False)
(options, args) = parser.parse_args()
# start the program
root = Tk()
CheckBox(root, options.verbose)
root.mainloop()
exit(0)
代码按原样运行,但我觉得我做错了什么,因为我设置 self.verbose
的部分似乎过于复杂:
def __init__(self, parent, verbose):
self.verbose = BooleanVar()
if verbose:
self.verbose.set(True)
else:
self.verbose.set(False)
…
在我看来这里应该有一些看起来更像的东西:
def __init__(self, parent, verbose):
self.verbose = verbose
…
这里的问题是,两个 CheckBoxes
正确地同步了变量(Tkinter.BooleanVar
类型),但是我的代码中的所有其他访问似乎都访问了另一个 self.verbose
变量这是正常的 Boolean
.
有什么方法可以美化这个丑陋的结构吗?
您不能只将布尔值传递给复选框,因为布尔值是不可变的。您必须以一种或另一种方式从复选框中获取新值,并且由于您还要同步两个独立的小部件,BooleanVar
是正确的方法。
但是,您可以替换方块
self.verbose = BooleanVar()
if verbose:
self.verbose.set(True)
else:
self.verbose.set(False)
只有一行
self.verbose = BooleanVar(value=verbose)
我想在我的程序中有一个布尔标志,它可以在启动时从命令行设置,也可以在程序运行时从 GUI 设置 运行。
我使用 OptParser
从命令行解析选项并将其作为变量提供给表示 GUI 的 class。问题似乎是 CheckBox 需要 Tkinter.BooleanVar
才能正常工作。
这是一个最小的工作示例
#!/usr/bin/python
# -*- coding: UTF-8 -*
from __future__ import print_function
from Tkinter import *
from optparse import OptionParser
class CheckBox:
def __init__(self, parent, verbose):
self.verbose = BooleanVar()
if verbose:
self.verbose.set(True)
else:
self.verbose.set(False)
myParent = parent
menubar = Menu(myParent)
myParent.config(menu=menubar)
menubar.add_checkbutton(label="Toggle Verbose",
variable=self.verbose,
)
menubar.add_command(label="Check Verbose", command=self.checkVerbose)
checkVerbose = Button(text="Check Verbose", command=self.checkVerbose)
checkVerbose.pack()
chk = Checkbutton(text="Toggle Verbose",
variable=self.verbose,
onvalue=TRUE,
offvalue=FALSE,
)
chk.pack()
def checkVerbose(self):
print(self.verbose.get())
if __name__ == '__main__':
usage = "usage: %prog [options]"
parser = OptionParser(usage=usage, version="%prog v0.1.x")
parser.add_option('-v', '--verbose',
action='store_true',
dest='verbose',
help='enables output to command line'
)
parser.set_defaults(verbose=False)
(options, args) = parser.parse_args()
# start the program
root = Tk()
CheckBox(root, options.verbose)
root.mainloop()
exit(0)
代码按原样运行,但我觉得我做错了什么,因为我设置 self.verbose
的部分似乎过于复杂:
def __init__(self, parent, verbose):
self.verbose = BooleanVar()
if verbose:
self.verbose.set(True)
else:
self.verbose.set(False)
…
在我看来这里应该有一些看起来更像的东西:
def __init__(self, parent, verbose):
self.verbose = verbose
…
这里的问题是,两个 CheckBoxes
正确地同步了变量(Tkinter.BooleanVar
类型),但是我的代码中的所有其他访问似乎都访问了另一个 self.verbose
变量这是正常的 Boolean
.
有什么方法可以美化这个丑陋的结构吗?
您不能只将布尔值传递给复选框,因为布尔值是不可变的。您必须以一种或另一种方式从复选框中获取新值,并且由于您还要同步两个独立的小部件,BooleanVar
是正确的方法。
但是,您可以替换方块
self.verbose = BooleanVar()
if verbose:
self.verbose.set(True)
else:
self.verbose.set(False)
只有一行
self.verbose = BooleanVar(value=verbose)