Сохранение настроек переменной
Мне нужно сделать так ,чтобы при нажатии на кнопку, путь приложения которое вызывает эта кнопка сохранялся в отдельный файл, а при перезагрузке скрипта всё становилось также, а не сбрасывалось.Прошу помочь с этим, ведь не имею представления как сохранять переменную и как ставить условие.
Мой код:
import tkinter.filedialog as tfd
import tkinter as tk
import os
window = tk.Tk()
window.title("Мой Открыватель")
window.geometry("600x400")
window.resizable(False, False)
file_name = ""
def open():
global file_name
if file_name == "":
file_name = tfd.askopenfilename()
os.startfile(file_name)
else:
os.startfile(file_name)
if btn1["text"] == "":
btn1["text"] = file_name
btn1 = tk.Button(window, text="", command=open)
btn1.place(x = 20, y = 25)
window.mainloop()
Ответы (1 шт):
Как сохранить данные из питона?
Самый простое способ - использовать встроенный модуль - pickle
Он может "замариновать" объект в питоне с помощью pickle.dump(obj, file)
И загрузить "замаринованный" объект обратно с помощью obj = pickle.load(file)
Для этого нам надо открывать файлы и помнить путь сохранения, звучит не очень просто, тогда давайте создадим класс, который будет отвечать именно за это:
@dataclass
class Saver:
filename: str
def save(self, data):
with open(self.filename, "wb") as file:
pickle.dump(data, file)
def load(self):
with open(self.filename, "rb") as file:
return pickle.load(file)
def save_exists(self):
return os.path.exists(self.filename)
Метод save будет сохранять объект в путь, перезаписывая что-либо, если что-то было.
Метод load загрузит сохранение из пути, если сохранение не существует, то поднимет ошибку.
Метод save_exists проверит, есть ли сохранение.
@dataclass здесь просто заменяет нам нужду в __init__
иначе можно было бы написать
def __init__(self, filename):
self.filename = filename
Что мы будем сохранять?
Данные? какие? Давайте определим класс со всеми данными, которые мы будем сохранять, пока что это только путь к файлу:
@dataclass
class Data:
filename: str = "<нет сохранения>"
По умолчанию путь это строка "<нет сохранения>"
Загрузка сохранения
давайте определим функцию, которая попробует загрузить сохранение, и если его нет, то просто вернёт новый объект с данными по умолчанию:
def try_to_load(saver):
if saver.save_exists():
print("загружаем сохранение")
return saver.load()
print("нет сохранения")
return Data()
Главная часть программы
здесь находится вся настройка (окно tk, путь сохранения, положения кнопок)
window = tk.Tk()
window.title("Мой Открыватель")
window.geometry("600x400")
window.resizable(False, False)
saver = Saver("save.pickle")
data = try_to_load(saver)
open_button = tk.Button(
window, text=data.filename, command=on_open)
open_button.place(x=20, y=25)
window.mainloop()
И заметим, что в кнопке мы сразу же используем данные из try_to_load (text=data.filename)
Но подождите, тут есть какая-то функцию on_open, мы её не определяли!
Всему своё время, сейчас определим:
При нажатии кнопки
мы хотим получить путь, если мы его не знаем и сохранить его, иначе можно ничего не делать.
def on_open():
if data.filename != Data.filename:
print("уже есть сохранение")
return
data.filename = tfd.askopenfilename()
saver.save(data)
print("сохранили")
os.startfile(data.filename)
open_button["text"] = data.filename
Здесь data.filename != Data.filename проверяет значение на факт того, было ли оно изменено, т.к. Data.filename == "<нет сохранения>" (как мы и объявляли в нашем классе с данными), и если data.filename было изменено на реальный путь, то оно не будет иметь то значение по умолчанию.
В остальном функция какая же, запрашивает путь, изменяет данные на путь, сохраняет данные и тд...
Одно целое
В итоге у нас получился такой код:
import os
import pickle
import tkinter as tk
import tkinter.filedialog as tfd
from dataclasses import dataclass
@dataclass
class Saver:
filename: str
def save(self, data):
with open(self.filename, "wb") as file:
pickle.dump(data, file)
def load(self):
with open(self.filename, "rb") as file:
return pickle.load(file)
def save_exists(self):
return os.path.exists(self.filename)
@dataclass
class Data:
filename: str = "<нет сохранения>"
def try_to_load(saver):
if saver.save_exists():
print("загружаем сохранение")
return saver.load()
print("нет сохранения")
return Data()
def on_open():
if data.filename != Data.filename:
print("уже есть сохранение")
return
data.filename = tfd.askopenfilename()
saver.save(data)
print("сохранили")
os.startfile(data.filename)
open_button["text"] = data.filename
window = tk.Tk()
window.title("Мой Открыватель")
window.geometry("600x400")
window.resizable(False, False)
saver = Saver("save.pickle")
data = try_to_load(saver)
open_button = tk.Button(
window, text=data.filename, command=on_open)
open_button.place(x=20, y=25)
window.mainloop()