猿创征文|Qt文本转语音类QTextToSpeech实例项目实现

猿创征文|Qt文本转语音类QTextToSpeech实例项目实现_第1张图片

猿创征文|Qt文本转语音类QTextToSpeech实例项目实现

  • 一、QTextToSpeech简介
  • 二、Qt解决中文乱码源码
  • 三、QTextToSpeech实现头文件
  • 四、QTextToSpeech实现解析
  • 五、QTextToSpeech实现源码
  • 六、QTextToSpeech实现效果

一、QTextToSpeech简介

QtSpeech是一个Qt封装的跨平台TTS(文本变成语音输出)API,在不同平台下利用系统自带的TTS引擎。
【1】在Windows下使用SAPI; 【2】在Mac下使用SpeechSynthesis; 【3】而在Linux下使用 Festival;
需要的类:QTextToSpeech
需要引入的模块:QT +=texttospeech
函数基类:QObjeck

请在.pro项目中添加文本转语音模块 -》texttospeech
猿创征文|Qt文本转语音类QTextToSpeech实例项目实现_第2张图片

为了促进理解,将ui设计界面先奉上,根据界面的信息,整个项目的实现不难理解

猿创征文|Qt文本转语音类QTextToSpeech实例项目实现_第3张图片
ui界面设计 ,仅供参考
猿创征文|Qt文本转语音类QTextToSpeech实例项目实现_第4张图片

二、Qt解决中文乱码源码

main.cpp

#include "mainwindow.h"
#include 
#include 
int main(int argc, char *argv[])
{
    //解决中文乱码
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForLocale(codec);

    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

三、QTextToSpeech实现头文件

先介绍头文件,将所需的头文件和变量说明清楚
保存语言和国家 目前只有中国和美国为例
QVector voices;
QTextToSpeech *my_tospeech;//说话对象


本次项目第一步通过读取文件内容添加进QPlainTextEdit文本框,然后语音读取里面的内容,语音分为中英文,有男女语音,以在Windows平台为例,低配的某些电脑可能语音无法收听,在Linux平台的需要安装对应的包,这里就不深究了,实际想了解者,可自行修炼。


mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include //文本转语音类
#include //数组容器类
#include //说话类
#include //日志记录类
#include 

#include //文件IO
#include //文件对话框
#include //目录
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
public :
    void speak();//说话
    void Speakstop();//停止
    void speakPause();//暂停说话
    void speakContinue();//继续说话

    void setRate(int );//语速
    void setPitch(int );//音高
    void setVolume(int );//男  女

    void stateChanged(QTextToSpeech::State state);//状态改变
    void engineSelected(int index);//引擎选择
    void languageSelected(int language);//语言选择
    void voiceSelected(int index);//语音选择

    void localeChanged(const QLocale &locale);//本地改变

private slots:
    void on_PB_speak_2_clicked();//打开文件 写入文本框

private:
    Ui::MainWindow *ui;
    QVector <QVoice> voices;//保存音量值
    QTextToSpeech *my_tospeech;//说话对象
};

#endif // MAINWINDOW_H

四、QTextToSpeech实现解析

配置应该通过一组规则来启用哪些类别和消息类型。 如果在安装程序过滤器()中安装了自定义类别过滤器, 或者如果用户定义了QT_LOGGING_CONFQT_LOGGING_RULES环境变量,则可能会忽略这些规则。
QStringLiteral: 宏在编译时从字符串文字str中生成QString的数据。在这种情况下,
从它创建一个QString是免费的,生成的字符串数据存储在已编译的对象文件的只读段中。

	//日志记录类 安装过滤规则
    QLoggingCategory::setFilterRules(QStringLiteral("qt.speech.tts=true \n qt.speech.tts.*=true"));

在本次项目中,信号与槽的初始化使用直接引用地址方式,其于几种自行修炼。
信号与槽可以看作调用函数的地址实现,在以下第二种,就是典型的函数指针类型,static_cast(&QComboBox::currentIndexChanged),其中static_cast代表强制类型转换,里面的参数就是转换类型:
返回值:void
指针:QComboBox:: *
参数:int
需要转化的类型:&QComboBox::currentIndexChanged

`
信号的发送者 :ui->PB_speak
信号函数	:clicked()
信号的接收者	:this
接收槽函数	:speak()
`
connect(ui->PB_speak,&QPushButton::clicked,this,&MainWindow::speak);
//以下这种需要介绍以下
connect(ui->com_language, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::languageSelected);

使用状态栏显示每个阶段的任务,本次添加了-》语速、音量、语言、音高等设置项,内容繁多但在本仙师的运作下,每个阶段皆可柳暗花明。

QTextToSpeech在进行读取 、暂定、停止、继续等阶段,只要按钮按下,QTextToSpeech里面得到枚举值会自动设置,并且QTextToSpeech的信号stateChanged(QTextToSpeech::State state)会触发以下槽函数,所以每次点击按钮显示以下信息不要受到惊吓

//状态改变 读 暂停 继续 停
void MainWindow::stateChanged(QTextToSpeech::State state)
{
    if (state == QTextToSpeech::Speaking) {
        ui->statusBar->showMessage("正在读取...");
    }
    else if (state == QTextToSpeech::Ready)
        ui->statusBar->showMessage("读取停止...");
    else if (state == QTextToSpeech::Paused)
        ui->statusBar->showMessage("读取暂停...");
    else
        ui->statusBar->showMessage("读取错误!!!");
}

五、QTextToSpeech实现源码

头文件和主函数上面已经介绍完毕,这里介绍实现的.cpp文件

内容还是比较繁多,经我折腾一上午,通过qDebug()打印出数据,一切自然明了,每个按钮皆可触发对应的信号与槽,根据函数的先后执行顺序进行理解即可

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),my_tospeech(0)   //参数列表初始化
{
    ui->setupUi(this);

    qDebug()<<"my_tospeech="<<my_tospeech<<endl;
    //配置应该通过一组规则来启用哪些类别和消息类型。
    //如果在安装程序过滤器()中安装了自定义类别过滤器,
    //或者如果用户定义了QT_LOGGING_CONF或QT_LOGGING_RULES环境变量,则可能会忽略这些规则
    /*QStringLiteral:宏在编译时从字符串文字str中生成QString的数据。在这种情况下,
     * 从它创建一个QString是免费的,生成的字符串数据存储在已编译的对象文件的只读段中。*/
    QLoggingCategory::setFilterRules(QStringLiteral("qt.speech.tts=true \n qt.speech.tts.*=true"));

    //填充引擎选择列表
    ui->com_engine->addItem("Default",tr("Default"));

    //获取当前受支持的区域设置的向量。[引擎]
    foreach(QString engineList, QTextToSpeech::availableEngines())
    {//后一个所有值依次给前面的字符串
        ui->com_engine->addItem(engineList, engineList);
        qDebug()<<"engineList="<<engineList<<endl;
    }
    ui->com_engine->setCurrentIndex(0);//默认显示第一项
    /*============================================================================*/
    engineSelected(0);//填充引擎选择
    /*============================================================================*/

    //信号与槽
    connect(ui->PB_speak,&QPushButton::clicked,this,&MainWindow::speak);
    connect(ui->PB_pause,&QPushButton::clicked,this,&MainWindow::speakPause);
    connect(ui->PB_continue,&QPushButton::clicked,this,&MainWindow::speakContinue);
    connect(ui->PB_stop,&QPushButton::clicked,this,&MainWindow::Speakstop);

    connect(ui->horizontalSlider_pitch,&QSlider::valueChanged,this,&MainWindow::setPitch);
    connect(ui->horizontalSlider_rate,&QSlider::valueChanged,this,&MainWindow::setRate);
    connect(ui->horizontalSlider_volume,&QSlider::valueChanged,this,&MainWindow::setVolume);
    //设置QComboBox信号与槽 这里使用函数指针
    connect(ui->com_engine,static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this,&MainWindow::engineSelected);

}
MainWindow::~MainWindow()
{
    delete ui;
}
//说话啊  靓仔
void MainWindow::speak()
{
    my_tospeech->say(ui->plainTextEdit->toPlainText());//读取文本
    ui->PB_stop->setStyleSheet("color:#000000");
    ui->PB_speak->setStyleSheet("color:#FF0000");
    ui->PB_continue->setStyleSheet("color:#000000");
    ui->PB_pause->setStyleSheet("color:#000000");
}
//先暂停下
void MainWindow::speakPause()
{
    my_tospeech->pause();
    ui->PB_stop->setStyleSheet("color:#000000");
    ui->PB_speak->setStyleSheet("color:#000000");
    ui->PB_continue->setStyleSheet("color:#000000");
    ui->PB_pause->setStyleSheet("color:#FF0000");
}
//继续说话
void MainWindow::speakContinue()
{
    qDebug()<<"继续说话";
    my_tospeech->resume();
    ui->PB_stop->setStyleSheet("color:#000000");
    ui->PB_speak->setStyleSheet("color:#000000");
    ui->PB_continue->setStyleSheet("color:#FF0000");
    ui->PB_pause->setStyleSheet("color:#000000");
}
//停止说话
void MainWindow::Speakstop()
{
    my_tospeech->stop();
    ui->PB_stop->setStyleSheet("color:#FF0000");
    ui->PB_speak->setStyleSheet("color:#000000");
    ui->PB_continue->setStyleSheet("color:#000000");
    ui->PB_pause->setStyleSheet("color:#000000");
}
//设置语速
void MainWindow::setRate(int rate)
{
    qDebug()<<"rate ="<<rate;
    my_tospeech->setRate(rate);
}
//设置音高
void MainWindow::setPitch(int pitch)
{
    qDebug()<<"pitch ="<<pitch;
    my_tospeech->setPitch(pitch);
}
//设置音量
void MainWindow::setVolume(int volume)
{
    qDebug()<<"volume ="<<volume;
    my_tospeech->setVolume(volume);
}
//引擎 索引改变时触发
void MainWindow::engineSelected(int index)
{
    qDebug()<<"index ="<<index<<endl;
    QString engineName = ui->com_engine->itemData(index).toString();//获取数据
    qDebug()<<"engineName ="<<engineName<<endl;
    my_tospeech->deleteLater();//删除
    if(engineName == "Default")
        my_tospeech = new QTextToSpeech(this);//第一个构造函数
    else
        my_tospeech = new QTextToSpeech(engineName,this);//第二个构造函数
    //此时语言不可连接
    disconnect(ui->com_language,static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this,&MainWindow::languageSelected);;
    ui->com_language->clear();

    //在连接其信号之前,先填充语言组合框。
    //QLocale类在各种语言中的数字及其字符串表示之间进行转换。
    QVector<QLocale>locales = my_tospeech->availableLocales();//[语言]
    qDebug()<<"locales="<<locales<<endl;
    //此属性保存正在使用的当前区域设置。默认情况下,将使用系统区域设置。
    QLocale curLocale = my_tospeech->locale();
    qDebug()<<"curLocale="<<curLocale<<endl;

    foreach (const QLocale &locale, locales) {
        QString name = QString("%1 (%2)").arg(QLocale::languageToString(locale.language()))
                .arg(QLocale::countryToString(locale.country()));
         QVariant localeVal(locale);
         ui->com_language->addItem(name,localeVal);
          qDebug()<<"name="<<name<<"localeVal="<<localeVal<<endl;
         if(locale.name() == curLocale.name())
         {
             curLocale = locale;
         }
    }

    //设置
    setRate(ui->horizontalSlider_rate->value());//语速
    setVolume(ui->horizontalSlider_volume->value());//音量
    setPitch(ui->horizontalSlider_pitch->value());//音高
    connect(my_tospeech, &QTextToSpeech::stateChanged, this, &MainWindow::stateChanged);
    connect(my_tospeech, &QTextToSpeech::localeChanged, this, &MainWindow::localeChanged);
    //可以选择语言
    connect(ui->com_language, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::languageSelected);
    /*===============================================================================*/
    localeChanged(curLocale);//设置当前语言和国家
    /*===============================================================================*/

    return;
}
//状态改变 读 暂停 继续 停
void MainWindow::stateChanged(QTextToSpeech::State state)
{
    if (state == QTextToSpeech::Speaking) {
        ui->statusBar->showMessage("正在读取...");
    }
    else if (state == QTextToSpeech::Ready)
        ui->statusBar->showMessage("读取停止...");
    else if (state == QTextToSpeech::Paused)
        ui->statusBar->showMessage("读取暂停...");
    else
        ui->statusBar->showMessage("读取错误!!!");
}
//男女语音 根据语言和国家改变
void MainWindow::localeChanged(const QLocale &locale)
{
    qDebug()<<"当前的语言和国家="<<locale<<endl;
    ui->statusBar->showMessage("男女语音 国家和语言改变");
    QVariant localeVal(locale);
    ui->com_language->setCurrentIndex(ui->com_language->findData(localeVal));
    //说话类型
    disconnect(ui->com_name, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::voiceSelected);
    ui->com_name->clear();

    voices = my_tospeech->availableVoices();//保存国家和语言在矢量数组
    QVoice currentVoice = my_tospeech->voice();
    foreach (const QVoice &voice, voices) {
        ui->com_name->addItem(QString("%1 - %2 - %3").arg(voice.name())//语音读字人
                          .arg(QVoice::genderName(voice.gender()))//女性  male:男性的
                          .arg(QVoice::ageName(voice.age())));//成年的
        if (voice.name() == currentVoice.name())
            ui->com_name->setCurrentIndex(ui->com_name->count() - 1);
    }
    connect(ui->com_name, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MainWindow::voiceSelected);

}
//当前的语言选择
void MainWindow::languageSelected(int language)
{
    QLocale locale1 = ui->com_language->itemData(language).toLocale();
    qDebug()<<"当前的语言选择="<<ui->com_language->itemText(language)<<endl;
    my_tospeech->setLocale(locale1);//设置语言

}
//男女 说话类型
void MainWindow::voiceSelected(int index)
{
    qDebug()<<"当前的语音类型="<<ui->com_name->itemText(index)<<endl;
    my_tospeech->setVoice(voices.at(index));
}
//打开要读取的文件
void MainWindow::on_PB_speak_2_clicked()
{
    ui->plainTextEdit->clear();
    QString curPath = QDir::currentPath();
    QString Title1 ="打开一个文件";
    //文件过滤器
    QString filter1 = "文本文件(*.txt);;程序文件(*.cpp *.h);;WPS(*.docx *.xlsx);;所有文件(*.*)";
    //获取文件绝对路径
    QString filename =QFileDialog::getOpenFileName(this,Title1,curPath,filter1);
    if(filename.isEmpty())
        return;
    qDebug()<<"filename="<<filename<<endl;

    //打开文件 读取内容
    QFile file(filename);
    if(!file.exists())
    {
        qDebug()<<file.errorString();
        return;
    }
    if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
        return;
    QByteArray alldata = file.readAll();
    QString data(alldata);
    ui->plainTextEdit->appendPlainText(tr("%1").arg(data));//将文件内容写入文本框
    file.close();
    return;
}

六、QTextToSpeech实现效果

语音转文字已不再新奇,也成为了生活必不可少的一部分,音量范围0~99 ,语速也可0~99,不过设置为0即可,不然快到让你意想不到,中文阅读是女士发音,在英文时,有男女发音,可切换多次进行校验,本尊以亲测,皆可使用
猿创征文|Qt文本转语音类QTextToSpeech实例项目实现_第5张图片

【1】打开文件时的效果
猿创征文|Qt文本转语音类QTextToSpeech实例项目实现_第6张图片
【2】说话时的效果
猿创征文|Qt文本转语音类QTextToSpeech实例项目实现_第7张图片
【3】选择英文时的效果,并且选择了男生语音
猿创征文|Qt文本转语音类QTextToSpeech实例项目实现_第8张图片
其他项,实现的效果相差无几,不在过多解释,说话类型和引擎这些选项获取的是电脑支持的类型,可能电脑不同,略有差异,不过能播放语音即可


就不再分享源码了,因为以上便是,推荐各位使用Qt版本5.9.0或者5.9.1功能完善,具有自动补齐功能,不过也有缺点,有些隐含错误不会提示,各有差异,用客自行选择即可,好的咋们下会见。
猿创征文|Qt文本转语音类QTextToSpeech实例项目实现_第9张图片

你可能感兴趣的:(QT,界面开发工程师课程,qt,ui,QTextToSpeech,c++,开源)