Issue
I am creating a little project for helping creating BG3 mods. My end goal is to have multiple tabs where I can enter the data, and it exports the files when I save.
I am able to perform the saving and tab creation with no issue. What I would like to happen is in the ConfigTab I type in a name for the custom class the mod will create (this is for DND if it helps). Then in the LocalizationTab I would like for there to be a label with an entry field. The label would read the class name from the ConfigTab and show as Class Name Description:; so in config I would type in Warrior and in localization it would show Warrior Description:
I am able to call to the StringVar for live updates, but that does not allow me to use f-string or other concatenation features. And if I use the get() method, I am only receiving the value that is set to classname at window creation. So if I use classname.set("Warrior"), classname.get() will return a string that I can use f-string and I can get it to show Warrior Description. However, get() is a one time call and does not update if I change the data in the config tab.
Below is a barebones implementation to show the general idea of what I have currently. There will be more than one field that will be referenced in the final project and not just the classname field.
MainProgram.py
import tkinter as tk
import tkinter.ttk as ttk
from ClassConfigTab import ClassConfigTab
from LocalizationTab import LocalizationTab
# Create tkinter window
root = tk.Tk()
root.title("BG3 Mod Creation Tool")
root.geometry("650x150")
# Create notebook
nb = ttk.Notebook(root)
config_tab = ClassConfigTab(nb)
localization_tab = LocalizationTab(config_tab, nb)
nb.add(config_tab, text='Configure class')
nb.add(localization_tab, text='Localization')
# Load window
nb.pack(expand=1, fill="both")
root.mainloop()
ClassConfigTab.py
import tkinter as tk
from tkinter import ttk
class ClassConfigTab(ttk.Frame):
"""Content for the required tab for creating a class mod."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.classname = tk.StringVar(name="classname")
self.classname.set("Warrior")
self.place_widgets()
def place_widgets(self):
entry_classname = ttk.Entry(self, width=50, textvariable=self.classname)
# Place widgets
entry_classname.grid(column=0,
row=1,
padx=10,
pady=0,
sticky=tk.W)
LocalizationTab.py
import tkinter as tk
from tkinter import ttk
class LocalizationTab(ttk.Frame):
"""This will contain what is going to be shown on the localization tab."""
def __init__(self, config_tab, *args, **kwargs):
super().__init__(*args, **kwargs)
# This updates automatically but can't use f-string.
self.label_main_name = ttk.Label(self,
textvariable=config_tab.classname)
# This loads the StringVar value on window creation, but does not auto update.
self.label_main_name_two = ttk.Label(self,
text=config_tab.classname.get())
self.place_widgets()
def place_widgets(self):
self.label_main_name.grid(column=0,
row=0,
padx=10,
pady=5,
sticky=tk.W)
self.label_main_name_two.grid(column=1,
row=0,
padx=10,
pady=5,
sticky=tk.W)
I have searched through StackOverflow and found other questions that are similar. They have referenced used trace, bind events, and even just having a button that you press to refresh data.
I have tried both trace and bind, and have had no luck. Perhaps the way I had implemented it was not correct and I apologize, but I do not have the code still in my files to show my attempts.
Solution
As you said, you can use trace()
on tkinter variable:
class LocalizationTab(ttk.Frame):
"""This will contain what is going to be shown on the localization tab."""
def __init__(self, config_tab, *args, **kwargs):
super().__init__(*args, **kwargs)
self.config_tab = config_tab # save for later access
self.label_main_name = ttk.Label(self)
# call self.update_label() whenever the variable is updated
config_tab.classname.trace_add("write", self.update_label)
self.place_widgets()
self.update_label() # update label initially
def place_widgets(self):
self.label_main_name.grid(column=0,
row=0,
padx=10,
pady=5,
sticky=tk.W)
def update_label(self, *args):
self.label_main_name["text"] = f"{self.config_tab.classname.get()} Description:"
Answered By - acw1668
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.