【发布时间】:2018-02-21 06:43:31
【问题描述】:
tkinter 有点麻烦
事情是这样的:
我有一个dropdown (OptionMenu),可以让我选择一些东西。
我在来自OptionMenu 的变量上设置了一个tracer,它在下拉列表更改时调用一个函数。 (函数callback_project_name_changed)
当回调被调用时,我检查已选择的项目并显示我想要的相应复选框列表。
这是我目前的代码:
from tkinter import *
import os
import sys
from tkinter import filedialog
class Checkbar(Frame):
def __init__(self, parent=None, picks=[], side=LEFT, anchor=W):
Frame.__init__(self, parent)
self.vars = []
for pick in picks:
var = IntVar()
chk = Checkbutton(self, text=pick, variable=var)
chk.pack(side=side, anchor=anchor, expand=YES)
self.vars.append(var)
def state(self):
return map((lambda var: var.get()), self.vars)
class Application():
def __init__(self):
self.window = Tk()
def close_window(self):
self.window.destroy()
sys.exit()
def close_window_escape(self, event):
self.window.destroy()
sys.exit()
def get_project_path(self):
self.path = filedialog.askdirectory()
print(self.path)
def callback_project_name_changed(self, *args):
# @todo: Make groups like when you tick `tests` it ticks all the tests
self.project_selected = self.project.get()
if self.project_selected == "other":
# @todo: whitelist/blacklist for options
self.options = Checkbar(self.window, ['author', 'norme', 'Makefile'])
self.options.pack(side=LEFT)
if self.project_selected == "42commandements":
self.options = None
if self.project_selected == "libft":
self.options = Checkbar(self.window, ['author', 'forbidden-functions', 'makefile', 'norme', 'static', 'extra', 'required', 'bonus', 'benchmark', 'tests', 'libftest', 'maintest', 'moulitest', 'fillit-checker', 'libft-unit-test'])
self.options.pack(side=LEFT)
if self.project_selected == "fillit":
self.options = Checkbar(self.window, ['author', 'forbidden-functions', 'makefile', 'norme', 'tests', 'fillit-checker'])
self.options.pack(side=LEFT)
def start(self):
if self.options != None:
print(list(self.options.state()))
def create_window(self):
self.window.title("42PyChecker")
self.window.minsize(width=800, height=800)
# @todo: Set a icon for app image
#self.window.iconbitmap(os.path.dirname(os.path.realpath(__file__)) + "/favicon.ico")
# @todo: Find a way to loop through gif frames to have animated logo
logo = PhotoImage(file=os.path.dirname(os.path.realpath(__file__)) + "/logo.gif")
Label(self.window, image=logo).pack()
Button(self.window, text="Select Project Path", width=20, command=self.get_project_path).pack()
self.project = StringVar(self.window)
dropdown = OptionMenu(self.window, self.project, "other", "42commandements", "libft", 'fillit')
dropdown.pack()
Button(self.window, text="Start", command=self.start).pack(side=BOTTOM)
Button(self.window, text="Exit", command=self.close_window).pack(side=BOTTOM)
self.window.bind('<Escape>', self.close_window_escape)
self.project.trace("w", self.callback_project_name_changed)
self.window.mainloop()
app = Application()
app.create_window()
如果您运行它并多次更改下拉菜单(更改为相同或不同的选项),它只会添加更多复选框而不会删除任何复选框。 我想这应该会发生,因为我没有删除任何内容,只是在每次更改下拉菜单时添加 CheckBars。
现在让我们更改一些代码并尝试添加.destroy() 或.pack_forget():
def callback_project_name_changed(self, *args):
# @todo: Make groups like when you tick `tests` it ticks all the tests
self.project_selected = self.project.get()
if self.project_selected == "other":
self.options.destroy()
# @todo: whitelist/blacklist for options
self.options = Checkbar(self.window, ['author', 'norme', 'Makefile'])
self.options.pack(side=LEFT)
if self.project_selected == "42commandements":
self.options = None
if self.project_selected == "libft":
self.options.destroy()
self.options = Checkbar(self.window, ['author', 'forbidden-functions', 'makefile', 'norme', 'static', 'extra', 'required', 'bonus', 'benchmark', 'tests', 'libftest', 'maintest', 'moulitest', 'fillit-checker', 'libft-unit-test'])
self.options.pack(side=LEFT)
if self.project_selected == "fillit":
self.options.destroy()
self.options = Checkbar(self.window, ['author', 'forbidden-functions', 'makefile', 'norme', 'tests', 'fillit-checker'])
self.options.pack(side=LEFT)
Now, when selected, the output gives me an error because self.options hasn't been initialized.所以我找到了一种解决方法,只需将 is_initialized 设置为 0 或 1 就可以了。
然而,复选框并没有被删除,只是不断被添加。
TL;DR:
更改时不会删除复选框。
我想要实现的是根据通过OptionMenu 选择的内容拥有不同的复选框列表
有没有更简单的方法?
【问题讨论】:
标签: python user-interface checkbox tkinter drop-down-menu