向 Tkinter 应用添加新行
Adding new rows to Tkinter app
我正在尝试将新行添加到简单的 table 应用程序(感谢@Bryan Oakley),该应用程序从 table 字段获取输入并存储它。我添加了按钮 "addrow",它被定义为向 SimpleTableInput 添加 +1 行:
self.addrow = tk.Button(self,text="Add row", command=self.addrow)
self.addrow.pack()
def addrow(self):
self.table.append([])
但是这个解决方案失败了。
AttributeError: SimpleTableInput instance has no attribute 'append'
理想情况下,它将新行图形更新为新数据行。
import Tkinter as tk
class SimpleTableInput(tk.Frame):
def __init__(self, parent, rows, columns):
tk.Frame.__init__(self, parent)
self._entry = {}
self.rows = rows
self.columns = columns
# register a command to use for validation
vcmd = (self.register(self._validate), "%P")
# create the table of widgets
for row in range(self.rows):
for column in range(self.columns):
index = (row, column)
e = tk.Entry(self, validate="key", validatecommand=vcmd)
e.grid(row=row, column=column, stick="nsew")
self._entry[index] = e
# adjust column weights so they all expand equally
for column in range(self.columns):
self.grid_columnconfigure(column, weight=1)
# designate a final, empty row to fill up any extra space
self.grid_rowconfigure(rows, weight=1)
def get(self):
'''Return a list of lists, containing the data in the table'''
result = []
for row in range(self.rows):
current_row = []
for column in range(self.columns):
index = (row, column)
current_row.append(self._entry[index].get())
result.append(current_row)
return result
def _validate(self, P):
'''Perform input validation.
Allow only an empty value, or a value that can be converted to a float
'''
if P.strip() == "":
return True
try:
f = float(P)
except ValueError:
self.bell()
return False
return True
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.table = SimpleTableInput(self, 2, 2)
self.submit = tk.Button(self, text="Submit", command=self.on_submit)
self.table.pack(side="top", fill="both", expand=True)
self.submit.pack(side="bottom")
self.addrow = tk.Button(self,text="Add row", command=self.addrow)
self.addrow.pack()
def on_submit(self):
print(self.table.get())
def addrow(self):
self.table.append([])
root = tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()
如果你想使用self.table.append
,你必须为SimpleTableInput
写一个append
方法。这可能是这样的:
def append(self):
row = self.rows
for column in range(self.columns):
index = (row, column)
e = tk.Entry(self, validate="key", validatecommand=self.vcmd)
e.grid(row=row, column=column, stick="nsew")
self._entry[index] = e
self.rows += 1
它会检查有多少行并在其下方再放置一行,其方式与您在 __init__
方法中创建行的方式相同。
要使用它,你必须在 __init__
中将 vcmd
重命名为 self.vcmd
,你可以使用:
def addrow(self):
self.table.append()
你确实可以使用类似的方法来删除最后一行(我现在在我的平板电脑上所以我没有测试过这个但我认为它应该有效):
def delete(self):
row = self.rows - 1
for column in range(self.columns):
index = (row, column)
self._entry[index].grid_remove()
self.rows -= 1
只需在 Example
class 中创建一个调用 self.table.delete()
的新按钮
我正在尝试将新行添加到简单的 table 应用程序(感谢@Bryan Oakley),该应用程序从 table 字段获取输入并存储它。我添加了按钮 "addrow",它被定义为向 SimpleTableInput 添加 +1 行:
self.addrow = tk.Button(self,text="Add row", command=self.addrow)
self.addrow.pack()
def addrow(self):
self.table.append([])
但是这个解决方案失败了。
AttributeError: SimpleTableInput instance has no attribute 'append'
理想情况下,它将新行图形更新为新数据行。
import Tkinter as tk
class SimpleTableInput(tk.Frame):
def __init__(self, parent, rows, columns):
tk.Frame.__init__(self, parent)
self._entry = {}
self.rows = rows
self.columns = columns
# register a command to use for validation
vcmd = (self.register(self._validate), "%P")
# create the table of widgets
for row in range(self.rows):
for column in range(self.columns):
index = (row, column)
e = tk.Entry(self, validate="key", validatecommand=vcmd)
e.grid(row=row, column=column, stick="nsew")
self._entry[index] = e
# adjust column weights so they all expand equally
for column in range(self.columns):
self.grid_columnconfigure(column, weight=1)
# designate a final, empty row to fill up any extra space
self.grid_rowconfigure(rows, weight=1)
def get(self):
'''Return a list of lists, containing the data in the table'''
result = []
for row in range(self.rows):
current_row = []
for column in range(self.columns):
index = (row, column)
current_row.append(self._entry[index].get())
result.append(current_row)
return result
def _validate(self, P):
'''Perform input validation.
Allow only an empty value, or a value that can be converted to a float
'''
if P.strip() == "":
return True
try:
f = float(P)
except ValueError:
self.bell()
return False
return True
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.table = SimpleTableInput(self, 2, 2)
self.submit = tk.Button(self, text="Submit", command=self.on_submit)
self.table.pack(side="top", fill="both", expand=True)
self.submit.pack(side="bottom")
self.addrow = tk.Button(self,text="Add row", command=self.addrow)
self.addrow.pack()
def on_submit(self):
print(self.table.get())
def addrow(self):
self.table.append([])
root = tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()
如果你想使用self.table.append
,你必须为SimpleTableInput
写一个append
方法。这可能是这样的:
def append(self):
row = self.rows
for column in range(self.columns):
index = (row, column)
e = tk.Entry(self, validate="key", validatecommand=self.vcmd)
e.grid(row=row, column=column, stick="nsew")
self._entry[index] = e
self.rows += 1
它会检查有多少行并在其下方再放置一行,其方式与您在 __init__
方法中创建行的方式相同。
要使用它,你必须在 __init__
中将 vcmd
重命名为 self.vcmd
,你可以使用:
def addrow(self):
self.table.append()
你确实可以使用类似的方法来删除最后一行(我现在在我的平板电脑上所以我没有测试过这个但我认为它应该有效):
def delete(self):
row = self.rows - 1
for column in range(self.columns):
index = (row, column)
self._entry[index].grid_remove()
self.rows -= 1
只需在 Example
class 中创建一个调用 self.table.delete()