向Tkinter应用添加新行

时间:2015-01-05 22:21:35

标签: python python-2.7 tkinter

我正在尝试向简单的表应用程序添加新行(感谢@Bryan Oakley),它从表字段中获取输入并存储它。我添加了按钮“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()

1 个答案:

答案 0 :(得分:1)

如果您想使用self.table.append,则必须为append编写SimpleTableInput方法。这可能是这样的:

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__方法中创建行的方式相同。
要使用此功能,您必须在vcmd中将self.vcmd重命名为__init__,并且您可以使用以下所有内容:

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课程中创建一个名为self.table.delete()

的新按钮即可