Skip to content
On this page

QT语音播报闹钟


标签:代码片段CPP/QT  
cpp
#include <QApplication>
#include <QPushButton>
#include "mainwindow.h"

int main(int argc, char *argv[]) {
  QApplication a(argc, argv);
  MainWindow w;
  w.show();
  return QApplication::exec();
}
cpp
#ifndef HOMEWORK_MAINWINDOW_H
#define HOMEWORK_MAINWINDOW_H

#include <QWidget>
#include <QEvent>
#include <QMessageBox>
#include <QtTextToSpeech/QtTextToSpeech>


QT_BEGIN_NAMESPACE
namespace Ui {
  class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QWidget {
  Q_OBJECT

public:
  explicit MainWindow(QWidget *parent = nullptr);
  ~MainWindow() override;

private:
  Ui::MainWindow *ui;
  QTextToSpeech *tts;
  bool countdown_flag; // 是否在倒计时状态
  bool inspeech_flag;  // 是否在播报状态
  int clock_id;  // 时钟定时器的 id
  int count_id;  // 倒计时定时器的 id
  void timerEvent(QTimerEvent *event) override;

public slots:
  void onStartBtnClicked();
  void onStopBtnClicked();
};


#endif//HOMEWORK_MAINWINDOW_H
cpp
#include "mainwindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent) :
      QWidget(parent), ui(new Ui::MainWindow),
      countdown_flag(false), inspeech_flag(false) {

  this->clock_id = this->startTimer(1000);
  tts = new QTextToSpeech(this);
  tts->setLocale(QLocale::Chinese);
  ui->setupUi(this);

  ui->timeEdit->setDisplayFormat("yyyy-MM-dd HH:mm:ss");
  ui->timeEdit->setAlignment(Qt::AlignCenter);
  // 给 TimeEdit 设置当前时间
  ui->timeEdit->setCalendarPopup(true);
  ui->timeEdit->setMinimumDate(QDate::currentDate());
  ui->timeEdit->setTime(QTime::currentTime());
  // 给按钮设置初始状态
  ui->stopBtn->setEnabled(false);
  // 给按钮点击绑定槽函数
  connect(ui->startBtn, &QPushButton::clicked, this, &MainWindow::onStartBtnClicked);
  connect(ui->stopBtn, &QPushButton::clicked, this, &MainWindow::onStopBtnClicked);
}

MainWindow::~MainWindow() {
  delete ui;
}

void MainWindow::onStartBtnClicked() {
  // 获取倒计时的时间
  QTime t = ui->timeEdit->time();
  if (t < QTime::currentTime()) {
    QMessageBox::warning(this, "警告", "倒计时时间不能小于当前时间");
    return;
  }// else...
  // 设置倒计时标志
  this->countdown_flag = true;
  ui->startBtn->setEnabled(false);
  ui->stopBtn->setEnabled(true);
  ui->timeEdit->setEnabled(false);
  ui->textEdit->setEnabled(false);
  // 开始倒计时
  this->count_id = this->startTimer(1000);
}

void MainWindow::onStopBtnClicked() {
  // 停止倒计时
  this->killTimer(this->count_id);
  this->count_id = 0;
  // 恢复按钮状态
  ui->startBtn->setEnabled(true);
  ui->stopBtn->setEnabled(false);
  ui->timeEdit->setEnabled(true);
  ui->textEdit->setEnabled(true);
  // 恢复时钟
  this->countdown_flag = false;
}

void MainWindow::timerEvent(QTimerEvent *event) {
  QTime now = QTime::currentTime();
  if (event->timerId() == clock_id) { // 每秒都会执行
      // 如果不在倒计时状态就刷新显示时间
      if (!countdown_flag) {
         QString t_str = now.toString("hh:mm:ss");
         ui->timeLabel->setText(t_str);
       }
      // 如果在播报状态但播报已经结束,切换状态
      if (inspeech_flag && QTextToSpeech::Speaking != tts->state()) {
          inspeech_flag = false;
          // 恢复按钮状态
          ui->startBtn->setEnabled(true);
          ui->stopBtn->setEnabled(false);
          ui->timeEdit->setEnabled(true);
          ui->textEdit->setEnabled(true);
          // 恢复时钟
          this->countdown_flag = false;
      }
  } else if (event->timerId() == count_id) {
    QTime t = ui->timeEdit->time();
    if (now >= t) {
      // 倒计时结束
      this->killTimer(this->count_id);
      this->count_id = 0;
      // 播放语音
      QString text = ui->textEdit->toPlainText();
      tts->say(text);
      this->inspeech_flag = true;
    } else {
      // 倒计时未结束
      int secs = QTime::currentTime().secsTo(ui->timeEdit->time());
      QString secs_str = QString::number(secs);
      ui->timeLabel->setText("倒计时:" + secs_str);
    }
  }
}
html
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QWidget" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>916</width>
    <height>542</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QLabel" name="timeLabel">
   <property name="geometry">
    <rect>
     <x>60</x>
     <y>50</y>
     <width>371</width>
     <height>131</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>微软雅黑</family>
     <pointsize>35</pointsize>
     <weight>75</weight>
     <bold>true</bold>
    </font>
   </property>
   <property name="styleSheet">
    <string notr="true">border: 1px solid #ddd;</string>
   </property>
   <property name="text">
    <string/>
   </property>
  </widget>
  <widget class="QDateTimeEdit" name="timeEdit">
   <property name="geometry">
    <rect>
     <x>460</x>
     <y>50</y>
     <width>401</width>
     <height>61</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>文泉驿等宽微米黑</family>
     <pointsize>16</pointsize>
    </font>
   </property>
  </widget>
  <widget class="QPushButton" name="startBtn">
   <property name="geometry">
    <rect>
     <x>460</x>
     <y>130</y>
     <width>191</width>
     <height>51</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>文泉驿等宽微米黑</family>
     <pointsize>20</pointsize>
    </font>
   </property>
   <property name="cursor">
    <cursorShape>PointingHandCursor</cursorShape>
   </property>
   <property name="text">
    <string>开始</string>
   </property>
  </widget>
  <widget class="QPushButton" name="stopBtn">
   <property name="geometry">
    <rect>
     <x>670</x>
     <y>130</y>
     <width>191</width>
     <height>51</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>文泉驿等宽微米黑</family>
     <pointsize>20</pointsize>
    </font>
   </property>
   <property name="cursor">
    <cursorShape>PointingHandCursor</cursorShape>
   </property>
   <property name="text">
    <string>停止</string>
   </property>
   <property name="icon">
    <iconset theme="start">
     <normaloff>.</normaloff>.</iconset>
   </property>
   <property name="checkable">
    <bool>false</bool>
   </property>
   <property name="checked">
    <bool>false</bool>
   </property>
  </widget>
  <widget class="QTextEdit" name="textEdit">
   <property name="geometry">
    <rect>
     <x>60</x>
     <y>210</y>
     <width>801</width>
     <height>301</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>文泉驿等宽微米黑</family>
     <pointsize>16</pointsize>
    </font>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
yaml
QT       += core gui texttospeech

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

Last updated: