[英]Tkinter, Change OptionMenu based on what is selected in another OptionMenu ANY TIME
[英]Change checkbox list based on OptionMenu answer with tkinter
我對tkinter
有點麻煩
事情是這樣的:我有一個dropdown
(OptionMenu),可以選擇某些內容。
我在OptionMenu
的變量上設置了tracer
,當下拉列表更改時,該OptionMenu
將調用函數。 (函數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)
現在,當選擇該選項時,輸出會給我一個錯誤,因為self.options
尚未初始化。 因此,我找到了一種解決方法,只是將is_initialized
設置為0或1可以解決問題。
但是,復選框並沒有被刪除,只是一直被添加。
TL; DR:更改后不會刪除復選框。 我要實現的是基於通過OptionMenu
選擇的內容具有不同的復選框列表
有沒有更簡單的方法?
好吧,我研究了一段時間,基於這個答案,我能夠使它工作。 這是代碼:
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()
self.window.title("42PyChecker")
self.window.minsize(width=800, height=800)
self.options_dict = {'other': ['author', 'norme', 'Makefile'],
'libft': ['author', 'forbidden-functions', 'makefile', 'norme', 'static', 'extra', 'required', 'bonus', 'benchmark', 'tests', 'libftest', 'maintest', 'moulitest', 'libft-unit-test'],
'fillit': ['author', 'forbidden-functions', 'makefile', 'norme', 'tests', 'fillit-checker'],
'42commandements': []}
# @todo: Make groups like when you tick `tests` it ticks all the tests
# @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)
self.options = ['None', 'NULL']
self.project.trace("w", self.update_options)
dropdown = OptionMenu(self.window, self.project, *self.options_dict.keys())
dropdown.pack()
self.options_choices = Checkbar(self.window, self.options)
self.options_choices.pack(side=BOTTOM)
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)
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 start(self):
print(list(self.options_choices.state()))
def update_options(self, *args):
self.options = self.options_dict[self.project.get()]
self.options_choices.destroy()
self.options_choices = Checkbar(self.window, self.options)
self.options_choices.pack(side=BOTTOM)
def create_window(self):
self.window.mainloop()
它的工作方式非常簡單。 您有一個包含所有項目和選項的字典。 更改下拉列表后,我們將更新列表,刪除當前列表並打包新列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.