'Storing and using GUI objects with Tkinter
So I have a class that just creates a gui with a text box to type into. I would like to store multiple of these objects and their content that is entered by the user. I have a button (on a seperate gui) that creates the new object and spawns the gui and then stores that into a simple list listOobjects = []
. My thought process was that I could simply just call listOobjects[i]
when a button was pressed to bring that gui back with its contents still in place. That didn't work so then I thought maybe I could use the listOobjects[i].withdraw()
and listOobjects[i].deiconify()
to hide and recall what gui I want. Not only did that not work but I also feel that isn't the best course of action with possibly 12 gui's practically 'minimized'. I also looked into pickle
to save and recall objects. I haven't tried it yet but was curious of my best course of action here?
Solution 1:[1]
Although I don't know what is considered best practice in this case, here is one possible way that avoids keeping track of 'minimized' widgets that aren't being used.
This solution deletes widgets which are not currently being displayed by calling the destroy
method, so the program isn't doing extra work maintaining objects that aren't being used.
In order to be able to recall the deleted widgets when the button is pressed, all relevant information from a widget is recorded and stored in a tuple before the widget is deleted. This way, no information is lost, but only simple values are being stored instead of tkinter
widgets.
These tuples of values are then used as parameters to instantiate new widgets which exactly replicate the old, deleted ones.
Here is a simple demo that toggles between three different Entry
widgets:
import tkinter as tk
window = tk.Tk()
window['width'] = 500
window['height'] = 300
textBox1 = tk.Entry(master=window, bg='darkblue', fg='yellow', text="First",
relief=tk.RAISED, bd=3)
textBox2 = tk.Entry(master=window, bg='purple', fg='white', text="Second",
relief=tk.RAISED, bd=3)
textBox3 = tk.Entry(master=window, bg='darkgreen', fg='yellow', text="Third",
relief=tk.RAISED, bd=3)
textBox1.place(x=50, y=100, width=100, height=30)
textBox2.place(x=200, y=100, width=100, height=30)
textBox3.place(x=350, y=100, width=100, height=30)
# Will store all information necessary to reconstruct and place previously displayed
# text boxes which have been removed.
storage = [None, None, None]
# Store a reference to the text box which is currently displayed
activeTextBox = {'textBox': textBox1, 'index': 0}
# After recording all information to be used in 'storage', call 'destroy()' to delete
# the widget instead of hiding it (for more efficiency)
def sendToStorage(textBox, index):
parameters = (textBox['bg'], textBox['fg'], textBox['relief'], textBox['bd'], textBox.get())
storage[index] = parameters
textBox.destroy()
# Using the stored information, construct a new text box (tk.Entry widget) which is
# identical to the old one that was deleted.
def retrieveFromStorage(index):
txtB = storage[index]
storage[index] = None
activeTextBox['textBox'] = tk.Entry(window, bg=txtB[0], fg=txtB[1], relief=txtB[2], bd=txtB[3])
activeTextBox['textBox'].insert(0, txtB[4])
activeTextBox['textBox'].place(x=50+150*index, y=100, width=100, height=30)
# Put the old text box in storage and retrieve the one after it. Increment the index
# of the text box that is currently active (loop around once you get to the end of 'storage').
def toggleTextBox():
sendToStorage(activeTextBox['textBox'], activeTextBox['index'])
activeTextBox['index'] += 1
if activeTextBox['index'] == len(storage):
activeTextBox['index'] = 0
retrieveFromStorage(activeTextBox['index'])
window.update()
# DEMO: CALL FUNCTION TO STORE AND DELETE ALL BUT 1 TEXT BOX
sendToStorage(textBox2, 1)
sendToStorage(textBox3, 2)
# THIS IS THE BUTTON THAT WILL CYCLE BETWEEN THE TEXT BOXES
toggleButton = tk.Button(master=window, text='TOGGLE ACTIVE TEXT BOX',
command=toggleTextBox)
toggleButton.place(x=100, y=200, width=300, height=50)
window.mainloop()
It will keep track of the text boxes' current text (that the user has entered) as well as their formatting options. Try it out and see if it does what you're looking for!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Quack E. Duck |