Python 如何绑定或使用radiobutton进行选择使用?

Python 如何绑定或使用radiobutton进行选择使用?,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,我有一个程序,我使用radiobutton从电脑中选择声音。有些程序只有一种声音,而其他程序则有更多声音。因此,当用户选择一种声音时,我希望该程序使用此声音进行对话 现在我可以找到这些声音并点击单选按钮,我可以在电脑中看到这些声音的效果。这是在第二个窗口,一个顶级窗口中,但在我找到一种方法将其用于我的主程序根窗口之后,我在我的根窗口中尝试了不同的组合,在我的engine.setPropertyvoice,voices[X].id中使用var.Set。X=我手动编写的语音编号,在我的情况下为0到3

我有一个程序,我使用radiobutton从电脑中选择声音。有些程序只有一种声音,而其他程序则有更多声音。因此,当用户选择一种声音时,我希望该程序使用此声音进行对话

现在我可以找到这些声音并点击单选按钮,我可以在电脑中看到这些声音的效果。这是在第二个窗口,一个顶级窗口中,但在我找到一种方法将其用于我的主程序根窗口之后,我在我的根窗口中尝试了不同的组合,在我的engine.setPropertyvoice,voices[X].id中使用var.Set。X=我手动编写的语音编号,在我的情况下为0到3。但是我希望这个数字可以通过用户选择的单选按钮来设置

此外,如果用户希望降低或加快速度,我希望能够在其他窗口中设置语音的速度。因此,我认为这将是语音选择的相同问题,因为我将在另一个顶级窗口中,而此调整在我的根窗口中

我在这里买这个。我在网上搜索过,现在什么也没找到。 这是我的代码:

import tkinter
from tkinter import *
import pyttsx3


def voice_info():
    voiceinfo = tkinter.Toplevel(root)
    var = IntVar()
    voiceinfo.title("Voices available.")
    voiceinfo.geometry("800x300+700+250")
    label = tkinter.Label(voiceinfo, text="Voices on your pc.", font=("Helvetica", 20))
    label.pack(pady=10)

    def sel():
        selection = f"Voice number #{var.get()} selected"
        label.config(text=selection)

    def voice():
        try:
            engine = pyttsx3.init()
        except ImportError:
            print("Requested driver is not found")
        except RuntimeError:
            print("Driver fails to initialize")

        voices = engine.getProperty("voices")

        for idx, voice in enumerate(voices):
            r1 = Radiobutton(voiceinfo, text=voice.id, variable=var, value=idx, command=sel)
            r1.pack(anchor=W)
        label2 = Label(voiceinfo, text="Select a voice", font=("Helvetica", 20))
        label2.pack(pady=10)

    button = tkinter.Button(voiceinfo, text="Search", command=voice)
    button.pack(pady=10)

    second_menu = tkinter.Menu(voiceinfo)
    files_menu2 = tkinter.Menu(second_menu, tearoff=0)
    files_menu2.add_command(label="Quit", activebackground="red", command=voiceinfo.destroy)

    second_menu.add_cascade(label="Files", menu=files_menu2)

    voiceinfo.config(menu=second_menu)


root = Tk()
root.title("Voices test for A.I. - Other Files")
root.geometry("500x350")


def talk():
    engine = pyttsx3.init()
    engine.setProperty("rate", 200)
    voices = engine.getProperty("voices")
    engine.setProperty("voice", voices[2].id)
    engine.say(my_entry.get(1.0, END))
    engine.runAndWait()
    my_entry.delete(1.0, END)


label = Label(root, text="Enter your text here", font=("Helvetica", 18))
label.pack(pady=20)

my_entry = Text(root, height=8, width=40, font=("Helvetica", 15))
my_entry.pack(pady=5)

my_button = Button(root, text="Speak", command=talk)
my_button.pack(pady=20)

mainmenu = tkinter.Menu(root)

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

option_menu = tkinter.Menu(mainmenu, tearoff=0)
option_menu.add_command(label="Check voices", command=voice_info)

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


root.config(menu=mainmenu)
root.mainloop()

这是可行的解决方案。首先拆下所有引擎,并将engine=pyttsx3.init放在root=Tk的正下方:

然后请注意,在talk中,您总是将属性设置为engine.setPropertyvoice,voices[2].id中可用的第三种语音,因此请删除该属性和其他不重要的内容。那就是:

def talk():
    engine.setProperty("rate", 200)
    engine.say(my_entry.get(1.0, END))
    engine.runAndWait()
    my_entry.delete(1.0, END)
现在更改sel功能以获取语音列表,然后将id索引出来,然后更改语音:

def sel():
    selection = f"Voice number #{var.get()} selected" # Consider #{int(var.get())+1}
    label.config(text=selection)
    voices = engine.getProperty("voices")
    engine.setProperty("voice", voices[int(var.get())].id)

我还建议您研究线程,并将您的讨论放在一个单独的线程中,这样就不会冻结GUI,而叙事线程也可能导致GUI崩溃。无论如何,感谢您耐心地清除所有查询。

如果我没有错的话,在用radiobutton选择voice之后,您也想应用该语音吗?@Cool Cloud,没错。这样,用户就可以在她的电脑上选择他们喜欢的声音。我想如果你在选择的末尾加上任何代码,它就会被执行。所以在最后,添加engine.setPropertyvoice,var.get?Mmmm它必须是本地引擎。好的,将engine=pyttsx3.init放在所有代码之外,在root=Tk下面,并删除所有其他engine=pyttsx3.init。只是当在函数内部使用engine时,它不同于其他函数外部和内部的其他引擎。所以有不止一个引擎,试着把它全部卸下。非常感谢,它工作得很好!我非常感谢你的帮助。我也学到了很多,谢谢。我会检查线程这对我来说是一个新的术语。。。。
def sel():
    selection = f"Voice number #{var.get()} selected" # Consider #{int(var.get())+1}
    label.config(text=selection)
    voices = engine.getProperty("voices")
    engine.setProperty("voice", voices[int(var.get())].id)