我们知道,win7系统自带有讲述人,即能够机器读出当前内容,详细能够将电脑锁定。然后点击左下角的button就可以。之前在用Matlab写扫雷游戏的时候,也以前调用过讲述人来进行游戏的语音提示。

详细的Matlab脚本文件例如以下:

 sp=actxserver('SAPI.SpVoice');sp.Speak('你好,欢迎来到西安电子科技大学!

Hello,Welcome to XD University!')
       Qt调用讲述人,须要使用专门的类。详细能够參考http://lynxline.com/qtspeech-say-hello-world  一文。文中大致介绍了该类的用法。以下我就通过使用该类来实现讲述人的调用。
    首先建立一个dialog类型的gui项目。将上面所说的类QtSpeech类的头文件speech.h和源文件speech.cpp加入到project中。这样项目中就有5个文件:dialog.h、speech.h、main.cpp、dialog.cpp、speech.cpp。当然还有界面文件dialog.ui。

在界面文件里加入QTextEdit控件用于输入你要读取的文字,然后在其槽函数中加入QtSpeech的发音功能,加入QPushButton控件来控制发音。详细的各个文件源代码例如以下:

1、dialog.h

#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include"speech.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT public:
explicit Dialog(QWidget *parent = 0);
~Dialog(); private slots:
void on_pushButton_clicked();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H

2、speech.h

#ifndef SPEECH_H
#define SPEECH_H
#include <QObject>
class QtSpeech : public QObject {
Q_OBJECT
public:
// 处理异常情况
struct Error { QString msg; Error(QString s):msg(s) {} };
struct InitError : Error { InitError(QString s):Error(s) {} };
struct LogicError : Error { LogicError(QString s):Error(s) {} };
struct CloseError : Error { CloseError(QString s):Error(s) {} };
//定义数据类型
struct VoiceName { QString id; QString name; };
typedef QList<VoiceName> VoiceNames;
//定义构造函数
QtSpeech(QObject * parent);
QtSpeech(VoiceName n = VoiceName(), QObject * parent =0L);
virtual ~QtSpeech();
const VoiceName & name() const; //要读的内容
static VoiceNames voices(); //要读的内容
void say(QString) const; //同步发音
void tell(QString) const; //异步发音
void tell(QString, QObject * obj, const char * slot) const; //发音结束时,有停顿
/*******************/
void pause(void) const;//暂停
void resume(void) const;//从暂停中恢复
void stop(void) const;//停止发音
/******************/
signals:
void finished();
protected:
virtual void timerEvent(QTimerEvent *);
private:
class Private;
Private * d;
};
//}
#endif // SPEECH_H

3、main.cpp

#include <QApplication>
#include"dialog.h"
int main(int argc, char *argv[]){
QApplication app(argc, argv);
Dialog dlg;
dlg.show();
return app.exec();
}

4、dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_pushButton_clicked()
{
QtSpeech *speaker = new QtSpeech(this);
speaker->tell(ui->textEdit->toPlainText(),speaker,SLOT(onSpeechFinished()));
// speaker.stop();
}

5、speech.cpp

#include "speech.h"
#include <QString>
#include <QPointer>
#include <QList>
#include <QTimerEvent>
#undef UNICODE
#include <sapi.h>
#include <sphelper.h>
#include <comdef.h>
#define UNICODE
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
// some defines for throwing exceptions
#define Where QString("%1:%2:").arg(__FILE__).arg(__LINE__)
#define SysCall(x,e) {\
HRESULT hr = x;\
if (FAILED(hr)) {\
QString msg = #e;\
msg += ":"+QString(__FILE__);\
msg += ":"+QString::number(__LINE__)+":"+#x+":";\
msg += _com_error(hr).ErrorMessage();\
throw e(msg);\
}\
}
// internal data
class QtSpeech::Private {
public:
Private()
:onFinishSlot(0L),waitingFinish(false) {}
VoiceName name;
static const QString VoiceId;
typedef QPointer<QtSpeech> Ptr;
static QList<Ptr> ptrs;
CComPtr<ISpVoice> voice;
const char * onFinishSlot;
QPointer<QObject> onFinishObj;
bool waitingFinish;
class WCHAR_Holder {
public:
WCHAR * w;
WCHAR_Holder(QString s)
:w(0) {
w = new WCHAR[s.length()+1];
s.toWCharArray(w);
w[s.length()] =0;
}
~WCHAR_Holder() { delete[] w; }
};
};
const QString QtSpeech::Private::VoiceId = QString("win:%1");
QList<QtSpeech::Private::Ptr> QtSpeech::Private::ptrs = QList<QtSpeech::Private::Ptr>();
//类的定义
QtSpeech::QtSpeech(QObject * parent)
:QObject(parent), d(new Private)
{
CoInitialize(NULL);
SysCall( d->voice.CoCreateInstance( CLSID_SpVoice ), InitError);
VoiceName n;
WCHAR * w_id = 0L;
WCHAR * w_name = 0L;
CComPtr<ISpObjectToken> voice;
SysCall( d->voice->GetVoice(&voice), InitError);
SysCall( SpGetDescription(voice, &w_name), InitError);
SysCall( voice->GetId(&w_id), InitError);
n.name = QString::fromWCharArray(w_name);
n.id = QString::fromWCharArray(w_id);
voice.Release();
if (n.id.isEmpty())
throw InitError(Where+"No default voice in system");
d->name = n;
d->ptrs << this;
}
QtSpeech::QtSpeech(VoiceName n, QObject * parent)
:QObject(parent), d(new Private)
{
ULONG count = 0;
CComPtr<IEnumSpObjectTokens> voices;
CoInitialize(NULL);
SysCall( d->voice.CoCreateInstance( CLSID_SpVoice ), InitError);
if (n.id.isEmpty()) {
WCHAR * w_id = 0L;
WCHAR * w_name = 0L;
CComPtr<ISpObjectToken> voice;
SysCall( d->voice->GetVoice(&voice), InitError);
SysCall( SpGetDescription(voice, &w_name), InitError);
SysCall( voice->GetId(&w_id), InitError);
n.name = QString::fromWCharArray(w_name);
n.id = QString::fromWCharArray(w_id);
voice.Release();
}
else {
SysCall( SpEnumTokens(SPCAT_VOICES, NULL, NULL, &voices), InitError);
SysCall( voices->GetCount(&count), InitError);
for (int i =0; i< count; ++i) {
WCHAR * w_id = 0L;
CComPtr<ISpObjectToken> voice;
SysCall( voices->Next( 1, &voice, NULL ), InitError);
SysCall( voice->GetId(&w_id), InitError);
QString id = QString::fromWCharArray(w_id);
if (id == n.id) d->voice->SetVoice(voice);
voice.Release();
}
}
if (n.id.isEmpty())
throw InitError(Where+"No default voice in system");
d->name = n;
d->ptrs << this;
}
QtSpeech::~QtSpeech()
{
d->ptrs.removeAll(this);
delete d;
}
const QtSpeech::VoiceName & QtSpeech::name() const {
return d->name;
}
QtSpeech::VoiceNames QtSpeech::voices()
{
VoiceNames vs;
ULONG count = 0;
CComPtr<IEnumSpObjectTokens> voices;
CoInitialize(NULL);
SysCall( SpEnumTokens(SPCAT_VOICES, NULL, NULL, &voices), LogicError);
SysCall( voices->GetCount(&count), LogicError);
for(int i=0; i< count; ++i) {
WCHAR * w_id = 0L;
WCHAR * w_name = 0L;
CComPtr<ISpObjectToken> voice;
SysCall( voices->Next( 1, &voice, NULL ), LogicError);
SysCall( SpGetDescription(voice, &w_name), LogicError);
SysCall( voice->GetId(&w_id), LogicError);
QString id = QString::fromWCharArray(w_id);
QString name = QString::fromWCharArray(w_name);
VoiceName n = { id, name };
vs << n;
voice.Release();
}
return vs;
}
void QtSpeech::tell(QString text) const {
tell(text, 0L,0L);
}
void QtSpeech::tell(QString text, QObject * obj, const char * slot) const
{
if (d->waitingFinish)
throw LogicError(Where+"Already waiting to finish speech");
d->onFinishObj = obj;
d->onFinishSlot = slot;
if (obj && slot)
connect(const_cast<QtSpeech *>(this), SIGNAL(finished()), obj, slot);
d->waitingFinish = true;
const_cast<QtSpeech *>(this)->startTimer(100);
Private::WCHAR_Holder w_text(text);
SysCall( d->voice->Speak( w_text.w, SPF_ASYNC | SPF_IS_NOT_XML, 0), LogicError);
}
void QtSpeech::say(QString text) const
{
Private::WCHAR_Holder w_text(text);
SysCall( d->voice->Speak( w_text.w, SPF_IS_NOT_XML, 0), LogicError);
}
void QtSpeech::timerEvent(QTimerEvent * te)
{
QObject::timerEvent(te);
if (d->waitingFinish) {
SPVOICESTATUS es;
d->voice->GetStatus( &es, NULL );
if (es.dwRunningState == SPRS_DONE) {
d->waitingFinish = false;
killTimer(te->timerId());
finished();
}
}
}
/************************/
void QtSpeech::pause(void) const{//暂停
SysCall( d->voice->Pause(), LogicError);
}
void QtSpeech::resume() const{//恢复
SysCall(d->voice->Resume(), LogicError);
}
void QtSpeech::stop() const{//停止
SysCall(d->voice->Speak(NULL, SPF_PURGEBEFORESPEAK, 0), LogicError)
}
/***************************/
//}
程序结果例如以下:

基于Qt的词典开发系列

  1. 词典框架设计及成品展示
  2. 本地词典的设计
  3. 開始菜单的设计
  4. 无边框窗体的缩放与拖动
  5. 无边框窗体的拖动
  6. 界面美化设计
  7. 调用网络API
  8. 用户登录及API调用的实现
  9. JSON数据解析
  10. 国际音标的显示
  11. 系统托盘的显示
  12. 调用讲述人
  13. 音频播放
  14. 自己主动补全功能
  15. HTML特殊字符及正則表達式
  16. 后序
作品下载地址(公布版):http://download.csdn.net/detail/tengweitw/8548767
作品下载地址(绿色版):http://download.csdn.net/detail/tengweitw/8830495
源代码下载地址:http://download.csdn.net/detail/tengweitw/8830503

原文:http://blog.csdn.net/tengweitw/article/details/38306803

作者:nineheadedbird

【Qt程序】基于Qt词典开发系列&lt;十二&gt;呼叫讲述的更多相关文章

  1. BizTalk 开发系列(四十二) 为BizTalk应用程序打包不同的环境Binding

    我们在使用微软或者其他公司提供的BizTalk应用程序MSI包的时候经常会有一个目标环境的选择选项.该选项可以在不同的环境下使用不同的绑定(BizTalk应用程序配置)感觉很高级. 其实这个非常的简单 ...

  2. BizTalk开发系列(三十二)浅谈BizTalk主机性能优化

    很多BizTalk的项目都要考虑到性能优化的问题,虽然BizTalk采用多线程处理消息的,大大提高了程序效率.但默认情况下 BizTalk的主机有很多阻止参数会控制BizTalk对服务器的资源使用率, ...

  3. Chrome浏览器扩展开发系列之十二:Content Scripts

    Content Scripts是运行在Web页面的上下文的JavaScript文件.通过标准的DOM,Content Scripts 可以操作(读取并修改)浏览器当前访问的Web页面的内容. Cont ...

  4. Android商城开发系列(十二)—— 首页推荐布局实现

    首页新品推荐的布局效果如下图: 这块布局是使用LinearLayout和GridView去实现,新建recommend_item.xml,代码如下所示: <?xml version=" ...

  5. 【Qt编程】基于Qt的词典开发系列--后序

    从去年八月份到现在,总算完成了词典的编写以及相关技术文档的编辑工作.从整个过程来说,文档的编写比程序的实现耗费的时间更多.基于Qt的词典开发系列文章,大致包含了在编写词典软件过程中遇到的技术重点与难点 ...

  6. 【Qt编程】基于Qt的词典开发系列<三>--开始菜单的设计

    这篇文章讲讲如何实现开始菜单(或者称为主菜单)的设计.什么是开始菜单呢?我们拿常用的软件来用图例说明,大多数软件的开始菜单在左下角,如下图: 1.window 7的开始菜单 2.有道词典的主菜单 3. ...

  7. 【Qt编程】基于Qt的词典开发系列<二>--本地词典的设计

    我设计的词典不仅可以实现在线查单词,而且一个重大特色就是具有丰富的本地词典库:我默认加入了八个类型的词典,如下所示: 由于是本人是通信专业,因此加入了华为通信词典.电子工程词典,又由于我喜爱编程,也加 ...

  8. 【Qt编程】基于Qt的词典开发系列<十>--国际音标的显示

    在年前的一篇文章中,我提到要学习Qt.于是在这学期看了一个月的qt.现在大致对qt有了一些了解.但是现在导师又把我调到了android应用开发平台,所以说qt的学习要搁置了.本打算这学期做一个单词查询 ...

  9. 【Qt编程】基于Qt的词典开发系列<十二>调用讲述人

    我们知道,win7系统自带有讲述人,即可以机器读出当前内容,具体可以将电脑锁定,然后点击左下角的按钮即可.之前在用Matlab写扫雷游戏的时候,也曾经调用过讲述人来进行游戏的语音提示.具体的Matla ...

随机推荐

  1. Windows Forms 窗体篇

    1,显示窗体 非模式: Form form = new Form(); form.Show(); 模式: Form form = new Form(); form.Show(); 2,拥有者窗体与附属 ...

  2. C#泛型(一)泛型方法

    namespace GenericsTest { class Program { // https://www.cnblogs.com/dotnet261010/p/9034594.html stat ...

  3. (转)oracle 启动监听 报“监听程序不支持服务” 解决

    转自 http://www.51testing.com/html/99/478599-842622.html 今天安装了oracle后,启动监听,报错如下:    启动tnslsnr: 请稍候... ...

  4. 【Codeforces Round #450 (Div. 2) C】Remove Extra One

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举删除第i个数字. 想想删掉这个数字后会有什么影响? 首先,如果a[i]如果是a[1..i]中最大的数字 那么record会减少1 ...

  5. PatentTips - Resource partitioning and direct access utilizing hardware support for virtualization

    BACKGROUND The present disclosure relates to the resource management of virtual machine(s) using har ...

  6. [D3] Animate with the General Update Pattern in D3 v4

    In D3, the General Update Pattern is the name given to what happens when a data join is followed by ...

  7. 微信支付v2开发(4) 交易通知

    本文介绍如何使用JS API支付时如何获得交易通知. 一.交易通知 用户在成功完成支付后,微信后台通知(POST)商户服务器(notify_url)支付结果.商户可以使用notify_url的通知结果 ...

  8. HTTP详解--请求、响应、缓存

    1. HTTP请求格式 做过Socket编程的人都知道,当我们设计一个通信协议时,“消息头/消息体”的分割方式是很常用的,消息头告诉对方这个消息是干什么的,消息体告诉对方怎么干.HTTP协议传输的消息 ...

  9. Loadrunner--关联详解

    当录制脚本时,VuGen会拦截client端(浏览器)与server端(网站服务器)之间的对话,并且通通记录下来,产生脚本.在VuGen的Recording Log中,您可以找到浏览器与服务器之间所有 ...

  10. 微服务实战(六):选择微服务部署策略 - DockOne.io

    原文:微服务实战(六):选择微服务部署策略 - DockOne.io [编者的话]这篇博客是用微服务建应用的第六篇,第一篇介绍了微服务架构模板,并且讨论了使用微服务的优缺点.随后的文章讨论了微服务不同 ...