我试着给一个输入框设置一个值,但输入框只接收到PY_VAR

编程语言 2026-07-09

我遇到一个问题:给一个StringVar设置了一个值,但与该StringVar关联的Entry没有显示任何值(它是空的)。如果我调试,变量本身(即StringVar)只显示 "PY_VAR" 而不是我设置的值。我尝试了两种方法:将值设置给StringVar var.set(),以及 entry.insert()。都不起作用,Entry字段仍然是空的。

应输入Entry的数据来自一个json文件,内容如下:

{
  "Project Settings": {
    "settings": {
      "pos1": "50",
      "pos2": "FALSE",
      "pos3": "FALSE",
      "pos4": "TRUE",
      "pos5": "70",
      "pos6": "TON"
    }
  }
}

如下所示的Python代码:

import tkinter as tk
from tkinter import ttk
import json

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title("Test Program")
        self.geometry("820x810")
        self.resizable(False, False)

        frame = ttk.Frame(padding=10)
        frame.grid()
        frame.columnconfigure(1, weight=1)


        self.settings = ImportSettings("Test.json")
        self.setting = self.settings.get_config()

        for row, (k, v) in enumerate(self.setting["Project Settings"]["settings"].items()):
            ttk.Label(frame, text=k).grid(row=row, column=0, sticky="w", padx=(0, 8), pady=4)
            var = tk.StringVar()
            var.set(str(v))
            ttk.Entry(frame, textvariable=var, width=80).grid(row=row, column=1, sticky="we", pady=4)



class ImportSettings:
    config_data = {}

    def __init__(self, path):
        with open(path) as json_file:
            self.config_data = json.load(json_file)

    def get_config(self):
        return self.config_data


if __name__ == "__main__":
    app = App()
    app.mainloop()

解决方案

问题在于你创建了本地 var = StringVar(),它会在下一个循环中移除之前的 var。而且很可能Python会把它从内存中移除。

你必须把变量保存到一个列表中,例如 self.string_vars = []

    self.string_vars = []

    for row, (k, v) in enumerate(self.setting["Project Settings"]["settings"].items()):

        # ... code ...

        var = tk.StringVar()
        self.string_vars.append(var)

        # ... code ...

本地变量在我使用 insert() 时也会造成问题,但当变量被分配给 self. Code works for me also with 时,它就能工作,例如.insert("end", str(v))but it doesn't needtextvariable. If you still use local variable in textvariable=var`

    for row, (k, v) in enumerate(self.setting["Project Settings"]["settings"].items()):

        # ... code ...

        e = ttk.Entry(frame, width=80)
        e.insert("end", str(v))

        # ... code ...

包含两种版本的完整可运行代码:

你可以运行 script.py 2 来测试第二个版本,等等。

import tkinter as tk
from tkinter import ttk
import json
import sys


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title("Test Program")
        self.geometry("820x810")
        self.resizable(False, False)

        frame = ttk.Frame(padding=10)
        frame.grid()
        frame.columnconfigure(1, weight=1)

        self.settings = ImportSettings("Test.json")
        self.setting = self.settings.get_config()

        if len(sys.argv) == 1:
            self.version_1(frame)
        else:
            if sys.argv[1] == "1":
                self.version_1(frame)
            elif sys.argv[1] == "2":
                self.version_2(frame)
            elif sys.argv[1] == "3":
                self.version_3(frame)

    def version_1(self, frame):
        print("--- version 1 ---")

        self.string_vars = []

        items = self.setting["Project Settings"]["settings"].items()

        for row, (k, v) in enumerate(items):
            label = ttk.Label(frame, text=k)
            label.grid(row=row, column=0, sticky="w", padx=(0, 8), pady=4)

            # var = tk.StringVar(value=str(v))
            var = tk.StringVar()
            self.string_vars.append(var)

            var.set(str(v))

            entry = ttk.Entry(frame, textvariable=var, width=80)
            entry.grid(row=row, column=1, sticky="we", pady=4)

            # var.set(str(v))

    def version_2(self, frame):
        print("--- version 2 ---")

        items = self.setting["Project Settings"]["settings"].items()

        for row, (k, v) in enumerate(items):
            label = ttk.Label(frame, text=k)
            label.grid(row=row, column=0, sticky="w", padx=(0, 8), pady=4)

            entry = ttk.Entry(frame, width=80)
            entry.grid(row=row, column=1, sticky="we", pady=4)

            entry.insert("end", str(v))

    def version_3(self, frame):
        print("--- version 3 ---")

        self.string_vars = []

        items = self.setting["Project Settings"]["settings"].items()

        for row, (k, v) in enumerate(items):
            label = ttk.Label(frame, text=k)
            label.grid(row=row, column=0, sticky="w", padx=(0, 8), pady=4)

            var = tk.StringVar()
            self.string_vars.append(var)

            entry = ttk.Entry(frame, textvariable=var, width=80)
            entry.grid(row=row, column=1, sticky="we", pady=4)

            entry.insert("end", str(v))


class ImportSettings:
    config_data = {}

    def __init__(self, path):
        with open(path) as json_file:
            self.config_data = json.load(json_file)

    def get_config(self):
        return self.config_data


if __name__ == "__main__":
    app = App()
    app.mainloop()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章