Добавить на форму поле для ввода позиции, в которую вставлять очередной элемент списка.
- Если поле пустое то вставлять в конец файла
- Если там 0, то в начало
- если 1 – на вторую позицию
- и т. д.
Добавить на форму поле для ввода позиции, в которую вставлять очередной элемент списка.
Попробуем теперь поработать со списком словариков. Допустим мы делаем программу с помощью которой можно формировать списки студентов. А сами списки чтобы можно было хранить в файле. Как бы мы могли это сделать?
Начнем с кода похожий на тот что был в прошлом задании:
from tkinter import *
import json
# это просто чтобы создавать поля для ввода
def create_entry(x, y, label_text, entry_width):
label = Label(gui, text=label_text)
label.place(x=x, y=y)
gui.update()
entry = Entry(gui)
entry.place(x=x + label.winfo_width() + 10, y=y, width=entry_width)
gui.update() # еще раз обновим интерфейс
return entry # вернем метку
class UI():
def __init__(self, gui):
gui.geometry("400x150")
# тут три поля под имя, фамилию, группу
self.name = create_entry(10, 10, "Имя", 120)
self.last_name = create_entry(10, 40, "Фамилия", 120)
self.group = create_entry(10, 70, "Группа", 120)
# кнопочка чтобы в файл сохранять
self.button = Button(text="Сохранить в файл", command=self.save_to_file)
self.button.place(x=10, y=100)
# собственно реакция на кнопочку для сохранения в файл
def save_to_file(self):
data = {
"name": self.name.get(),
"last_name": self.last_name.get(),
"group": self.group.get(),
}
with open("user.json", "w", encoding="utf8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
gui = Tk()
UI(gui)
gui.mainloop()
сейчас при попытке сохранить в файла она будет постоянно перезаписывать данные
поэтому надо как-то научится там делать сразу несколько записей.
Идея заключается в том, что мы вместо того чтобы хранить одну запись будем хранить список записей.
Можно для начала попробовать запихать в файлик просто список с одной записью:
class UI():
def __init__(self, gui):
# ...
def save_to_file(self):
# data это теперь список, внутри которого лежит один словарик:
data = [
{
"name": self.name.get(),
"last_name": self.last_name.get(),
"group": self.group.get(),
}
]
with open("user.json", "w", encoding="utf8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
теперь если на кнопочку кликнуть, то увидим, что внутри там стал тоже список, только уже с заполненными значениями
попробуем теперь немного реструктурировать код. Ведь по идее когда мы первый раз запустили программу список у нас пустой, а потому по клику мы добавляем в список нового студента. С точки зрения кода — это можно записать так:
class UI():
def __init__(self, gui):
# ...
def save_to_file(self):
data = [] # создали пустой список
data.append( # добавили в него элемент
{
"name": self.name.get(),
"last_name": self.last_name.get(),
"group": self.group.get(),
}
)
# перезаписываем файл
with open("user.json", "w", encoding="utf8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
работать это правда все равно будет так же, потому что наша кнопка при клике
поэтому нам надо сделать так чтобы при клике на кнопку:
пишем код:
class UI():
def __init__(self, gui):
# ...
def save_to_file(self):
# заружаем список из файла
with open("user.json", encoding="utf8") as f:
data = json.load(f) # кладем его в переменную data
# добавляем в этот список данные с формы
data.append(
{
"name": self.name.get(),
"last_name": self.last_name.get(),
"group": self.group.get(),
}
)
# сохраняем обновленный список в файл
with open("user.json", "w", encoding="utf8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
проверяем:
чудеса =О
Кстати у нас получается, что добавление идет всегда в конец файла, можно в принципе сделать чтобы добавление шло в начало списка.
Для этого надо добавлять элемент в список следующим образом:
class UI():
def __init__(self, gui):
# ...
def save_to_file(self):
with open("user.json", encoding="utf8") as f:
data = json.load(f)
# использую метод insert, у него первый параметр — это куда вставлять элемент,
# если указать 0 то будет вставлять элемент на первую позицию в списке
# если указать 1 то будет вставлять элемент на вторую позицию и т.д.
data.insert(0, {
"name": self.name.get(),
"last_name": self.last_name.get(),
"group": self.group.get(),
})
with open("user.json", "w", encoding="utf8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)