1

I have created a simple application where you can enter a word and press a button, and each time you press the button, an image and 2 labels are packed onto the screen, 1 label containing the words you have typed. I want to make it so that if you close the application and reopen it, the images and labels you have placed by pressing the button are still there. How could this be done?

from tkinter import *
import pickle
import calendar
from tkcalendar import *

import calendar

from tkcalendar import *
from datetime import datetime
from datetime import date
from time import strftime
from datetime import timedelta, datetime, date
from ttkthemes import ThemedTk, THEMES
import pickle

self = Tk()
self.title('Storing data')
self.geometry("850x800")

x = 200
y = 250
c = 460
d = 290
e = 325
f = 355
g = 390
h = 420
i = 460
j = 490

LARGE_FONT= ("Verdana", 24)
SMALL_FONT=("Verdana", 12)


def get_text(file):
    with open(file, "r") as MyFile:
        return MyFile.read()


def edit_text(file, text, img_dir):
    with open(file, "w") as MyFile:
        MyFile.write(text + "\n" + "apple.png")


def step(self):
    my_progress['value']+= 5
        

def display():

    global x , y , c , d , e , f , g, h, i, j
    box_image = PhotoImage(file='apple.png')
    panel2 = Label(self, image=box_image, bg='#f7f6f6')
    panel2.image = box_image
    panel2.place(x=x, y=y)
    x=x
    y = y+260
    #assessment name
    n = Label(self, text="", bg="#e0f6fc", font=60)
    
    n.configure(text=assessment_name.get())
    n.pack()
    
    #due date
    d = Label(self, text="Due:", bg="#e0f6fc", font=SMALL_FONT)
    d.pack()
    #cal date
    c= Label(self, text="", bg="#e0f6fc", font=SMALL_FONT)
    c.pack()
        
    
button = Button(self, text="place", command=display)
button.pack()

save = Button(self, text="save", command=edit_text)
save.pack()

open_button =Button(self, text="open", command=get_text)
open_button.pack()


edit_text("textfile.txt", "label contents", "apple.png")



  

assessment_name = Entry(self)
assessment_name.place(relx=0.5, y=220, anchor='center')

global cal2
cal2 = Calendar(self, background="#e0f6fc", disabledbackground="white", bordercolor="light blue", headersbackground="light blue", normalbackground="#e0f6fc", foreground="black", normalforeground='black', headersforeground='white', selectmode="day", year=2021, month=8, day=9)
cal2.place(relx=0.5, y=400, anchor='center')

due_date = Button(self, text="Submit")
due_date.place(relx=0.5, y=510, anchor='center')







self.mainloop()
Minbutt
  • 59
  • 1
  • 6
  • Does this answer your question? [How to save a data after closing a window?](https://stackoverflow.com/questions/55363748/how-to-save-a-data-after-closing-a-window) – qwerteee Oct 23 '21 at 06:52

3 Answers3

0

If you want to save something for later, you can save it to a text file. You can save the text and the directory for the image

First, create a .txt file where you want ( within the same folder as the code is best ). Next, create a function which gets the text from the file:

def get_text(file):
    with open(file, "r") as MyFile:
        return MyFile.read()

This code will return a string containing what is in the text file. Next, create a function which can edit the file. It is best to do this by deleting it and re-writing it again

def edit_text(file, text, img_dir):
    with open(file "w") as MyFile:
        MyFile.write(text + "\n" + img_dir)

When calling this function, it will change the contents of the file to what is inputted. For example:

edit_text("textfile.txt", "label contents", "apple.png")

This would change the contents of "textfile.txt" to:

label contents
apple.png

You can use this to store data for your application. I hope this helped!

  • Hello, I have edited my code to add in what you suggested but I am still a bit confused. I made a save button with the `edit_text` command and a open button with the `get_text` command but am getting error `TypeError: edit_text() missing 3 required positional arguments: 'file', 'text', and 'img_dir'` when I press the save button. – Minbutt Oct 24 '21 at 22:55
  • Hello, you are getting this error because the edit_text command requires three inputs within the brackets. You can call it like this: edit_text(“nameoffile.txt”, “the contents of the label”, “apple.png”) – Atomic Peanut Oct 26 '21 at 06:28
  • Hello, may I ask what you mean by "the contents of the label" ? – Minbutt Oct 26 '21 at 11:52
  • Where do I place this code? Do I put it where I am defining the function? e.g. `def edit_text("r.txt", "contents of the label", "apple.png"):` ? What would I put for "contents of the label? r.txt is the name of my text file. – Minbutt Oct 27 '21 at 06:24
  • By “contents of the label” I mean what is in the label. You can use label.text to get the text within it. You can place the code defining the functions at the top of the file after the imports. – Atomic Peanut Oct 27 '21 at 09:22
0

While you could save data into a txt, it is much easier imo to store it as JSON. With JSON, you could store a dictionary of values and recall them quickly and easily. You could then take these values and set them to the various parameters within your app.

Python also has a built in JSON library, so all you have to do is import json. You can find the documentation here

SlavaCat
  • 101
  • 6
0

Here is a more detailed explanation:

To accomplish this you will need to store the saved data in an external file. This will require knowledge of the .open() , .read() , json.loads() , and json.dumps() functions

We will first start by creating the json file we want to store out data in, ex: myJson.json.

In this file, create a dictionary with the value you want to store, ex: {"entryVal": "Hello World!"}

The following is a basic GUI that we will build on:

from tkinter import *
import json

root = Tk()

toSave = StringVar()
Entry(root, textvariable = toSave) .pack()

Button(root, text = "save value!") .pack()

root.mainloop()

Next, we need to define two functions: one to open the Json, and one to save the Json.

def openJson():
    with open('myJson.json', 'r') as f:
        value = json.loads(f.read())["entryVal"]
        toSave.set(value)

def saveJson():
    with open('myJson.json', 'w') as f:
        currentVal = json.dumps({"entryVal":toSave.get()})
        f.write(currentVal)

openJson() will open the Json file, decode from Json, take the key-value of 'entryVal' and set our entry box to have the text it found.

saveJson() will take the value from our entry, put it in a dictionary under the key 'entryVal', encode to Json, and then write it into the save file.

Now we just need to call openJson() when we start the program, and create a button to trigger saveJson():

from tkinter import *
import json

root = Tk()

def openJson():
    with open('myJson.json', 'r') as f:
        value = json.loads(f.read())["entryVal"]
        toSave.set(value)

def saveJson():
    with open('myJson.json', 'w') as f:
        currentVal = json.dumps({"entryVal":toSave.get()})
        f.write(currentVal)

toSave = StringVar()
Entry(root, textvariable = toSave) .pack()

Button(root, text = "save value!", command = saveJson) .pack()

openJson()

root.mainloop()
SlavaCat
  • 101
  • 6
  • Will this method work for multiple images and labels? Also, how do I create a json file? – Minbutt Oct 27 '21 at 06:49
  • You could store boolean values in the Json, such as `"openedImages":true` , and when you start the program, open the Json, check if the bools are True, and if so, pack the images onto the screen, same works for labels. – SlavaCat Oct 27 '21 at 13:31
  • As for Json files, you just create a new file and give it the extension `.json` while saving. Json is super easy to learn: https://www.youtube.com/watch?v=iiADhChRriM – SlavaCat Oct 27 '21 at 13:33
  • Hello, I have decided to just start with labels only. I am trying to implement the Json method but am struggling. Would you be able to look at my full code and provide feedback? – Minbutt Oct 28 '21 at 05:02
  • Sure, what part of the process are you getting stuck at? Saving Json, Loading Json, Checking if you should display the Labels? – SlavaCat Oct 28 '21 at 13:32