Python语音合成小工具(PyQt5 + pyttsx3)

news2024/11/27 10:29:36

TTS简介

TTS(Text To Speech)是一种语音合成技术,可以让机器将输入文本以语音的方式播放出来,实现机器说话的效果。

TTS分成语音处理及语音合成,先由机器识别输入的文字,再根据语音库进行语音合成。现在有很多可供调用的TTS接口,比如百度智能云的语音合成接口。微软在Windows系统中也提供了TTS的接口,可以调用此接口实现离线的TTS语音合成功能。

本文将使用pyttsx3库作为示范,编写一个语音合成小工具。

pyttsx3官方文档:https://pyttsx3.readthedocs.io 

本文源码已上传至GitHub:

https://github.com/XMNHCAS/SpeechSynthesisTool


安装需要的包

安装PyQt5及其GUI设计工具

# 安装PyQt5
pip install PyQt5

# 安装PyQt5设计器
pip install PyQt5Designer

本文使用的编辑器是VSCode,不是PyCharm,使用PyQt5的方式可能存在差异,具体使用时可以根据实际情况进行配置。 

安装pyttsx3

pip install pyttsx3

UI界面 

可参考下图设计简单的GUI界面,由于本文主要为功能实例,故不考虑界面美观问题。

界面应有一个文本输入框,用以输入将要转化为语音的文本,同时需要一个播放按钮,用以触发语音播放的方法。语速、音量和语言可以按需选择。 

使用PyQt5的设计工具,可以根据以上配置的GUI界面生成以下UI(XML)代码:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>313</width>
    <height>284</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>语音合成器</string>
  </property>
  <property name="windowIcon">
   <iconset>
    <normaloff>voice.ico</normaloff>voice.ico</iconset>
  </property>
  <widget class="QWidget" name="verticalLayoutWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>291</width>
     <height>261</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <property name="spacing">
     <number>20</number>
    </property>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <widget class="QLabel" name="label">
        <property name="text">
         <string>播报文本</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignJustify|Qt::AlignTop</set>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QTextEdit" name="tbx_text"/>
      </item>
     </layout>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_4">
      <item>
       <widget class="QLabel" name="label_3">
        <property name="text">
         <string>语速</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QSlider" name="slider_rate">
        <property name="maximum">
         <number>300</number>
        </property>
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLabel" name="label_rate">
        <property name="minimumSize">
         <size>
          <width>30</width>
          <height>0</height>
         </size>
        </property>
        <property name="text">
         <string>0</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignCenter</set>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_3">
      <item>
       <widget class="QLabel" name="label_2">
        <property name="text">
         <string>音量</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QSlider" name="slider_volumn">
        <property name="maximum">
         <number>100</number>
        </property>
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLabel" name="label_volumn">
        <property name="minimumSize">
         <size>
          <width>30</width>
          <height>0</height>
         </size>
        </property>
        <property name="text">
         <string>0</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignCenter</set>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QLabel" name="label_4">
        <property name="text">
         <string>选择语言</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QRadioButton" name="rbtn_zh">
        <property name="text">
         <string>中文</string>
        </property>
        <property name="checked">
         <bool>true</bool>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QRadioButton" name="rbtn_en">
        <property name="text">
         <string>英文</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_5">
      <item>
       <widget class="QLabel" name="label_5">
        <property name="minimumSize">
         <size>
          <width>60</width>
          <height>0</height>
         </size>
        </property>
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="btn_play">
        <property name="minimumSize">
         <size>
          <width>0</width>
          <height>30</height>
         </size>
        </property>
        <property name="text">
         <string>播放</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

最后再使用PyQt5的界面工具,可以根据以上UI的代码,生成以下的窗体类:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'd:\Program\VSCode\Python\TTS_PyQT\tts_form.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(313, 284)
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap("./voice.ico"),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        Form.setWindowIcon(icon)
        self.verticalLayoutWidget = QtWidgets.QWidget(Form)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 291, 261))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(20)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label.setAlignment(QtCore.Qt.AlignJustify | QtCore.Qt.AlignTop)
        self.label.setObjectName("label")
        self.horizontalLayout_2.addWidget(self.label)
        self.tbx_text = QtWidgets.QTextEdit(self.verticalLayoutWidget)
        self.tbx_text.setObjectName("tbx_text")
        self.horizontalLayout_2.addWidget(self.tbx_text)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.label_3 = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_4.addWidget(self.label_3)
        self.slider_rate = QtWidgets.QSlider(self.verticalLayoutWidget)
        self.slider_rate.setMaximum(300)
        self.slider_rate.setOrientation(QtCore.Qt.Horizontal)
        self.slider_rate.setObjectName("slider_rate")
        self.horizontalLayout_4.addWidget(self.slider_rate)
        self.label_rate = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label_rate.setMinimumSize(QtCore.QSize(30, 0))
        self.label_rate.setAlignment(QtCore.Qt.AlignCenter)
        self.label_rate.setObjectName("label_rate")
        self.horizontalLayout_4.addWidget(self.label_rate)
        self.verticalLayout.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.label_2 = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_3.addWidget(self.label_2)
        self.slider_volumn = QtWidgets.QSlider(self.verticalLayoutWidget)
        self.slider_volumn.setMaximum(100)
        self.slider_volumn.setOrientation(QtCore.Qt.Horizontal)
        self.slider_volumn.setObjectName("slider_volumn")
        self.horizontalLayout_3.addWidget(self.slider_volumn)
        self.label_volumn = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label_volumn.setMinimumSize(QtCore.QSize(30, 0))
        self.label_volumn.setAlignment(QtCore.Qt.AlignCenter)
        self.label_volumn.setObjectName("label_volumn")
        self.horizontalLayout_3.addWidget(self.label_volumn)
        self.verticalLayout.addLayout(self.horizontalLayout_3)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label_4 = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout.addWidget(self.label_4)
        self.rbtn_zh = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.rbtn_zh.setChecked(True)
        self.rbtn_zh.setObjectName("rbtn_zh")
        self.horizontalLayout.addWidget(self.rbtn_zh)
        self.rbtn_en = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.rbtn_en.setObjectName("rbtn_en")
        self.horizontalLayout.addWidget(self.rbtn_en)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.label_5 = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label_5.setMinimumSize(QtCore.QSize(60, 0))
        self.label_5.setText("")
        self.label_5.setObjectName("label_5")
        self.horizontalLayout_5.addWidget(self.label_5)
        self.btn_play = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.btn_play.setMinimumSize(QtCore.QSize(0, 30))
        self.btn_play.setObjectName("btn_play")
        self.horizontalLayout_5.addWidget(self.btn_play)
        self.verticalLayout.addLayout(self.horizontalLayout_5)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "语音合成器"))
        self.label.setText(_translate("Form", "播报文本"))
        self.label_3.setText(_translate("Form", "语速"))
        self.label_rate.setText(_translate("Form", "0"))
        self.label_2.setText(_translate("Form", "音量"))
        self.label_volumn.setText(_translate("Form", "0"))
        self.label_4.setText(_translate("Form", "选择语言"))
        self.rbtn_zh.setText(_translate("Form", "中文"))
        self.rbtn_en.setText(_translate("Form", "英文"))
        self.btn_play.setText(_translate("Form", "播放"))

如果直接复制此代码,可能会出现图标丢失的问题。这个需要根据实际情况修改icon的配置,并添加要使用的ico图标文件。 


功能代码

语音工具类

首先我们需要初始化并获取语音合成用的语音引擎对象。

# tts对象
engine = pyttsx3.init()

我们可以通过该对象的setProperty方法,对语音合成的对象的属性进行修改:

属性名解释
rate以每分钟字数表示的整数语速
volume音量,取值范围为[0.0, 1.0]
voices语音的字符串标识符

语音工具类代码如下,代码含义可参考注释:

import pyttsx3


class VoiceEngine():
    '''
    tts 语音工具类
    '''

    def __init__(self):
        '''
        初始化
        '''
        # tts对象
        self.__engine = pyttsx3.init()
        # 语速
        self.__rate = 150
        # 音量
        self.__volume = 100
        # 语音ID,0为中文,1为英文
        self.__voice = 0

    @property
    def Rate(self):
        '''
        语速属性
        '''
        return self.__rate

    @Rate.setter
    def Rate(self, value):
        self.__rate = value

    @property
    def Volume(self):
        '''
        音量属性
        '''
        return self.__volume

    @Volume.setter
    def Volume(self, value):
        self.__volume = value

    @property
    def VoiceID(self):
        '''
        语音ID:0 -- 中文;1 -- 英文
        '''

        return self.__voice

    @VoiceID.setter
    def VoiceID(self, value):
        self.__voice = value

    def Say(self, text):
        '''
        播放语音
        '''
        self.__engine.setProperty('rate', self.__rate)
        self.__engine.setProperty('volume', self.__volume)

        # 获取可用语音列表,并设置语音
        voices = self.__engine.getProperty('voices')
        self.__engine.setProperty('voice', voices[self.__voice].id)

        # 保存语音文件
        # self.__engine.save_to_file(text, 'test.mp3')

        self.__engine.say(text)
        self.__engine.runAndWait()
        self.__engine.stop()

窗体类

我们可以创建一个继承于我们刚刚创建的PyQt5的窗体类,并为窗体的拖拽事件和点击事件注册回调函数,同时创建一个语音工具类的实例,用以实现指定事件触发时需要执行的语音操作。

import sys
import _thread as th
from PyQt5.QtWidgets import QMainWindow, QApplication
from Ui_tts_form import Ui_Form

class MainWindow(QMainWindow, Ui_Form):
    '''
    窗体类
    '''

    def __init__(self, parent=None):
        '''
        初始化窗体
        '''
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        # 获取tts工具类实例
        self.engine = VoiceEngine()
        self.__isPlaying = False

        # 设置初始文本
        self.tbx_text.setText('床前明月光,疑似地上霜。\n举头望明月,低头思故乡。')

        # 进度条数据绑定到label中显示
        self.slider_rate.valueChanged.connect(self.setRateTextValue)
        self.slider_volumn.valueChanged.connect(self.setVolumnTextValue)

        # 设置进度条初始值
        self.slider_rate.setValue(self.engine.Rate)
        self.slider_volumn.setValue(self.engine.Volume)

        # RadioButton选择事件
        self.rbtn_zh.toggled.connect(self.onSelectVoice_zh)
        self.rbtn_en.toggled.connect(self.onSelectVoice_en)

        # 播放按钮点击事件
        self.btn_play.clicked.connect(self.onPlayButtonClick)

    def setRateTextValue(self):
        '''
        修改语速label文本值
        '''
        value = self.slider_rate.value()
        self.label_rate.setText(str(value))
        self.engine.Rate = value

    def setVolumnTextValue(self):
        '''
        修改音量label文本值
        '''
        value = self.slider_volumn.value()
        self.label_volumn.setText(str(value / 100))
        self.engine.Volume = value

    def onSelectVoice_zh(self):
        '''
        修改中文的语音配置及默认播放文本
        '''
        self.tbx_text.setText('床前明月光,疑似地上霜。\n举头望明月,低头思故乡。')
        self.engine.VoiceID = 0

    def onSelectVoice_en(self):
        '''
        修改英文的语音配置及默认的播放文本
        '''
        self.tbx_text.setText('Hello World')
        self.engine.VoiceID = 1

    def playVoice(self):
        '''
        播放
        '''

        if self.__isPlaying is not True:
            self.__isPlaying = True
            text = self.tbx_text.toPlainText()
            self.engine.Say(text)
            self.__isPlaying = False

    def onPlayButtonClick(self):
        '''
        播放按钮点击事件
        开启线程新线程播放语音,避免窗体因为语音播放而假卡死
        '''
        th.start_new_thread(self.playVoice, ())

完整代码

import sys
import _thread as th
from PyQt5.QtWidgets import QMainWindow, QApplication
from Ui_tts_form import Ui_Form
import pyttsx3


class VoiceEngine():
    '''
    tts 语音工具类
    '''

    def __init__(self):
        '''
        初始化
        '''
        # tts对象
        self.__engine = pyttsx3.init()
        # 语速
        self.__rate = 150
        # 音量
        self.__volume = 100
        # 语音ID,0为中文,1为英文
        self.__voice = 0

    @property
    def Rate(self):
        '''
        语速属性
        '''
        return self.__rate

    @Rate.setter
    def Rate(self, value):
        self.__rate = value

    @property
    def Volume(self):
        '''
        音量属性
        '''
        return self.__volume

    @Volume.setter
    def Volume(self, value):
        self.__volume = value

    @property
    def VoiceID(self):
        '''
        语音ID:0 -- 中文;1 -- 英文
        '''

        return self.__voice

    @VoiceID.setter
    def VoiceID(self, value):
        self.__voice = value

    def Say(self, text):
        '''
        播放语音
        '''
        self.__engine.setProperty('rate', self.__rate)
        self.__engine.setProperty('volume', self.__volume)
        voices = self.__engine.getProperty('voices')
        self.__engine.setProperty('voice', voices[self.__voice])

        # 保存语音文件
        # self.__engine.save_to_file(text, 'test.mp3')

        self.__engine.say(text)
        self.__engine.runAndWait()
        self.__engine.stop()


class MainWindow(QMainWindow, Ui_Form):
    '''
    窗体类
    '''

    def __init__(self, parent=None):
        '''
        初始化窗体
        '''
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        # 获取tts工具类实例
        self.engine = VoiceEngine()
        self.__isPlaying = False

        # 设置初始文本
        self.tbx_text.setText('床前明月光,疑似地上霜。\n举头望明月,低头思故乡。')

        # 进度条数据绑定到label中显示
        self.slider_rate.valueChanged.connect(self.setRateTextValue)
        self.slider_volumn.valueChanged.connect(self.setVolumnTextValue)

        # 设置进度条初始值
        self.slider_rate.setValue(self.engine.Rate)
        self.slider_volumn.setValue(self.engine.Volume)

        # RadioButton选择事件
        self.rbtn_zh.toggled.connect(self.onSelectVoice_zh)
        self.rbtn_en.toggled.connect(self.onSelectVoice_en)

        # 播放按钮点击事件
        self.btn_play.clicked.connect(self.onPlayButtonClick)

    def setRateTextValue(self):
        '''
        修改语速label文本值
        '''
        value = self.slider_rate.value()
        self.label_rate.setText(str(value))
        self.engine.Rate = value

    def setVolumnTextValue(self):
        '''
        修改音量label文本值
        '''
        value = self.slider_volumn.value()
        self.label_volumn.setText(str(value / 100))
        self.engine.Volume = value

    def onSelectVoice_zh(self):
        '''
        修改中文的语音配置及默认播放文本
        '''
        self.tbx_text.setText('床前明月光,疑似地上霜。\n举头望明月,低头思故乡。')
        self.engine.VoiceID = 0

    def onSelectVoice_en(self):
        '''
        修改英文的语音配置及默认的播放文本
        '''
        self.tbx_text.setText('Hello World')
        self.engine.VoiceID = 1

    def playVoice(self):
        '''
        播放
        '''

        if self.__isPlaying is not True:
            self.__isPlaying = True
            text = self.tbx_text.toPlainText()
            self.engine.Say(text)
            self.__isPlaying = False

    def onPlayButtonClick(self):
        '''
        修改语速label文本值
        '''
        th.start_new_thread(self.playVoice, ())


if __name__ == "__main__":
    '''
    主函数
    '''
    app = QApplication(sys.argv)
    form = MainWindow()
    form.show()
    sys.exit(app.exec_())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/51692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript -- 三种循环语句的介绍及示例代码

文章目录循环语句1 While循环2 do-while循环3 for循环4 嵌套循环循环语句 通过循环语句可以使指定的代码反复执行 JS中一共有三种循环语句 while语句do-while语句for语句 通常编写一个循环&#xff0c;要有三个要件 初始化表达式&#xff08;初始化变量&#xff09;条件表…

风云气象卫星系列介绍

风云气象卫星系列是中国于1977年开始研制的气象卫星系列&#xff0c;目前发射了风云一号、风云二号、风云三号、风云四号等卫星。 风云一号 FY-1卫星分为两个批次&#xff0c;各两颗星。01批的FY-1A星于1988年7月9日发射&#xff0c;FY-1B星于1990年9月3日发射。02批卫星在01批…

Word处理控件Aspose.Words功能演示:在 Java 中将 Word 文档转换为 EPUB

大多数智能设备&#xff0c;如智能手机、平板电脑、笔记本电脑等&#xff0c;都支持EPUB格式来查看或阅读文档。它是电子书或电子出版物的常用格式。另一方面&#xff0c;MS Word 格式&#xff0c;如DOCX、DOC等&#xff0c;是数字世界中广泛使用的文档格式之一。在本文中&…

Web3中文|NFT无法保障数字所有权?

来源 | nftnow 编译 | DaliiNFTnews.com 2021年&#xff0c;有这样一个头条新闻&#xff1a;一家投资公司以大约400万美元的价格在The Sandbox上买下了2000英亩的虚拟地产。 通过在以太坊区块链上购买792个NFT&#xff0c;该公司得到了元宇宙平台上的1200个城市街区。 但是…

家用宽带如何叠加多条宽带,提高局域网速度

前言 关于多条宽带如何合并&#xff0c;使局域网内带宽更快&#xff1f;通常我们在企业网络或实际项目中&#xff0c;随着用户的增加&#xff0c;一条或者几条带宽不能满足正常使用&#xff0c;便可以对带宽进行叠加&#xff0c;便于网络带度更快&#xff1b; 一、为什么要用…

web基础阶段的小兔鲜儿项目学习

小兔鲜儿1. 所用素材2. 项目文件介绍3. index页面的基本骨架4. 思路&#xff1a;先写外面大盒子和版心&#xff0c;由外往内写5. 源码&#xff1a;1. 所用素材 素材链接&#xff0c;点我跳转&#xff1a;https://download.csdn.net/download/angrynouse/87228151 2. 项目文件…

全国产!全志T3+Logos FPGA核心板(4核ARM Cortex-A7)规格书

核心板简介 创龙科技SOM-TLT3F是一款基于全志科技T3四核ARM Cortex-A7处理器 + 紫光同创Logos PGL25G/PGL50G FPGA设计的异构多核全国产工业核心板,ARM Cortex-A7处理单元主频高达1.2GHz。核心板CPU、FPGA、ROM、RAM、电源、晶振、连接器等所有器件均采用国产工业级方案,国产…

【HDU No. 4902】 数据结构难题 Nice boat

【HDU No. 4902】 数据结构难题 Nice boat 杭电OJ 题目地址 【题意】 有n 个数字a 1 , a 2 , …, an &#xff0c;每次都可以将[l , r ]区间的每个数字都更改为数字x &#xff08;类型1&#xff09;&#xff0c;或将[l ,r ]区间每个大于x 的ai 都更改为最大公约数gcd(ai , x …

云服务连续三年增长150%,网宿科技开拓新赛道

摘要&#xff1a;开拓云服务市场&#xff0c;网宿科技的打法。 提到网宿科技&#xff0c;很多人还停留在传统IT服务商的印象中。其实&#xff0c;网宿科技已经在一条新赛道加速前行&#xff0c;这就是云服务。 “借助亚马逊云科技的持续赋能&#xff0c;网宿科技积累了丰富的云…

swiper轮播图片+视频播放,预览及页面跳转功能

1.效果 2.上代码 <template> <swiper :circulartrue indicator-dots"true" change"changeSwiper" :autoplay"true" interval5000 classswiper-view><swiper-item class"swiper-img" v-for"(item,index) in swipe…

2022 CMU15-445 Project0 Trie

通过截图 在线测试 本地测试 总览 代码风格 我们的代码必须遵循 Google C Style Guide。在线检测网站使用 Clang 自动检查源代码的质量。如果我们的提交未通过任何这些检查&#xff0c;您的项目成绩将为零。 对于 Google C Style Guide &#xff0c;我们可以看这里 google-s…

Spring Boot Logback启动流程

Spring Boot 默认使用的是 Logback 的日志框架、Logback 的组件主要通过 Spring Boot ApplicationListener 启动的 // LoggingApplicationListener Override public void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationStartingEvent) {onApp…

测试工作中的测试用例设计

测试工作中的测试用例设计 测试工作的最核心的模块&#xff0c;在执行任何测试之前&#xff0c;首先必须完成测试用例的编写。测试用例是指导你执行测试&#xff0c;帮助证明软件功能或发现软件缺陷的一种说明。 进行用例设计&#xff0c;需要对项目的需求有清晰的了解&#xf…

Excel找回打开密码过程

Excel文件设置了打开密码&#xff0c;但是忘记了打开密码或者不知道这份文件的打开密码都没办法打开excel文件了。可是文件的打开密码&#xff0c;一旦忘记了&#xff0c;想要再打开文件&#xff0c;都是需要找回密码的。网上的一些绕过密码、直接删除密码都是无效的解决方法。…

C# 文件压缩解压与sqlite存储文件数据

文章目录环境压缩nugetUI代码资源链接&#xff08;下载地址&#xff09;ZipFile 类方法环境 .netframerwork4.8sqlite3 压缩 nuget <package id"System.IO.Compression" version"4.3.0" targetFramework"net48" /><package id"…

四嗪-五聚乙二醇-羧基,1682653-79-7,Tetrazine-PEG5-COOH 水溶性和稳定性怎么样?

●中文名&#xff1a;四嗪-五聚乙二醇-羧基 ●英文&#xff1a;Tetrazine-PEG5-COOH ●外观以及性质&#xff1a;Tetrazine-PEG5-COOH为红色固体&#xff0c;四嗪目前被广泛应用于蛋白质特定位点功能阐释、亚细胞结构选择性标记。四嗪PEG衍生物用于与 TCO&#xff08;反式环辛烯…

【Linux初阶】操作系统概念与定位 | 操作系统管理硬件方法、系统调用和库函数概念

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux初阶】 ✒️✒️本篇内容&#xff1a;操作系统的基础概念、设计OS的目的&#xff0c;操作系统的定位&#xff0c;操作系统管理硬件方法&#xff0c;…

【正厚软件干货】我推荐你的入门编程语言选python

By——正厚技术极客陈多多 当友友看到这篇文章的时候&#xff0c;心里一定有一个学习编程的想法&#xff0c;但是又不知道挑选哪个作为入门语言&#xff01;我写这篇文章就是为了帮有困难的你做出选择&#xff01;&#xff08;作者本人有选择困难症&#xff0c;当时也纠结了好久…

图神经网络关系抽取论文阅读笔记(五)

1 依赖驱动的注意力图卷积网络关系抽取方法&#xff08;Dependency-driven Relation Extractionwith Attentive Graph Convolutional Networks&#xff09; 论文&#xff1a;Dependency-driven Relation Extraction with Attentive Graph Convolutional Networks.ACL 2021 1.1 …

Win11系统禁止关机键关机的方法教学

Win11系统禁止关机键关机的方法教学。在操作电脑的时候&#xff0c;有用户经常出现自己误触关键按键导致电脑关机的情况。对于这个情况&#xff0c;我们可以去开启电脑禁止关机按键关机的设置。这样就可以不用担心误触导致关机的问题了。一起看看设置的方法吧。 操作方法&#…