【问题标题】:How Can I only save filled in entry widgets without saving the empty entry widget in atext file using Tkinter app?如何使用 Tkinter 应用程序只保存填写的条目小部件而不将空的条目小部件保存在文本文件中?
【发布时间】:2020-07-31 11:02:42
【问题描述】:

我正在为桁架分析创建一个简单的应用程序,我必须收集一些数据并将其保存在文本文件中。根据我的代码,我最多只能解决 6 个节点(6 个输入框)。但是当我不填写时所有的盒子它还将空盒子保存为空字符串。例如,如果我为 3 个节点(即前 3 个盒子)放置坐标。我得到以下内容;

nodes = {'1': ['0', '0'], '2': ['1', '1'], '3': ['2', '2'], '': ['', '']}

如何将我的保存按钮编程为只保存用户填写的数据,仅此而已?

我的代码如下;

from tkinter import*
root = Tk()
root.geometry("480x480")
root.title ("TRUSS 2D")
# creating coordinates input

myLabel = Label(root,text = "Coordinates")
myLabel.grid (row = 0,column = 0)
myLabel9 = Label(root,text = "Node")
myLabel9.grid (row = 1,column = 0, columnspan = 1 )
e_1 = Entry(root,width=5,borderwidth=5)
e_1.grid(row = 2,column = 0)
e_2 = Entry(root,width=5,borderwidth=5)
e_2.grid(row = 3,column = 0)
e_3 = Entry(root,width=5,borderwidth=5)
e_3.grid(row = 4,column = 0)
e_4 = Entry(root,width=5,borderwidth=5)
e_4.grid(row = 5,column = 0)
e_5 = Entry(root,width=5,borderwidth=5)
e_5.grid(row = 6,column = 0)
e_6 = Entry(root,width=5,borderwidth=5)
e_6.grid(row = 7,column = 0)
myLabel_x0 = Label(root,text = "x0")
myLabel_x0.grid (row = 2,column = 1)
e_x0 = Entry(root,width=5,borderwidth=5)
e_x0.grid(row = 2,column = 2)
myLabel_y0 = Label(root,text = "y0")
myLabel_y0.grid (row = 2,column = 3)
e_y0 = Entry(root,width=5,borderwidth=5)
e_y0.grid(row = 2,column = 4)
myLabel_x1 = Label(root,text = "x1")
myLabel_x1.grid (row = 3,column = 1)
e_x1 = Entry(root,width=5,borderwidth=5)
e_x1.grid(row = 3,column = 2)
myLabel_y1 = Label(root,text = "y1")
myLabel_y1.grid (row = 3,column = 3)
e_y1 = Entry(root,width=5,borderwidth=5)
e_y1.grid(row = 3,column = 4)
myLabel_x2 = Label(root,text = "x2")
myLabel_x2.grid (row = 4,column = 1)
e_x2 = Entry(root,width=5,borderwidth=5)
e_x2.grid(row = 4,column = 2)
myLabel_y2 = Label(root,text = "y2")
myLabel_y2.grid (row = 4,column = 3)
e_y2 = Entry(root,width=5,borderwidth=5)
e_y2.grid(row = 4,column = 4)
myLabel_x3 = Label(root,text = "x3")
myLabel_x3.grid (row = 5,column = 1)
e_x3 = Entry(root,width=5,borderwidth=5)
e_x3.grid(row = 5,column = 2)
myLabel_y3 = Label(root,text = "y3")
myLabel_y3.grid (row = 5,column = 3)
e_y3 = Entry(root,width=5,borderwidth=5)
e_y3.grid(row = 5,column = 4)
myLabel_x4 = Label(root,text = "x4")
myLabel_x4.grid (row = 6,column = 1)
e_x4 = Entry(root,width=5,borderwidth=5)
e_x4.grid(row = 6,column = 2)
myLabel_y4 = Label(root,text = "y4")
myLabel_y4.grid (row = 6,column = 3)
e_y4 = Entry(root,width=5,borderwidth=5)
e_y4.grid(row = 6,column = 4)
myLabel_x5 = Label(root,text = "x5")
myLabel_x5.grid (row = 7,column = 1)
e_x5 = Entry(root,width=5,borderwidth=5)
e_x5.grid(row = 7,column = 2)
myLabel_y5 = Label(root,text = "y5")
myLabel_y5.grid (row =7 ,column = 3)
e_y5 = Entry(root,width=5,borderwidth=5)
e_y5.grid(row = 7,column = 4) 
# add data to text file
def save():
    node_1 = e_1.get()
    node_2 =e_2.get()
    node_3 =e_3.get()
    node_4 =e_4.get()
    node_5 =e_5.get()
    node_6 =e_6.get()
    x0 = e_x0.get()
    y0 = e_y0.get()
    x1 = e_x1.get()
    y1 = e_y1.get()
    x2 = e_x2.get()
    y2 = e_y2.get()
    x3 = e_x3.get()
    y3 = e_y3.get()
    x4 = e_x4.get()
    y4 = e_y4.get()
    x5 = e_x5.get()
    y5 = e_y5.get()

    line = str({node_1:[x0,y0],node_2:[x1,y1],node_3:[x2,y2],node_4:[x3,y3],node_5:[x4,y4],node_6:[x5,y5]})
    name_string = line.strip('\"')
    print("nodes = " + line,name_string,file = open("input.txt","a"))

    file.close()
btn=Button(root, text="save", command = save).grid(row=8,column = 4)
root.mainloop()

【问题讨论】:

    标签: python tkinter tkinter-entry truss


    【解决方案1】:

    最好使用 for 循环来创建输入行并使用列表来存储输入框。然后更容易创建用于保存的输出字典:

       rows = []  # how the input entry boxes
        for i in range(6):
            # name
            entry = Entry(root, width=5, bd=5)
            entry.grid(row=2+i, column=0)
            # Node
            myLabel1 = Label(root, text=f'Node')
            myLabel1.grid(row=0, column=0)
            # x
            myLabel2 = Label(root, text=f'x{i}')
            myLabel2.grid(row=2+i, column=1)
            entry_x = Entry(root, width=5, bd=5)
            entry_x.grid(row=2+i, column=2)
            # y
            myLabel3 = Label(root, text=f'y{i}')
            myLabel3.grid(row=2+i, column=3)
            entry_y = Entry(root, width=5, bd=5)
            entry_y.grid(row=2+i, column=4)
            # save current input row
            rows.append((entry, entry_x, entry_y))
    
        # add data to text file
        def save():
            nodes = {int(name.get()):[int(ex.get()), int(ey.get())] for name,ex,ey in rows if name.get() and ex.get() and ey.get()}
            if nodes:
                with open('input.txt', 'a') as f:
                    print('nodes =', nodes, file=f)
        myButton_save = Button(root, text="save",padx = 10,pady = 10, command=save)
        myButton_save.grid(row=8, column=4)
        # delete data from window
        def clear():
            with open("input.txt", "r+") as f:
                d = f.readlines()
                f.seek(0)
                for i in d:
                    if i != "nodes":
                        f.write(i)
                f.truncate()
        myButton_clear = Button(root, text="clear",padx = 10,pady = 10, command=clear)
        myButton_clear.grid(row=8, column=5)
        def close():
             for name,ex,ey in rows:
                 name.destroy()
                 ex.destroy()
                 ey.destroy()
            lbl = myLabel1,myLabel2,myLabel3
            for lbl in rows:
                lbl.destroy()
                lbl.destroy()
                lbl.destroy()
            myButton_save.destroy()
            myButton_clear.destroy()
            myButton_close.destroy()
        myButton_close = Button(root, text="close",padx = 10,pady = 10, command=close)
        myButton_close.grid(row=8, column=6)
    

    【讨论】:

    • 这实际上是一种比我放置小部件的答案更清晰易读的方式
    • @acw1668 非常感谢您的回复。代码运行良好,我已包含在其余代码中。我正在尝试清除(使用我定义为“关闭”的新按钮(到他们仍然卡在窗口上的标签。你建议我如何解决这个问题?提前谢谢。
    • 没有看到更新的代码,我完全不明白你说什么。
    • 我已经更新了此评论线程上方的代码。虽然我没有收到任何错误,但在删除其他所有内容后,我仍然可以看到 winow 上的标签。
    【解决方案2】:

    有几种方法可以解决这个问题。 首先

    line = {node_1: [x0, y0], node_2: [x1, y1], node_3: [x2, y2], node_4: [x3, y3], node_5: [x4, y4], node_6: [x5, y5]}
    line.pop('', None)
    

    此代码使用键:'' 删除行字典中的任何元素。但是,如果您的程序增长,您将创建一个包含空白元素的大行字典,然后删除它们,这可能效率低下?

    第二种可能更有效的方法是首先检查输入框是否已填充,如果已填充,则将节点插入行字典中:Tkinter check if entry box is empty

    编辑: 考虑一下,如果您将自己限制为少量的桁架/节点,那么您创建入口框的方式很好,如果您打算扩展程序,那么以下创建入口小部件的迭代方式可能会对您有所帮助:

    from tkinter import *
    
    root = Tk()
    root.geometry("480x480")
    root.title("TRUSS 2D")
    # creating coordinates input
    
    myLabel = Label(root, text="Coordinates")
    myLabel.grid(row=0, column=1, columnspan=4)
    myLabel9 = Label(root, text="Node")
    myLabel9.grid(row=0, column=0, columnspan=1)
    # removed long list of widget creation
    
    # array to hold widget elements
    e_list = []
    for i in range(0, 5):
        e_list.append([Entry(root, width=5, borderwidth=5), Label(root, text="x"), Entry(root, width=5, borderwidth=5),
                       Label(root, text="y"), Entry(root, width=5, borderwidth=5)])
    
    row = 2
    column = 0
    # place elements iteratively, this all depends on the order of the e_list list
    for e in e_list:
        for element in e:
            element.grid(row=row, column=column)
            column += 1
        row += 1
        column = 0
    
    
    
    # add data to text file
    def save():
        lines = dict()
    
        for e in e_list:
            # check to make sure the number, x and y boxes are all populated
            # The elements check depends on the order of e_list
    
            if e[0].index('end') != 0 and e[2].index('end') != 0 and e[4].index('end') != 0:
                if e[0].get() in lines:
                    print('Multiple nodes with the same number!')
                else:
                    # The elements to assign depends on the order of e_list
                    lines[e[0].get()] = [e[2].get(), e[4].get()]
        print(lines)
        # need to format the dictionary and save etc.
    
    btn = Button(root, text="save", command=save).grid(row=8, column=4)
    root.mainloop()
    

    【讨论】:

    • 感谢您解决问题,如何删除输出中的单引号?我只想将它们保存为整数
    • 只是将输入框字符串转换为整数lines[int(e[0].get())] = [int(e[2].get()), int(e[4].get())]
    猜你喜欢
    • 2020-08-03
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2014-10-06
    • 1970-01-01
    相关资源
    最近更新 更多