【QT】TXT电子书语音朗读器开发
【QT】TXT电子书语音朗读器开发
- 前言
- 需求实现
- 文本读取
- 按钮焦点转移
- 语音朗读
- 效果
前言
在电脑上看电子书时候,用Notepad、记事本等打开查看多有不便,考虑开发一个小型软件可以按行查看文档。而在使用过程中,能够进行页码跳转、页码保存也很有必要,否则每次都重头开始看很不方便。而且有时候在不同平台看了文档一部分,当用户在客户端上想继续看,此时内容查找也很有必要。经常性的点击按钮,鼠标声音很吵闹,此时按钮随着鼠标移动焦点转移也很有必要。前台直接查看内容有时不方便,配合按钮焦点灵活移动,以及空格按键,以实现后台页面切换,同时有语音朗读,解决后台无法查看的问题。
基于以上的需求以及使用过程中的场景描述,最终软件1.0功能需求如下:
- 可按行查看文档;
- 可进行页面跳转;
- 可进行页面保存,下次打开直接显示之前记录;
- 可进行内容查看;
- 可随着鼠标移动进行按钮焦点转移;
- 有语音朗读功能。
需求实现
以上需求实现相对较为简单,在实现过程中,建议trimmed()
进行字符串的去空,增加用户使用体验。以下对重点需求实现进行介绍,主要包括文本读取、按钮焦点转移、语音朗读功能实现3部分。
文本读取
文件的读取在本客户端中主要采用QFile
类实现,以只读形式打开,然后按行存到变量中,后续以页码的形式进行每个元素的获取,页码排序从0开始。
QFile *m_file = new QFile("C:/Users/11003189/Downloads/bj.txt");if (!m_file->open(QIODevice::ReadOnly | QIODevice::Text)) {QMessageBox::critical(this, "错误", "无法打开文件: " + m_file->errorString());return;}QTextStream *m_textStream = new QTextStream(m_file);while (!m_textStream->atEnd()) {m_lines.append(m_textStream->readLine());}if (m_lines.isEmpty()) {QMessageBox::information(this, "提示", "文件为空");return;}
当然也可以兼容其他格式的文件,以及自定义文件,可以采用QFileDialog
去实现,定义一个按钮,取名浏览,然后点击调用这个类以实现功能。
fileAddress = QFileDialog::getOpenFileName(this, u8"打开文件", QDir::currentPath(), u8"任意文件 (*.*)");if(fileAddress.isEmpty()) {QMessageBox::warning(this, tr("!!!"), tr("文件选择为空!"));return;}
按钮焦点转移
按钮焦点转移主要安装事件过滤器时筛选的方式进行实现,对需要控制的按钮安装过滤器,然后对过滤器方法进行复写,实现焦点转移。
ui->befor->installEventFilter(this);ui->pushButton->installEventFilter(this);ui->pushButton_2->installEventFilter(this);ui->pushButton_3->installEventFilter(this);
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{if(event->type() ==QEvent::Enter){QPushButton *bt=qobject_cast<QPushButton*>(obj);if(bt){bt->setFocus();return true;}}return QMainWindow::eventFilter(obj,event);
}
这里要注意,由于是复写,头函数中方法定义是bool eventFilter(QObject *obj, QEvent *event) override;
,必须要加override。其次因为创建的客户端继承QMainWindow
,因此默认调用的是QMainWindow::eventFilter(obj,event);
,如果客户端继承QDialog
,此处应该是QDialog::eventFilter(obj,event);
。
语音朗读
语音朗读采用QT官方的QTextToSpeech
类实现,由于是第一次用这个类,最初以为实现该功能会用到第三方的库,结果官方有,那调用方便很多,只需要QT += texttospeech
进行库的导入即可。在使用过程中,要注意QT5和QT6的方法使用还是有些区别的,部分方法不能使用,这里建议根据对应使用的QT版本去进行方法查看,本博文使用的QT5.11.2。在进行客户端功能实现前,可先进行demo的编写。
// 创建文本转语音对象QTextToSpeech *speech = new QTextToSpeech(&window);// 创建按钮触发语音QPushButton *speakButton = new QPushButton("朗诵文本", &window);layout.addWidget(speakButton);QVoice chineseVoice;for (const QVoice &voice : speech->availableVoices()) {qDebug()<<voice.name();}QLocale englocale;for(const QLocale &lc:speech->availableLocales()){if(lc.name()=="en_US"){englocale=lc;}qDebug()<<lc.nativeCountryName()<<lc.nativeLanguageName()<<lc.name()<<lc.country();}speech->setLocale(englocale);// 连接按钮点击事件到语音朗诵QObject::connect(speakButton, &QPushButton::clicked, [=]() {speech->say("Hello EVeryone");});speech->say("你好呀,大家");
使用过程中,如果不定义语言类型,是会自定义进行中英文切换的,但如果定义了中英文,那么中文的内容是不能进行英文朗诵的,否则的话,中文内容中文朗诵,英文内容英文朗诵。在demo中,用speech->setLocale(englocale);
来进行语音类型的自定义,用speech->availableLocales()
来进行可支持语音类型的输出。以上输出结果如下:
可支持简体中文和英文2种,分别用zh_CN
和en_US
命名,在进行过滤区分时候可以进行命名区分。用demo完成熟悉,客户端中直接采用默认自动切换的方式进行设计,以实现语音朗读功能。
speech = new QTextToSpeech(this);
QString ct=m_lines[--m_currentLine>0?m_currentLine:0].trimmed();
speech->say(ct);
效果
最终界面设计如下,可以完美实现以上功能,而且如果后续有自定义需求也可以对应增加。为了方便安装使用,可以用Inno Setup Compiler进行打包,这个在之前的博文【QT】自动更新库QSimpleUpdater使用实例封装也已经进行描述。