如何修改Python Tkinter Entry控件高度实现文本换行避免截断?
问题
我有一段能处理任意JSON文件并在GUI中展示键和子键的Python代码,但目前遇到文本内容被截断的问题。我想扩展输入框的高度(2-3行)来完整查看内容,但修改width属性会导致小输入框过度扩展,界面混乱。当前输入框由类似以下代码创建:
globals()[f"dv_{key}_{subkey}"] = tk.Entry(self.root, width=50)
希望修改后输入框支持高度扩展和文本换行,避免内容截断。
附现有代码:
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): # create menu bar menubar = tk.Menu(self.root) filemenu = tk.Menu(menubar, tearoff=0) filemenu.add_command(label="Save", command=self.save_file) menubar.add_cascade(label="File", menu=filemenu) self.root.config(menu=menubar) # create textboxes for JSON keys and values 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) subtextbox = tk.Entry(self.root, width=50) subtextbox.insert(0, subvalue) 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.grid(row=row, column=1) self.textboxes.append((key, textbox)) row += 1 # create submit button submit_button = tk.Button(self.root, text="Submit", 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 self.json_data[key] = textbox.get() elif len(item) == 3: key, subkey, subtextbox = item self.json_data[key][subkey] = subtextbox.get() with open(self.filename, "w") as f: json.dump(self.json_data, f) root = tk.Tk() # set the display resolution root.geometry("800x600") # set the JSON file path filename = "C:/orderprepare.json" # create the editor GUI editor = JsonEditor(root, filename) # start the GUI main loop 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" } ] }
解决方案
tkinter的Entry控件是单行输入组件,无法支持多行显示和高度调整,需要替换为Text控件,它支持多行文本、高度设置和自动换行。具体修改步骤如下:
- 替换Entry为Text控件:创建输入框时,用
tk.Text代替tk.Entry,设置height参数为2或3,同时开启wrap=tk.WORD实现按单词自动换行,保持width=50避免界面混乱。 - 调整文本插入方式:Text控件的插入方法是
insert(tk.END, 内容),而非Entry的insert(0, 内容)。 - 修改数据读取逻辑:Text控件获取内容用
get("1.0", tk.END).strip(),其中"1.0"表示第一行第一个字符,tk.END表示末尾,strip()用于移除自动添加的换行符。
修改后的完整代码:
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="Save", command=self.save_file) menubar.add_cascade(label="File", 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, sticky="nw") row += 1 for subkey, subvalue in value.items(): sublabel = tk.Label(self.root, text=subkey) sublabel.grid(row=row, column=1, sticky="nw") # 替换为Text控件,设置高度2行,按单词换行 subtextbox = tk.Text(self.root, width=50, height=2, wrap=tk.WORD) subtextbox.insert(tk.END, subvalue) subtextbox.grid(row=row, column=2, sticky="nsew") self.textboxes.append((key, subkey, subtextbox)) row += 1 else: label = tk.Label(self.root, text=key) label.grid(row=row, column=0, sticky="nw") # 替换为Text控件,设置高度2行,按单词换行 textbox = tk.Text(self.root, width=50, height=2, wrap=tk.WORD) textbox.insert(tk.END, value) textbox.grid(row=row, column=1, sticky="nsew") self.textboxes.append((key, textbox)) row += 1 # 创建提交按钮 submit_button = tk.Button(self.root, text="Submit", command=self.save_file) submit_button.grid(row=row, column=1) # 让网格列自动适应窗口宽度(可选优化) self.root.grid_columnconfigure(2, weight=1) self.root.grid_columnconfigure(1, weight=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 # 获取Text内容并移除末尾换行符 self.json_data[key] = textbox.get("1.0", tk.END).strip() elif len(item) == 3: key, subkey, subtextbox = item self.json_data[key][subkey] = subtextbox.get("1.0", tk.END).strip() with open(self.filename, "w") as f: json.dump(self.json_data, f, indent=4) # 添加indent让保存的JSON更美观 root = tk.Tk() # 设置窗口大小 root.geometry("800x600") # 设置JSON文件路径 filename = "C:/orderprepare.json" # 创建编辑器GUI editor = JsonEditor(root, filename) # 启动GUI主循环 root.mainloop()
额外优化:添加了sticky="nw"让标签和文本框左上角对齐,grid_columnconfigure让列自动适应窗口宽度,保存JSON时添加indent=4保持格式化。
内容的提问来源于stack exchange,提问作者Alex Co
相关产品推荐
相关产品推荐

