Как я могу сохранить только заполненные виджеты ввода без сохранения пустого виджета записи в файле Atext с помощью приложения Tkinter? - PullRequest
0 голосов
/ 17 апреля 2020

Я создаю простое приложение для анализа ферм, и мне нужно собрать и сохранить некоторые данные в текстовом файле. Согласно моему коду, я могу решить только для 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()

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Лучше использовать для l oop для создания входных строк и использовать список для хранения полей ввода. Тогда проще создать выходной файл для сохранения:

   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)
0 голосов
/ 18 апреля 2020

Есть несколько способов решить эту проблему. Первый

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 проверить, если поле ввода пусто

РЕДАКТИРОВАТЬ: Если подумать, то как вы создали поля ввода Хорошо, если вы ограничите себя небольшим количеством ферм / узлов, если вы планируете расширить программу, вам может помочь следующий более итеративный способ создания виджетов ввода:

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

Results from the EDIT code. Note, node 2 x and y boxes aren't populated and don't show up in the terminal output

...