Maison  >  Article  >  développement back-end  >  Comment utiliser un StringVar d'un onglet à un autre objet d'onglet tout en autorisant l'utilisation de f-string et les mises à jour en direct lors de l'utilisation de Tkinter Notebooks

Comment utiliser un StringVar d'un onglet à un autre objet d'onglet tout en autorisant l'utilisation de f-string et les mises à jour en direct lors de l'utilisation de Tkinter Notebooks

WBOY
WBOYavant
2024-02-09 18:30:04803parcourir

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

Contenu de la question

Je crée un petit projet pour aider à créer des mods bg3. Mon objectif ultime est d'avoir plusieurs onglets dans lesquels je peux saisir des données et exporter le fichier lorsque je l'enregistre.

J'ai pu effectuer la sauvegarde et la création d'onglets sans aucun problème. Ce que je veux, c'est entrer dans l'onglet de configuration le nom de la classe personnalisée que le mod créera (c'est pour le mdn si cela peut aider). Ensuite, dans l'onglet localisation, je souhaite avoir un onglet avec un champ de saisie. La balise lira le nom de la classe dans l'onglet de configuration et s'affichera comme description du nom de classe : donc dans la configuration, je taperais guerrier et dans la localisation, elle affichera la description du guerrier :

Je peux appeler stringvar pour les mises à jour en direct, mais cela ne me permet pas d'utiliser des f-strings ou d'autres fonctions de concaténation. Si j'utilise la méthode get(), je ne reçois que la valeur définie sur le nom de la classe lors de la création de la fenêtre. Donc, si j'utilise classname.set("warrior"), classname.get() renverra une chaîne, je peux utiliser une f-string et je peux lui faire afficher la description du guerrier. Cependant, get() est un appel unique et ne se met pas à jour si je modifie les données dans l'onglet de configuration.

Ce qui suit est une implémentation simple qui montre mon idée générale actuelle. Plusieurs champs seront référencés dans le projet final, pas seulement le champ du nom de classe.

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)

localisationtab.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)

J'ai cherché dans stackoverflow et trouvé d'autres questions similaires. Ils ont cité l'utilisation du suivi, la liaison d'événements ou même la simple pression sur un bouton pour actualiser les données.

J'ai essayé le suivi et la liaison, mais sans succès. Peut-être que la façon dont je l'ai implémenté est incorrecte, je suis désolé mais je n'ai pas le code dans mon fichier pour montrer ma tentative.


Bonne réponse


Comme vous l'avez dit, vous pouvez utiliser trace() sur les variables tkinter :

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer