#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class CheckboxRow(tk.Frame):
def __init__(self, master, name, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.name = name
checkbox = tk.Checkbutton(self, text=name)
checkbox.pack(side=tk.LEFT)
deleteItem = tk.Button(self, text="x", bg="red", fg="white",
activebackground="white", activeforeground="red",
command=self.destroyCheckbox)
deleteItem.pack(side=tk.RIGHT)
def destroyCheckbox(self):
self.master.master.checkboxList.remove(self.name)
self.destroy()
class CheckboxArea(tk.Frame):
def add(self, name):
row = CheckboxRow(self, name)
row.pack(fill=tk.X)
class InputStuff(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
prompt = tk.Label(self, text="What do you want your checkbox to be for?")
prompt.pack()
bottomInput = tk.Frame(self)
self.entry = tk.Entry(bottomInput, bd=3)
self.entry.pack(side=tk.LEFT)
buttonConfirm = tk.Button(bottomInput, text="Confirm", command=self.drawCheckbox)
buttonConfirm.pack(side=tk.LEFT)
bottomInput.pack()
buttonDone = tk.Button(self, text = "Close Input", command=master.hide_input_stuff)
buttonDone.pack()
def drawCheckbox(self, event=None):
self.master.add(self.entry.get())
self.entry.delete(0, tk.END)
class MainWindow(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
master.protocol("WM_DELETE_WINDOW", self.on_closing)
self.checkboxList = []
self.checkbox_area = CheckboxArea(self)
self.checkbox_area.pack(fill=tk.X)
self.input_stuff = InputStuff(self)
self.add_button = tk.Button(self, text="Add Item", command=self.show_input_stuff)
self.hide_input_stuff() # start with "add" button active
self.load()
def add(self, name):
self.checkbox_area.add(name)
self.checkboxList.append(name)
def show_input_stuff(self):
self.add_button.pack_forget()
self.input_stuff.pack()
self.input_stuff.entry.focus()
self.master.bind('<Return>', self.input_stuff.drawCheckbox)
def hide_input_stuff(self):
self.input_stuff.pack_forget()
self.add_button.pack()
self.master.unbind('<Return>')
def load(self):
try:
with open('toDoListSaveFile.json') as infile:
checkboxList = json.load(infile)
for savedCheckbox in checkboxList:
self.add(savedCheckbox)
except (IOError, ValueError):
#an error occured while loading ... so no saved settings loaded
pass
def on_closing(self):
with open("toDoListSaveFile.json", 'w') as outfile:
json.dump(self.checkboxList, outfile)
self.quit()
def main():
master = tk.Tk()
master.title("To-Do List (with saving!)")
master.geometry("300x300")
win = MainWindow(master)
win.pack(fill=tk.X)
master.mainloop()
if __name__ == '__main__':
main()
**kwargs
在CheckboxRow类中。为什么需要它?据我所知,当您接受可变数量的参数时,您只需要**kwargs
,但__init__()
只会采用三个参数self,
master and
name`。
与tk.Frame.__init__
相同。为什么需要kwargs?我很确定我应该如何使用 kwargs ,有人可以解释一下吗?
答案 0 :(得分:3)
严格来说,不需要它。但是,通过包含它,您可以将标准框架选项传递给子类。
例如,使用**kwargs
,您可以设置框架的边框宽度,如下所示:
x = CheckboxRow(root, "A row", borderwidth=1, relief="sunken")
原因是borderwidth=1, relief="sunken"
是kwargs
中包含的内容,并且它被传递给将继承这些参数的继承的Frame
类。
如果您还要从**kwargs
调用中删除Frame.__init__
,则可以从参数列表中省略Frame
,但缺点是您无法再传递有效的class CheckboxRow(tk.Frame):
def __init__(self, master, name):
tk.Frame.__init__(self, master)
选项:< / p>
class CheckboxRow(tk.Frame):
def __init__(self, master, name, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
答案 1 :(得分:0)
CheckboxRow
这样,用于初始化tk.Frame
实例的任何关键字都将:
tk.Frame
查看您的代码,如果不查看documentation,就无法知道kwargs
将使用哪些关键字参数。
这是一个没有def f(x):
print x
f(2, width=800, height=600)
#=> TypeError: f() got an unexpected keyword argument 'width'
的简单示例:
kwargs
使用def f(x, **kwargs):
print x
g(**kwargs)
def g(**kwargs):
print kwargs
f(2, width=800, height=600)
# 2
# {'width': 800, 'height': 600}
:
{{1}}
答案 2 :(得分:0)
kwargs允许您传递可选的关键字参数。所以如果你只想改变一些论点而不是其他论点:
例如:
f = Frame(height=2, bd=1, relief=SUNKEN)
f = Frame(relief=SUNKEN) #This also works
f = Frame() # Also works