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

Tkinter文本编辑器编辑菜单字体设置功能失效问题求助

解决Tkinter记事本字体不更新的问题

我帮你找到了问题所在,咱们一步步来修复:

问题根源

  1. Text组件未监听字体变量变化:你初始化Text时用了font=[font, 12],但font是StringVar对象,Tkinter的Text不会自动追踪这个变量的变更,所以就算你选了新字体,文本区域也不会响应。
  2. OptionMenu缺少变更回调:当前的OptionMenu只是让用户选择字体,但没有绑定任何函数来把选中的字体应用到Text组件上。
  3. 隐藏bug:Save函数里误用了field变量,应该是你定义的文本组件text,不然点击保存会抛出NameError。

修复方案

步骤1:添加字体变更的回调函数

写一个函数,当用户在OptionMenu中选择新字体时,自动更新Text的字体设置:

def update_font(*args):
    # 提取当前选中的字体,结合字号12,更新Text组件的字体
    text.configure(font=(font.get(), 12))

步骤2:给StringVar绑定回调

让font变量在值变化时自动触发上面的函数:

font.trace_add("write", update_font)

步骤3:修正Text组件的初始化

把font参数改成元组形式,初始使用默认字体值:

text = tk.Text(
    main,
    width=win.winfo_screenwidth(),
    height=30,
    font=(font.get(), 12)
)

修改后的完整代码

try:
    import tkinter as tk
    import tkinter.messagebox as msg
    from tkinter import filedialog
except ImportError:
    import Tkinter as tk
    import Tkinter.messagebox as msg
    from Tkinter import filedialog
import re
import pyautogui

fonts = [ 'consolas', 'helvetica', 'algerian' ]

### Functions
## File menu
def Save():
    filepath = filedialog.asksaveasfilename(
        initialdir='/',
        title='Save as',
        filetypes=(('Text document', '*.txt'),('All files','*.*'))
    )
    if not filepath:
        return
    # 修复:把field改成text
    with open(filepath, 'w') as f:
        f.write(text.get(1.0, tk.END))
    win.title(filepath)

def Open():
    filepath = filedialog.askopenfilename(
        initialdir = "/",
        title = "Open file",
        filetypes=(('Text document', '*.txt'),('All files','*.*'))
    )
    if not filepath:
        return
    text.delete(1.0, tk.END)
    with open(filepath, 'r') as f:
        text.insert(tk.END, f.read())
    win.title(filepath)

def Exit():
    global win
    if msg.askyesno('Quit?', 'Are you sure you want to quit?'):
        win.destroy()

## Edit menu
def ctrl(key):
    pyautogui.keyDown('ctrl')
    pyautogui.hotkey(key)
    pyautogui.keyUp('ctrl')

# 新增:字体更新回调函数
def update_font(*args):
    text.configure(font=(font.get(), 12))

####### 修改后的edit_win函数
def edit_win():
    global font, fonts
    editwin = tk.Toplevel(win)
    editwin.title("Font and Size")
    choose_font = tk.OptionMenu(editwin, font, *fonts)
    choose_font.pack(padx=10, pady=10)
#######

### Window
win = tk.Tk()
win.title('Text editor')
win.geometry('600x500')
font = tk.StringVar(win)
font.set(fonts[0])
# 绑定变量变化的回调
font.trace_add("write", update_font)

### Widgets
## Main Frame
main = tk.Frame(win)
main.pack(side='top', fill='both', expand=True)

## Field
# 修复:font参数改为元组形式,初始使用默认字体
text = tk.Text(
    main,
    width=win.winfo_screenwidth(),
    height=30,
    font=(font.get(), 12)
)
text.grid(row=0, column=1, sticky='nsew')

## Menu
bar = tk.Menu(win)
# File
file = tk.Menu(bar, tearoff=0)
file.add_command(label='Save', command=Save)
file.add_command(label='Open', command=Open)
file.add_command(label='Exit', command=Exit)
bar.add_cascade(label='File', menu=file)
# Edit
edit = tk.Menu(bar, tearoff=0)
edit.add_command(label='Font and size', command=edit_win)
edit.add_command(label='Copy', command=lambda: ctrl('c'))
edit.add_command(label='Paste', command=lambda: ctrl('v'))
bar.add_cascade(label='Edit', menu=edit)

win.config(menu=bar)
win.mainloop()

额外说明

如果之后要添加字号调整功能,可以再新增一个IntVar来存储字号,然后在update_font函数里把字号也加入到font参数中,比如:

size_var = tk.IntVar(win, value=12)
# 然后在update_font里改成:
text.configure(font=(font.get(), size_var.get()))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 15:37:35