【Qt程序】基于Qt词典开发系列<十二>呼叫讲述
我们知道,win7系统自带有讲述人,即能够机器读出当前内容,详细能够将电脑锁定。然后点击左下角的button就可以。之前在用Matlab写扫雷游戏的时候,也以前调用过讲述人来进行游戏的语音提示。
详细的Matlab脚本文件例如以下:
sp=actxserver('SAPI.SpVoice');sp.Speak('你好,欢迎来到西安电子科技大学! Hello,Welcome to XD University!')
在界面文件里加入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的词典开发系列
- 词典框架设计及成品展示
- 本地词典的设计
- 開始菜单的设计
- 无边框窗体的缩放与拖动
- 无边框窗体的拖动
- 界面美化设计
- 调用网络API
- 用户登录及API调用的实现
- JSON数据解析
- 国际音标的显示
- 系统托盘的显示
- 调用讲述人
- 音频播放
- 自己主动补全功能
- HTML特殊字符及正則表達式
- 后序
原文:http://blog.csdn.net/tengweitw/article/details/38306803
作者:nineheadedbird
【Qt程序】基于Qt词典开发系列<十二>呼叫讲述的更多相关文章
- BizTalk 开发系列(四十二) 为BizTalk应用程序打包不同的环境Binding
我们在使用微软或者其他公司提供的BizTalk应用程序MSI包的时候经常会有一个目标环境的选择选项.该选项可以在不同的环境下使用不同的绑定(BizTalk应用程序配置)感觉很高级. 其实这个非常的简单 ...
- BizTalk开发系列(三十二)浅谈BizTalk主机性能优化
很多BizTalk的项目都要考虑到性能优化的问题,虽然BizTalk采用多线程处理消息的,大大提高了程序效率.但默认情况下 BizTalk的主机有很多阻止参数会控制BizTalk对服务器的资源使用率, ...
- Chrome浏览器扩展开发系列之十二:Content Scripts
Content Scripts是运行在Web页面的上下文的JavaScript文件.通过标准的DOM,Content Scripts 可以操作(读取并修改)浏览器当前访问的Web页面的内容. Cont ...
- Android商城开发系列(十二)—— 首页推荐布局实现
首页新品推荐的布局效果如下图: 这块布局是使用LinearLayout和GridView去实现,新建recommend_item.xml,代码如下所示: <?xml version=" ...
- 【Qt编程】基于Qt的词典开发系列--后序
从去年八月份到现在,总算完成了词典的编写以及相关技术文档的编辑工作.从整个过程来说,文档的编写比程序的实现耗费的时间更多.基于Qt的词典开发系列文章,大致包含了在编写词典软件过程中遇到的技术重点与难点 ...
- 【Qt编程】基于Qt的词典开发系列<三>--开始菜单的设计
这篇文章讲讲如何实现开始菜单(或者称为主菜单)的设计.什么是开始菜单呢?我们拿常用的软件来用图例说明,大多数软件的开始菜单在左下角,如下图: 1.window 7的开始菜单 2.有道词典的主菜单 3. ...
- 【Qt编程】基于Qt的词典开发系列<二>--本地词典的设计
我设计的词典不仅可以实现在线查单词,而且一个重大特色就是具有丰富的本地词典库:我默认加入了八个类型的词典,如下所示: 由于是本人是通信专业,因此加入了华为通信词典.电子工程词典,又由于我喜爱编程,也加 ...
- 【Qt编程】基于Qt的词典开发系列<十>--国际音标的显示
在年前的一篇文章中,我提到要学习Qt.于是在这学期看了一个月的qt.现在大致对qt有了一些了解.但是现在导师又把我调到了android应用开发平台,所以说qt的学习要搁置了.本打算这学期做一个单词查询 ...
- 【Qt编程】基于Qt的词典开发系列<十二>调用讲述人
我们知道,win7系统自带有讲述人,即可以机器读出当前内容,具体可以将电脑锁定,然后点击左下角的按钮即可.之前在用Matlab写扫雷游戏的时候,也曾经调用过讲述人来进行游戏的语音提示.具体的Matla ...
随机推荐
- VC6.0调试知识大全
VC6.0调试知识大全 分类: C++ 2010-09-06 21:33 7080人阅读 评论(5) 收藏 举报 debuggingmfcfunctionmenumicrosoftdll My Not ...
- MYSQL添加远程用户或允许远程访问三种方法
添加远程用户admin密码为password GRANT ALL PRIVILEGES ON *.* TO admin@localhost IDENTIFIED BY \'password\' WIT ...
- DB2 概览
2006:IBM公布DB2.9.将数据库领域带入XML时代.IT建设业已进入SOA(Service-Oriented Architecture)时代.实现SOA.其核心难点是顺畅解决不同应用间的数据交 ...
- amazeui学习笔记--css(常用组件2)--面包屑导航Breadcrumb
amazeui学习笔记--css(常用组件2)--面包屑导航Breadcrumb 一.总结 1.am-breadcrumb:用am-breadcrumb来声明面包屑导航控件,.am-breadcrum ...
- 逻辑与和逻辑或:&& 、||
逻辑或:首先看左边是真还是假(除了那5个都是真),如果为真,返回左边值,如果为假,返回右边的值 逻辑与:和逻辑或相同,先看左边的值是真是假,如果左边为真返回右边的值,左边为假返回左边的值 在两者同时出 ...
- msys 中打开系统程序
按照msys 后发现sh自带的vim不好用,下载安装了个gvim,在etc/profile中作如下设置: alias gvim="D:/Program\ Files/Vim/vim73/gv ...
- 使用PHP实现双向队列
使用PHP实现双向队列 一.总结 就是几个array函数 push pop shift unshift n. 移动:变化:手段:轮班 vi. 移动:转变:转换 vt. 转移:改变:替换 二.使用PHP ...
- stm32的串口中断
下面有很多问题没有验证: 在设置USART_CR1中的TE位时,会发送一个空闲帧作为第一次数据发送, 目前我所了解的串口中断发送,有两种方式: 一个是:TC 一个是:TXE 这是判断两个标志位, 第一 ...
- 10.3、android输入系统_必备Linux编程知识_任意进程双向通信(scoketpair+binder)
3. 任意进程间通信(socketpair_binder) 进程每执行一次open打开文件,都会在内核中有一个file结构体表示它: 对每一个进程在内核中都会有一个task_struct表示进程,这个 ...
- OC学习篇之---Foundation框架中的NSArray类和NSMutableArray类
我们继续来看一下Foundation框架中的NSArray类和NSMutableArray类,其实NSArray类和Java中的List差不多,算是一种数据结构,当然我们从这两个类可以看到,NSArr ...