You need to enable JavaScript to run this app. 如何在for循环中配置tkinter Radiobutton实现语音选择功能
优惠活动
大模型
产品
解决方案
定价
更多

如何在for循环中配置tkinter Radiobutton实现语音选择功能

问题根源
  • 循环生成单选按钮时,所有按钮的value参数被硬编码为1。tkinter 同组单选按钮的互斥规则是:绑定同一个变量时,只有不同按钮对应不同的value值,才会实现多选一的逻辑。所有按钮value相同的话,任意点击一个都会把变量设置为同一个值,系统会把所有匹配该值的单选按钮都标记为选中,就出现了全选的异常。
  • 额外潜在问题:每次点击「Search」按钮都会新增一批单选按钮,不会清理之前生成的旧按钮,多次点击会出现大量重复冗余的控件。
修正方案
  1. 循环遍历语音列表时,给每个单选按钮分配唯一的value(可用索引值,后续要直接调用语音的话也可以直接存语音ID)
  2. 每次点击Search生成新按钮前,先清理上次生成的所有旧单选按钮,避免控件堆积
  3. (可选)给绑定的变量设置默认初始值,避免未选择时出现取值异常
修正后代码
from tkinter import *
import pyttsx3

def sel():
    selection = "Voice number #" + str(var.get())
    label.config(text=selection)

def voice():
    # 先清空上次生成的旧单选按钮,避免重复堆积
    for widget in voice_frame.winfo_children():
        widget.destroy()
    
    try:
        engine = pyttsx3.init()
    except ImportError:
        print("Requested driver is not found")
    except RuntimeError:
        print("Driver fails to initialize")

    voices = engine.getProperty("voices")
    
    # 用enumerate拿到每个语音的唯一索引,给对应单选按钮分配唯一value
    for idx, voice in enumerate(voices):
        r1 = Radiobutton(
            voice_frame, 
            text=voice.id, 
            variable=var, 
            value=idx, 
            command=sel
        )
        r1.pack(anchor=W)


app = Tk()
var = IntVar()
# 可选:设置默认选中第一个语音,取消注释即可启用
# var.set(0)

app.title("Voices available.")
app.geometry("800x300+700+250")

label = Label(app, text="Voices on your pc.", font=("Helvetica", 20))
label.pack()
button = Button(app, text="Search", command=voice)
button.pack()

# 新增专门放置语音单选按钮的容器,避免和其他控件混淆
voice_frame = Frame(app)
voice_frame.pack(pady=10)

mainmenu = Menu(app)
files_menu = Menu(mainmenu, tearoff=0)
files_menu.add_command(label="Quit", activebackground="red", command=app.quit)

mainmenu.add_cascade(label="Files", menu=files_menu)

app.config(menu=mainmenu)
app.mainloop()
后续优化建议

如果后续需要直接拿到选中的语音ID用于语音合成,可以把变量类型换成StringVar,直接把voice.id作为单选按钮的value,不用再通过索引回查语音列表:

  • 把var = IntVar()改为var = StringVar()
  • 循环内单选按钮的value=idx改为value=voice.id
    此时sel函数里var.get()返回的就是选中语音的ID,可直接传给pyttsx3设置使用。

内容的提问来源于stack exchange,提问作者Mélissa Ch.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 16:06:04