Обработка и хранение данных / подсказка к 2 задачке

2

Добавить кнопку к приложению из подсказки, чтобы при нажатии на которую загрузились данные из файлика. Как-то так:

Попробуем теперь сохранить введённые в поля для ввода значения в файл, а потом сделаем так чтобы при открытии файла значения восстановились.

Начнем как всегда с базы:

from tkinter import *

class UI():
    def __init__(self, gui):    
        gui.geometry("400x200")
        
gui = Tk()
UI(gui)
gui.mainloop()

теперь добавим функцию для создания полей для ввода:

from tkinter import *

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("400x200")

gui = Tk()
UI(gui)
gui.mainloop()

теперь добавим поля для ввода:

from tkinter import *

def create_entry(x, y, label_text, entry_width):
    # ...

class UI():
    def __init__(self, gui):    
        gui.geometry("400x200")
        
        # добавил три поля
        self.name = create_entry(10, 10, "Имя", 120)
        self.last_name = create_entry(10, 40, "Фамилия", 120)
        self.age = create_entry(10, 70, "Возраст", 120)
          

gui = Tk()
UI(gui)
gui.mainloop()

если запустить получится что-то такое:

добавим еще кнопочку:

class UI():
    def __init__(self, gui):    
        gui.geometry("400x200")
        
        self.name = create_entry(10, 10, "Имя", 120)
        self.last_name = create_entry(10, 40, "Фамилия", 120)
        self.age = create_entry(10, 70, "Возраст", 120)
        
        self.button = Button(text="Сохранить в файл")
        self.button.place(x=10, y=100)       

и реакцию к ней добавим:

class UI():
    def __init__(self, gui):    
        gui.geometry("400x200")
        
        self.name = create_entry(10, 10, "Имя", 120)
        self.last_name = create_entry(10, 40, "Фамилия", 120)
        self.age = create_entry(10, 70, "Возраст", 120)
        
        # подключил функцию, через command=self.save_to_file
        self.button = Button(text="Сохранить в файл", command=self.save_to_file)
        self.button.place(x=10, y=100)
      
    # собственно сама функция
    def save_to_file(self):
        print("Привет! =)")

а теперь попробуем сохранять то что ввели на форму в файл.

Для этого нам надо собрать данные с формы в так называемый словарик. Словарик — это еще одна структура данных по типу списка. Работает примерно так:

data = {
    "ключ1": "значение1",
    "ключ2": 234,
    "ключ3": ["весна", "лето", "осень"],    
}

# к привязанному к ключу значению получаем через квадратные скобочки
print(data['ключ1'])  # напечатает "значение1"
print(data['ключ2'])  # напечатает 234
print(data['ключ3'])  # напечатает ["весна", "лето", "осень"]

То есть собирать будем так

class UI():
    def __init__(self, gui):    
        # ...
          
    def save_to_file(self):
        # считаем значения с формы и сохраним в словарик
        data = {
            "name": self.name.get(), 
            "last_name": self.last_name.get(),
            "age": self.age.get(),            
        }
        print(data)  # попробуем напечатать словарик в консольку

тестируем:

как видим словарик сформировался из значений на форме.

Мы можем эти значения сохранить в файл, для этого в python есть пакет json. Подключается он как обычно через import, добавим его в самый вверх:

from tkinter import *
import json # добавил импорт

def create_entry(x, y, label_text, entry_width):
    # ...

class UI():
    def __init__(self, gui):    
        # ...
          
    def save_to_file(self):
        # ...

gui = Tk()
UI(gui)
gui.mainloop()

а теперь воспользуемся этим пакетом чтобы сохранить данные в файл, делается это достаточно просто:

class UI():
    def __init__(self, gui):    
        # ...
          
    def save_to_file(self):
        data = {
            "name": self.name.get(), 
            "last_name": self.last_name.get(),
            "age": self.age.get(),            
        }
        print(data)
        
        # открываем файл user.json на запись
        with open("user.json", "w") as f:
            json.dump(data, f) # собственно записываем словарик data в файл f

пробуем:

о файлик появился, только вместо букв какая-та абракадабра. Чтобы буквы писались нормально добавим несколько параметров:

class UI():
    def __init__(self, gui):    
        # ...
          
    def save_to_file(self):
        data = {
            "name": self.name.get(), 
            "last_name": self.last_name.get(),
            "age": self.age.get(),            
        }
        print(data)
        
        # тут добавим encoding="utf8", указав таким образом кодировку, которая поддерживает все буквы
        with open("user.json", "w", encoding="utf8") as f:
            # тут добавим ensure_ascii=False чтобы русские буквы не преобразовывались в комбинации английских
            #  indent -- сделает вывод словарика более читабельным
            json.dump(data, f, ensure_ascii=False, indent=2)

проверяем:

красота! =)

Теперь попробуем считать значения из этого файла и заполнять поля при старте приложения

class UI():
    def __init__(self, gui):    
        # ...
        
        self.button = Button(text="Сохранить в файл", command=self.save_to_file)
        self.button.place(x=10, y=100)
        
        # открываем файл для чтения
        with open("user.json", encoding="utf8") as f:
            # считываем словарик из файла в переменную
            data = json.load(f)
        
        # выведем считанный словарик в консоль
        print(data)
          
    def save_to_file(self):
        # ...

gui = Tk()
UI(gui)
gui.mainloop()

по идее при запуске приложения сразу должно вывестись в консоль содержимое файла, проверяем:

так, попробуем какой-нибудь конкретный ключ вывести, допустим фамилию:

class UI():
    def __init__(self, gui):    
        # ...
        
        with open("user.json", encoding="utf8") as f:
            data = json.load(f)
        
        # выведем фамилию в консоль
        print(data['last_name'])
          
    def save_to_file(self):
        # ...

gui = Tk()
UI(gui)
gui.mainloop()

класс! =О

Ну в принципе теперь можно без проблем заполнить поля на форме по этим полям:

class UI():
    def __init__(self, gui):    
        # ...

        print(data['last_name'])
        
        # заполняем поля для ввода
        self.name.insert(0, data['name'])
        self.last_name.insert(0, data['last_name'])
        self.age.insert(0, data['age'])
          
    def save_to_file(self):
        # ...

gui = Tk()
UI(gui)
gui.mainloop()