快速语音示例

快速语音示例可朗读用户提供的文本。

快速语音示例演示了如何在应用程序中使用TextToSpeech 类型来朗读文本和控制语音。 Qt Quick应用程序中使用该类型来朗读文本和控制语音。

该示例使用 Qt Quick Controls来控制语音的音调、音量和语速。它还允许用户选择引擎、语言和语音。

初始化文本到语音

首先,我们初始化文本到语音对象tts

    TextToSpeech {
        id: tts
        volume: volumeSlider.value
        pitch: pitchSlider.value
        rate: rateSlider.value

获取状态

切换情况用于更新页脚中的标签statusLabel

        onStateChanged: updateStateLabel(state)

        function updateStateLabel(state)
        {
            switch (state) {
                case TextToSpeech.Ready:
                    statusLabel.text = qsTr("Ready")
                    break
                case TextToSpeech.Speaking:
                    statusLabel.text = qsTr("Speaking")
                    break
                case TextToSpeech.Paused:
                    statusLabel.text = qsTr("Paused...")
                    break
                case TextToSpeech.Error:
                    statusLabel.text = qsTr("Error!")
                    break
            }

在说话时突出显示单词

TextArea input 用于获取输入的文本和作为触发器的onSayingWord 信号,还用于了解在说话时高亮显示单词的位置。

        onSayingWord: (word, id, start, length)=> {
            input.select(start, start + length)

TextArea input 在此声明:

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 8
        id: inputForm

        TextArea {
            id: input
            wrapMode: TextEdit.WordWrap
            text: qsTr("Hello, world!")
            Layout.fillWidth: true
            Layout.minimumHeight: implicitHeight
            font.pointSize: 24
        }

控制语音

Button 类型与 排列在一起,并配置为控制 。RowLayout TextToSpeech tts

发言按钮

创建了一个标有 "说话 "的Button 。如果tts 的状态属性为PausedReady ,该按钮就会启用。

        RowLayout {
            Button {
                text: qsTr("Speak")
                enabled: [TextToSpeech.Paused, TextToSpeech.Ready].includes(tts.state)

单击按钮后,将检索目标设备上的可用语音,并将tts.voice 设置为当前选定的语音voicesComboBox 。然后调用TextToSpeech::say() 并将inputbox 中的文本传递给它。

                onClicked: {
//! [say0]
                    let voices = tts.availableVoices()
                    tts.voice = voices[voicesComboBox.currentIndex]
//! [say1]
                    tts.say(input.text)
                }

暂停、继续和停止按钮

这些按钮的实现类似于Speak 按钮:

            Button {
                text: qsTr("Pause")
                enabled: tts.state == TextToSpeech.Speaking
                onClicked: tts.pause()
                visible: tts.engineCapabilities & TextToSpeech.Capabilities.PauseResume
            }
//! [pause]
//! [resume]
            Button {
                text: qsTr("Resume")
                enabled: tts.state == TextToSpeech.Paused
                onClicked: tts.resume()
                visible: tts.engineCapabilities & TextToSpeech.Capabilities.PauseResume
            }
//! [resume]
            Button {
                text: qsTr("Stop")
                enabled: [TextToSpeech.Speaking, TextToSpeech.Paused].includes(tts.state)
                onClicked: tts.stop()
            }
        }

选择文本到语音选项

GridLayout 用于安排选择文本到语音合成的引擎、地域、语音、音量、音调和速率选项的控件和标签。

选择引擎、地域和语音

一组ComboBox 组件用于选择这些参数。

对于引擎选择ComboBoxtts.availableEngines() 被用作模型。

onActivated 触发将 tts.engine 分配给 ComboBoxes 当前索引处的当前文本。

            Text {
                text: qsTr("Engine:")
            }
            ComboBox {
                id: enginesComboBox
                Layout.fillWidth: true
                model: tts.availableEngines()
                onActivated: {
                    tts.engine = textAt(currentIndex)
                    updateLocales()
                    updateVoices()

上述代码片段的最后两行显示,可用的本地语言和语音也会在此时更新,因为它们取决于所选的引擎。这些功能将在下一节中介绍。

localesComboBox 的实现方式与engineComboBox 相同,但不更新可用引擎。

                }
            }
            Text {
                text: qsTr("Locale:")
            }
            ComboBox {
                id: localesComboBox
                Layout.fillWidth: true
                onActivated: {
                    let locales = tts.availableLocales()
                    tts.locale = locales[currentIndex]
                    updateVoices()
                }
            }
            Text {
                text: qsTr("Voice:")
            }
            ComboBox {
                id: voicesComboBox
                Layout.fillWidth: true
            }
选择音量、音高和音速

这些控制功能通过Sliders 实现,具体如下:

            Text {
                text: qsTr("Volume:")
            }
            Slider {
                id: volumeSlider
                from: 0
                to: 1.0
                stepSize: 0.2
                value: 0.8
                Layout.fillWidth: true
            }
            Text {
                text: qsTr("Pitch:")
            }
            Slider {
                id: pitchSlider
                from: -1.0
                to: 1.0
                stepSize: 0.5
                value: 0
                Layout.fillWidth: true
            }
            Text {
                text: qsTr("Rate:")
            }
            Slider {
                id: rateSlider
                from: -1.0
                to: 1.0
                stepSize: 0.5
                value: 0
                Layout.fillWidth: true
            }
        }
    }

更新可用选项

通过使用Component.onCompleted 信号,一旦根ApplicationWindow 实例化,就会执行以下操作。

  • enginesComboBox 索引被设置为当前设置的tts 引擎。
  • 更新可用的本地语言和语音。
  • tts 发送当前状态信号。
    Component.onCompleted: {
        enginesComboBox.currentIndex = tts.availableEngines().indexOf(tts.engine)
        // some engines initialize asynchronously
        if (tts.state == TextToSpeech.Ready) {
            engineReady()

在整个应用程序中使用的updateLocales()updateVoice() 函数实现如下:

        } else {
            tts.stateChanged.connect(root.engineReady)
        }

        tts.updateStateLabel(tts.state)
    }

    function engineReady() {
        tts.stateChanged.disconnect(root.engineReady)
        if (tts.state != TextToSpeech.Ready) {
            tts.updateStateLabel(tts.state)
            return;
        }
        updateLocales()
        updateVoices()
    }

    function updateLocales() {
        let allLocales = tts.availableLocales().map((locale) => locale.nativeLanguageName)
        let currentLocaleIndex = allLocales.indexOf(tts.locale.nativeLanguageName)
        localesComboBox.model = allLocales
        localesComboBox.currentIndex = currentLocaleIndex
    }

    function updateVoices() {
        voicesComboBox.model = tts.availableVoices().map((voice) => voice.name)
        let indexOfVoice = tts.availableVoices().indexOf(tts.voice)
        voicesComboBox.currentIndex = indexOfVoice

运行示例

运行示例 Qt Creator,打开Welcome 模式,并从Examples 中选择示例。更多信息,请参阅Qt Creator: 教程:构建并运行

示例项目 @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.