You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让tkinter Entry组件设为只读且保留原有内容?

Tkinter Entry只读状态下保留内容的解决方案

问题说明

使用Python的tkinter开发JSON编辑器时,通过以下代码创建Entry输入框:

globals()[f"dv_{key}_{subkey}"] = tk.Entry(self.root, width=250)

添加state='disabled'参数实现只读后,输入框虽无法编辑,但原有内容消失。需要实现只读状态的同时正常显示设置只读前的内容。

解决方案

Tkinter的Entry组件在state='disabled'状态下无法插入或修改内容,因此正确的操作顺序是:

  1. 先创建**默认正常状态(state='normal')**的Entry组件
  2. 插入需要显示的内容
  3. 最后将组件设置为state='disabled'

如果需要允许用户选中复制内容但不能编辑,也可以保留state='normal',同时绑定<Key>事件阻止输入:

def disable_input(event):
    return "break"

entry.bind("<Key>", disable_input)

这种方式下用户仍可选中复制内容,体验更友好。

另外需要注意:若后续要读取或修改Entry内容,必须先将组件恢复为state='normal',操作完成后再设回disabled,否则无法获取或修改内容。

修改后的完整JSON编辑器代码

import json
import tkinter as tk

class JsonEditor:
    def __init__(self, root, filename):
        self.root = root
        self.root.title("JSON Editor")
        self.json_data = {}
        self.textboxes = []
        self.filename = filename
        self.read_file()
        self.create_widgets()

    def create_widgets(self):
        # 创建菜单栏
        menubar = tk.Menu(self.root)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="保存", command=self.save_file)
        menubar.add_cascade(label="文件", menu=filemenu)
        self.root.config(menu=menubar)

        # 为JSON键值对创建输入框
        row = 0
        for key, value in self.json_data.items():
            if isinstance(value, dict):
                label = tk.Label(self.root, text=key)
                label.grid(row=row, column=0)
                row += 1
                for subkey, subvalue in value.items():
                    sublabel = tk.Label(self.root, text=subkey)
                    sublabel.grid(row=row, column=1)
                    # 先创建正常状态的Entry
                    subtextbox = tk.Entry(self.root, width=50)
                    # 插入内容
                    subtextbox.insert(0, subvalue)
                    # 设置为只读状态
                    subtextbox.config(state='disabled')
                    subtextbox.grid(row=row, column=2)
                    self.textboxes.append((key, subkey, subtextbox))
                    row += 1
            else:
                label = tk.Label(self.root, text=key)
                label.grid(row=row, column=0)
                textbox = tk.Entry(self.root, width=50)
                textbox.insert(0, value)
                textbox.config(state='disabled')
                textbox.grid(row=row, column=1)
                self.textboxes.append((key, textbox))
                row += 1

        # 创建提交按钮
        submit_button = tk.Button(self.root, text="提交", command=self.save_file)
        submit_button.grid(row=row, column=1)

    def read_file(self):
        with open(self.filename, "r") as f:
            self.json_data = json.load(f)

    def save_file(self):
        # 保存前恢复正常状态,否则无法获取内容
        for item in self.textboxes:
            if len(item) == 2:
                key, textbox = item
                textbox.config(state='normal')
                self.json_data[key] = textbox.get()
                textbox.config(state='disabled')
            elif len(item) == 3:
                key, subkey, subtextbox = item
                subtextbox.config(state='normal')
                self.json_data[key][subkey] = subtextbox.get()
                subtextbox.config(state='disabled')
        with open(self.filename, "w") as f:
            json.dump(self.json_data, f, indent=4)

root = tk.Tk()

# 设置窗口大小
root.geometry("800x600")

# 设置JSON文件路径
filename = "C:/orderprepare.json"

# 创建编辑器GUI
editor = JsonEditor(root, filename)

# 启动GUI主循环
root.mainloop()

示例JSON文件

{
    "ShipTo": {
        "CustomerName1": "test test",
        "CustomerName2": "test test",
        "Phone": "000-000-0000dfswerwer",
        "Address1": "test test",
        "Address2": "dfewrwer",
        "City": "Tazewellddsewrer",
        "StateOrProvince": "TNdsfsewr",
        "PostalCode": "82823",
        "Country": "USA"
    },
    "BillTo": {
        "CustomerName1": "test2 test2",
        "CustomerName2": "test2 test2",
        "Address1": "test test",
        "Address2": "dfewrwer",
        "City": "anywhere",
        "StateOrProvince": "TNdsfsewr",
        "PostalCode": "84747",
        "Country": "USA"
    },
    "ItemList": [
        {
            "ItemNumber": "itemxxxx111",
            "BuyerPartNumber": "partxxx1111",
            "Quantity": "7",
            "UnitPrice": "809"
        }
    ]
}

内容的提问来源于stack exchange,提问作者Alex Co

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:52:52