Home >Backend Development >Python Tutorial >How to use a StringVar from one tab to another tab object while allowing f-string usage and live updates when using Tkinter Notebooks

How to use a StringVar from one tab to another tab object while allowing f-string usage and live updates when using Tkinter Notebooks

WBOY
WBOYforward
2024-02-09 18:30:04865browse

使用 Tkinter Notebooks 时,如何将一个选项卡中的 StringVar 用于另一个选项卡对象,同时允许 f 字符串使用和实时更新

Question content

I'm creating a small project to help create bg3 mods. My ultimate goal is to have multiple tabs where I can enter data and export the file when I save.

I am able to perform saving and tab creation without any issues. What I want to happen is to enter into the configtab the name of the custom class that the mod will create (this is for dnd if it helps). Then in the localizationtab I want to have a tab with an input field. The tag will read the class name from the configtab and display as class name description:; so in config I would type warrior and in localization it will display warrior description:

I can call stringvar for live updates, but this doesn't allow me to use f-strings or other concatenation capabilities. If I use the get() method I only receive the value that was set to the class name when the window was created. So if I use classname.set("warrior"), classname.get() will return a string, I can use an f-string, and I can have it display the warrior description. However, get() is a one-time call and does not update if I change the data in the configuration tab.

The following is a barebones implementation that shows my current general idea. Multiple fields will be referenced in the final project, not just the class name 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 searched in stackoverflow and found other similar questions. They cited using tracking, binding events, or even just pressing a button to refresh data.

I've tried tracking and binding without success. Maybe the way I implemented it is incorrect, I'm sorry but I don't have the code in my file to show my attempt.


Correct answer


As you said, you can use trace() on tkinter variables:

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:"

The above is the detailed content of How to use a StringVar from one tab to another tab object while allowing f-string usage and live updates when using Tkinter Notebooks. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete