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

2024-05-16 03:10:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个程序,我使用radiobutton从pc上选择声音(有些只有一种声音,而另一些有更多),因此当用户选择一种声音时,我希望该程序使用该声音进行对话

现在我可以找到这些声音并点击单选按钮,我可以在pc中看到这些声音的#。(这是在第二个窗口,一个顶级窗口中),但在我找到一种方法将其用于我的主程序(我的根窗口)之后,我在我的根窗口中尝试了不同的组合,在我的引擎.setProperty(“voice”,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()

Tags: textadd声音tkinterrootfileslabelengine
1条回答
网友
1楼 · 发布于 2024-05-16 03:10:23

这是可行的解决方案。首先移除所有engine并将engine = pyttsx3.init()放在root = Tk()的正下方:

root = Tk()
engine = pyttsx3.init()

然后注意talk()中总是将属性设置为engine.setProperty("voice", 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)

我还建议您查看threading,并将talk放在单独的线程中,这样就不会在叙述时冻结GUI(threading也可能导致GUI崩溃)。无论如何,谢谢你耐心地解答所有问题

相关问题 更多 >