【Qt编程】基于Qt的词典开发系列<十二>调用讲述人
来源:互联网 发布:手机看报纸软件 编辑:程序博客网 时间:2024/05/21 07:58
我们知道,win7系统自带有讲述人,即可以机器读出当前内容,具体可以将电脑锁定,然后点击左下角的按钮即可。之前在用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添加到工程中,这样项目中就有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_H2、speech.h
#ifndef SPEECH_H#define SPEECH_H#include <QObject>class QtSpeech : public QObject { Q_OBJECTpublic: // 处理异常情况 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 dataclass 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://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
0 0
- 【Qt编程】基于Qt的词典开发系列<十二>调用讲述人
- 【Qt编程】基于Qt的词典开发系列--后序
- 【Qt编程】基于Qt的词典开发系列<八>--用户登录及API调用的实现
- 【Qt编程】基于Qt的词典开发系列<七>--调用网络API
- 【Qt编程】基于Qt的词典开发系列<二>--本地词典的设计
- 【Qt编程】基于Qt的词典开发系列<一>--词典框架设计及成品展示
- 【Qt编程】基于Qt的词典开发系列<十>--国际音标的显示
- 【Qt编程】基于Qt的词典开发系列<十一>系统托盘的显示
- 【Qt编程】基于Qt的词典开发系列<四>--无边框窗口的缩放与拖动
- 【Qt编程】基于Qt的词典开发系列<五>--无边框窗口的拖动
- 【Qt编程】基于Qt的词典开发系列<三>--开始菜单的设计
- 【Qt编程】基于Qt的词典开发系列<十三>音频播放
- 【Qt编程】基于Qt的词典开发系列<十四>自动补全功能
- 【Qt编程】基于Qt的词典开发系列<十五>html特殊字符及正则表达式
- 【Qt编程】基于Qt的词典开发系列<六>--界面美化设计
- 【Qt编程】基于Qt的词典开发系列<九>--JSON数据解析
- 基于Qt的sqlite编程
- qt学习之路十二(基于Windows qt的聊天室)
- Linux下的输入/输出重定向
- 用工厂方法(Factory Method)和 单例模式(Singleton)实现抽象工厂(Abstract Factory)
- UVa 164 - String Computer
- 百度员工离职总结:如何做个好员工
- Android网络连接判断与处理
- 【Qt编程】基于Qt的词典开发系列<十二>调用讲述人
- C++中 vector结合迭代器实现增删操作!
- hybrid app
- HELP!!!混乱+迷茫+懒惰的我
- JAVA 中的 char, byte
- java interface
- 胜利大逃亡
- c++:primer plus 源代码
- The Great Pan