向 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()

的新按钮