├── img ├── logo.ico ├── main1.png ├── main2.png ├── input1.png ├── workspace1.png └── delete_dataset.png ├── requirements.txt ├── .gitignore ├── PyAudio-0.2.11-cp39-cp39-win_amd64.whl ├── global_obj.py ├── test.py ├── ui ├── wait.ui ├── ui_wait.py ├── main.ui ├── inputdata.ui ├── ui_main.py ├── ui_inputdata.py ├── guiclass.py ├── ui_gui.py └── gui.ui ├── main.py ├── README.md └── utils.py /img/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kslz/SoundLabel/HEAD/img/logo.ico -------------------------------------------------------------------------------- /img/main1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kslz/SoundLabel/HEAD/img/main1.png -------------------------------------------------------------------------------- /img/main2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kslz/SoundLabel/HEAD/img/main2.png -------------------------------------------------------------------------------- /img/input1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kslz/SoundLabel/HEAD/img/input1.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kslz/SoundLabel/HEAD/requirements.txt -------------------------------------------------------------------------------- /img/workspace1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kslz/SoundLabel/HEAD/img/workspace1.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /介绍/ 2 | *.srt 3 | *.wav 4 | .idea 5 | /test 6 | /build 7 | /dist 8 | /filepath/output -------------------------------------------------------------------------------- /img/delete_dataset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kslz/SoundLabel/HEAD/img/delete_dataset.png -------------------------------------------------------------------------------- /PyAudio-0.2.11-cp39-cp39-win_amd64.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kslz/SoundLabel/HEAD/PyAudio-0.2.11-cp39-cp39-win_amd64.whl -------------------------------------------------------------------------------- /global_obj.py: -------------------------------------------------------------------------------- 1 | """ 神奇的全局变量 """ 2 | def _init(): 3 | global _global_dict 4 | _global_dict = {} 5 | 6 | def set_value(key,value): 7 | """ 定义一个全局变量 """ 8 | _global_dict[key] = value 9 | 10 | def get_value(key,defValue=None): 11 | """ 获取一个全局变量,不存在则返回默认值 """ 12 | try: 13 | return _global_dict[key] 14 | except KeyError: 15 | return defValue 16 | 17 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | from pydub.playback import play 2 | 3 | from utils import AllSound, MySound 4 | 5 | jr1_allsound = AllSound("./filepath/jr1.wav") 6 | info_dict ={ 7 | "text":"你好", 8 | "start":10500, 9 | "end":13700, 10 | "checked":0, 11 | "can_use":0, 12 | "file_name":"jr1.wav", 13 | "all_sound":jr1_allsound.sound 14 | } 15 | 16 | short_sound = MySound(info_dict) 17 | print(len(short_sound.sound)) 18 | play(short_sound.sound) 19 | -------------------------------------------------------------------------------- /ui/wait.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | widget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | 加载中 15 | 16 | 17 | 18 | 19 | 20 | 21 | 16 22 | 23 | 24 | 25 | 加载中,请稍等 26 | 27 | 28 | Qt::AlignCenter 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from PySide6.QtWidgets import QApplication 4 | 5 | import global_obj 6 | from ui import guiclass 7 | from utils import dictdir, LiteDB, check_mkdir 8 | from threading import Thread 9 | 10 | 11 | def main(): 12 | global_obj._init() 13 | 14 | db_path = "db/data.db" 15 | file_dict_path = "filepath/" 16 | sound_type = ["wav", "mp3", "aac"] 17 | 18 | # 读取文件路径 19 | check_mkdir(file_dict_path) 20 | srt_file_dict = {} 21 | file_dict = {} 22 | dictdir(file_dict_path, srt_file_dict, "srt") 23 | dictdir(file_dict_path, file_dict, "") 24 | global sound_dict 25 | sound_dict = get_sound_dict(srt_file_dict, file_dict, sound_type) 26 | # print(sound_dict) 27 | db = LiteDB() 28 | global_obj.set_value("sound_dict", sound_dict) 29 | global_obj.set_value("db", db) 30 | global_obj.set_value("sound_type",sound_type) 31 | 32 | # sqlite的对象不能在别的线程里用,先不用了 33 | # gui_thread = Thread(target=guiclass.main) 34 | # gui_thread.start() 35 | # gui_thread.join() 36 | guiclass.main() 37 | print("GUI已关闭") 38 | db.close() 39 | 40 | 41 | 42 | 43 | def get_sound_dict(srt_file_dict, file_dict, sound_type): 44 | sound_dict = {} 45 | for srt_file in srt_file_dict.keys(): 46 | sound_path = "" 47 | for type in sound_type: 48 | sound_file = srt_file.replace(".srt", "." + type) 49 | # print(sound_file) 50 | if sound_file in file_dict: 51 | sound_path = file_dict[sound_file] 52 | break 53 | sound_dict[srt_file.replace(".srt", "")] = (srt_file_dict[srt_file], sound_path) 54 | return sound_dict 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /ui/ui_wait.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ################################################################################ 4 | ## Form generated from reading UI file 'wait.ui' 5 | ## 6 | ## Created by: Qt User Interface Compiler version 6.3.0 7 | ## 8 | ## WARNING! All changes made in this file will be lost when recompiling UI file! 9 | ################################################################################ 10 | 11 | from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, 12 | QMetaObject, QObject, QPoint, QRect, 13 | QSize, QTime, QUrl, Qt) 14 | from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, 15 | QFont, QFontDatabase, QGradient, QIcon, 16 | QImage, QKeySequence, QLinearGradient, QPainter, 17 | QPalette, QPixmap, QRadialGradient, QTransform) 18 | from PySide6.QtWidgets import (QApplication, QLabel, QSizePolicy, QVBoxLayout, 19 | QWidget) 20 | 21 | class Ui_widget(object): 22 | def setupUi(self, widget): 23 | if not widget.objectName(): 24 | widget.setObjectName(u"widget") 25 | widget.resize(400, 300) 26 | self.verticalLayout = QVBoxLayout(widget) 27 | self.verticalLayout.setObjectName(u"verticalLayout") 28 | self.label_2 = QLabel(widget) 29 | self.label_2.setObjectName(u"label_2") 30 | font = QFont() 31 | font.setPointSize(16) 32 | self.label_2.setFont(font) 33 | self.label_2.setAlignment(Qt.AlignCenter) 34 | 35 | self.verticalLayout.addWidget(self.label_2) 36 | 37 | 38 | self.retranslateUi(widget) 39 | 40 | QMetaObject.connectSlotsByName(widget) 41 | # setupUi 42 | 43 | def retranslateUi(self, widget): 44 | widget.setWindowTitle(QCoreApplication.translate("widget", u"\u52a0\u8f7d\u4e2d", None)) 45 | self.label_2.setText(QCoreApplication.translate("widget", u"\u52a0\u8f7d\u4e2d\uff0c\u8bf7\u7a0d\u7b49", None)) 46 | # retranslateUi 47 | 48 | -------------------------------------------------------------------------------- /ui/main.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 660 10 | 421 11 | 12 | 13 | 14 | 入口 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 12 26 | 27 | 28 | 29 | 导入字幕文件和音频文件 30 | 31 | 32 | 33 | 34 | 35 | 36 | 请在此表中选择你要操作的数据集 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 数据集名 45 | 46 | 47 | 48 | 49 | 文件路径 50 | 51 | 52 | 53 | 54 | 进入编辑 55 | 56 | 57 | 58 | 59 | 导出 60 | 61 | 62 | 63 | 64 | 删除 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | pushButton 79 | clicked() 80 | MainWindow 81 | to_inputfile() 82 | 83 | 84 | 420 85 | 38 86 | 87 | 88 | 345 89 | 64 90 | 91 | 92 | 93 | 94 | 95 | to_inputfile() 96 | to_workspace() 97 | to_outputfile() 98 | 99 | 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 语音数据集制作标注工具 2 | 3 | ## 简介 4 | 5 | 用于从音频文件和srt字幕文件开始制作数据集,用户可以相对方便的在图形界面中编辑数据信息并导出。 6 | 7 | 初衷是用于给阿里云的语音识别系统输出可用的数据集以提高识别效果,也许还有别的用处。 8 | 9 | 界面:PySide6 10 | 11 | 数据存储:sqlite 12 | 13 | ## 开始 14 | 15 | ### 1.安装依赖 16 | 17 | #### 直接下载最新的release文件 18 | 19 | 在[这里](https://github.com/kslz/SoundLabel/releases)下载最新release的zip压缩包,然后解压双击exe文件即可使用,不过你还是需要安装[ffmpeg](https://ffmpeg.org/download.html#get-packages) 20 | 21 | #### 或者从源代码运行 22 | 23 | 你需要 python3 环境和配置好的 [ffmpeg](https://ffmpeg.org/download.html#get-packages) 24 | 25 | 运行`pip install -r requirements.txt` 安装所需依赖,如果你所在的地区网络不好可以尝试指定源,比如: `pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/` 26 | 27 | 你也许会安装 pyaudio 失败,请在 [这里](https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio) 下载对应版本的 whl 文件,我在根目录下也放了一个 whl 文件,如果你的python版本是3.9的话可以直接使用。得到whl文件后运行`pip install xxx.whl`安装。 28 | 29 | ### 2.准备数据 30 | 31 | ① 请准备一个音频文件(支持wav,mp3,acc格式)和一个与之同名的srt文件,两个文件名之间只能有后缀名不同。 32 | 33 | ② 在项目根目录下新建一个文件夹`filepath` 将srt文件和音频文件放入其中 34 | 35 | ### 3.运行项目 36 | 37 | 运行 `python main.py` 38 | 39 | ## 功能介绍 40 | 41 | ### 主界面: 42 | 43 | ![主界面](https://github.com/kslz/SoundLabel/blob/master/img/main1.png?raw=true) 44 | 45 | - 点击上方的【导入字幕文件和音频文件】按钮可以进入导入界面 46 | - 表格中展示了已有的数据集,点击【进入】按钮可以跳转到对应数据集的编辑页,点击【导出数据集】按钮可以将已标注且标注为可用的数据导出,导出路径为: `filepath/output/数据集名_日期时间/` 47 | ![主界面](https://github.com/kslz/SoundLabel/blob/master/img/main2.png?raw=true) 48 | - 点击删除按钮可以删除对应数据集(没有真的删除,可以从sqlite中找回) 49 | - 被导入的数据会记录音频文件的位置,请不要移动或删除。当对应的音频文件找不到时数据集会不可用 50 | 51 | 52 | 53 | ### 导入界面 54 | 55 | ![导入界面](https://github.com/kslz/SoundLabel/blob/master/img/input1.png?raw=true) 56 | 57 | - 导入界面中展示了目前可导入和已有的数据集,程序会遍历`filepath`目录下的srt文件,然后寻找对应的音频文件,如果可以找到则会在表格中将其展示。点击导入按钮可以导入新的数据集。 58 | - 数据集成功导入后srt文件就不再使用了,可以删除或移动,只保留音频文件即可。 59 | 60 | ### 标注界面 61 | 62 | ![标注界面](https://github.com/kslz/SoundLabel/blob/master/img/workspace1.png?raw=true) 63 | 64 | 标注界面比较复杂,注意:出于节约时间考虑在取数据时过滤掉了4个字和以下长度的音频 65 | 66 | - 窗口右下角的数据列表展示了本数据集中的语句(从srt文件中提取得到),点击【跳转】可以使页面展示对应条目的音频标注信息。 67 | - 界面上方的起止时间表示了本条音频在总音频文件中的起止时间,点击【播放音频】按钮可以试听,如果觉得切割位置不对可以修改这两个值后再点击【播放音频】试听效果。注意:如果此时不点击【确定标注】按钮,则修改的起止时间不会保存。 68 | - 快捷调节时间按钮:点击可以快速加减起止时间 69 | - 【刷新数据列表】按钮的功能是刷新右下角的数据列表,当你修改音频的起止时间影响到音频顺序时你可以点击这个按钮更新列表信息。我不是很推荐做这么大的改动,可能会有bug(待测试)。而且这个按钮比较吃资源,没事不要点,作者之后会想办法优化。 70 | - 【上一条】【下一条】按钮:跳转到上一条或下一条音频信息。 71 | - 【确定标注】按钮:将页面中的数据保存到数据库中 72 | - 两个勾选框:功能如描述 73 | - 标注信息:本条音频对应的文本信息。 74 | - 是否可用:如果你觉得这条音频效果太烂了,加进去可能会影响训练效果,请选择不可用。 75 | - 选择音频播放设备:如果需要可以在此选择,默认选择为系统默认音频设备。注意:如果打开界面后修改了系统默认音频设备,则此处会顺序错乱,请重新打开此界面。 76 | - 导出当前音频:将目前页面上的起止时间划出的音频保存到 `filepath/output` 路径下 根据时间命名 77 | - 【返回首页]按钮:返回首页 78 | - 已知问题:当跳转按钮置灰时鼠标放上去滑动滚轮会无法滚动表格,作者太菜了不会改,谁知道怎么办务必教一下 感谢 79 | 80 | 81 | 82 | ## 其他 83 | 84 | sqlite位置:db/data.db 85 | 86 | 删除数据集后找回:如图所示,将表重命名回原来的名字即可 87 | 88 | ![删除找回界面](https://github.com/kslz/SoundLabel/blob/master/img/delete_dataset.png?raw=true) 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /ui/inputdata.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 800 10 | 600 11 | 12 | 13 | 14 | 导入数据 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | false 25 | 26 | 27 | 28 | 文件名 29 | 30 | 31 | 32 | 33 | 文件路径 34 | 35 | 36 | 37 | 38 | 操作 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 请双击左上角的表格来导入对应的音频和字幕 53 | 注意:音频只支持wav,acc和mp3格式 54 | 且音频和字幕的文件名必须相同,后缀可以不同 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 0 63 | 0 64 | 65 | 66 | 67 | 返回入口 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | true 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | pushButton 94 | clicked() 95 | MainWindow 96 | back_to_main() 97 | 98 | 99 | 492 100 | 303 101 | 102 | 103 | 573 104 | 271 105 | 106 | 107 | 108 | 109 | 110 | double_clicked_file() 111 | back_to_main() 112 | 113 | 114 | -------------------------------------------------------------------------------- /ui/ui_main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ################################################################################ 4 | ## Form generated from reading UI file 'main.ui' 5 | ## 6 | ## Created by: Qt User Interface Compiler version 6.3.0 7 | ## 8 | ## WARNING! All changes made in this file will be lost when recompiling UI file! 9 | ################################################################################ 10 | 11 | from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, 12 | QMetaObject, QObject, QPoint, QRect, 13 | QSize, QTime, QUrl, Qt) 14 | from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, 15 | QFont, QFontDatabase, QGradient, QIcon, 16 | QImage, QKeySequence, QLinearGradient, QPainter, 17 | QPalette, QPixmap, QRadialGradient, QTransform) 18 | from PySide6.QtWidgets import (QApplication, QHeaderView, QLabel, QMainWindow, 19 | QPushButton, QSizePolicy, QTableWidget, QTableWidgetItem, 20 | QVBoxLayout, QWidget) 21 | 22 | class Ui_MainWindow(object): 23 | def setupUi(self, MainWindow): 24 | if not MainWindow.objectName(): 25 | MainWindow.setObjectName(u"MainWindow") 26 | MainWindow.resize(660, 421) 27 | self.centralwidget = QWidget(MainWindow) 28 | self.centralwidget.setObjectName(u"centralwidget") 29 | self.verticalLayout_2 = QVBoxLayout(self.centralwidget) 30 | self.verticalLayout_2.setObjectName(u"verticalLayout_2") 31 | self.widget = QWidget(self.centralwidget) 32 | self.widget.setObjectName(u"widget") 33 | self.verticalLayout = QVBoxLayout(self.widget) 34 | self.verticalLayout.setObjectName(u"verticalLayout") 35 | self.pushButton = QPushButton(self.widget) 36 | self.pushButton.setObjectName(u"pushButton") 37 | font = QFont() 38 | font.setPointSize(12) 39 | self.pushButton.setFont(font) 40 | 41 | self.verticalLayout.addWidget(self.pushButton) 42 | 43 | self.label = QLabel(self.widget) 44 | self.label.setObjectName(u"label") 45 | 46 | self.verticalLayout.addWidget(self.label) 47 | 48 | self.tableWidget = QTableWidget(self.widget) 49 | if (self.tableWidget.columnCount() < 5): 50 | self.tableWidget.setColumnCount(5) 51 | __qtablewidgetitem = QTableWidgetItem() 52 | self.tableWidget.setHorizontalHeaderItem(0, __qtablewidgetitem) 53 | __qtablewidgetitem1 = QTableWidgetItem() 54 | self.tableWidget.setHorizontalHeaderItem(1, __qtablewidgetitem1) 55 | __qtablewidgetitem2 = QTableWidgetItem() 56 | self.tableWidget.setHorizontalHeaderItem(2, __qtablewidgetitem2) 57 | __qtablewidgetitem3 = QTableWidgetItem() 58 | self.tableWidget.setHorizontalHeaderItem(3, __qtablewidgetitem3) 59 | __qtablewidgetitem4 = QTableWidgetItem() 60 | self.tableWidget.setHorizontalHeaderItem(4, __qtablewidgetitem4) 61 | self.tableWidget.setObjectName(u"tableWidget") 62 | 63 | self.verticalLayout.addWidget(self.tableWidget) 64 | 65 | 66 | self.verticalLayout_2.addWidget(self.widget) 67 | 68 | MainWindow.setCentralWidget(self.centralwidget) 69 | 70 | self.retranslateUi(MainWindow) 71 | self.pushButton.clicked.connect(MainWindow.to_inputfile) 72 | 73 | QMetaObject.connectSlotsByName(MainWindow) 74 | # setupUi 75 | 76 | def retranslateUi(self, MainWindow): 77 | MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"\u5165\u53e3", None)) 78 | self.pushButton.setText(QCoreApplication.translate("MainWindow", u"\u5bfc\u5165\u5b57\u5e55\u6587\u4ef6\u548c\u97f3\u9891\u6587\u4ef6", None)) 79 | self.label.setText(QCoreApplication.translate("MainWindow", u"\u8bf7\u5728\u6b64\u8868\u4e2d\u9009\u62e9\u4f60\u8981\u64cd\u4f5c\u7684\u6570\u636e\u96c6", None)) 80 | ___qtablewidgetitem = self.tableWidget.horizontalHeaderItem(0) 81 | ___qtablewidgetitem.setText(QCoreApplication.translate("MainWindow", u"\u6570\u636e\u96c6\u540d", None)); 82 | ___qtablewidgetitem1 = self.tableWidget.horizontalHeaderItem(1) 83 | ___qtablewidgetitem1.setText(QCoreApplication.translate("MainWindow", u"\u6587\u4ef6\u8def\u5f84", None)); 84 | ___qtablewidgetitem2 = self.tableWidget.horizontalHeaderItem(2) 85 | ___qtablewidgetitem2.setText(QCoreApplication.translate("MainWindow", u"\u8fdb\u5165\u7f16\u8f91", None)); 86 | ___qtablewidgetitem3 = self.tableWidget.horizontalHeaderItem(3) 87 | ___qtablewidgetitem3.setText(QCoreApplication.translate("MainWindow", u"\u5bfc\u51fa", None)); 88 | ___qtablewidgetitem4 = self.tableWidget.horizontalHeaderItem(4) 89 | ___qtablewidgetitem4.setText(QCoreApplication.translate("MainWindow", u"\u5220\u9664", None)); 90 | # retranslateUi 91 | 92 | -------------------------------------------------------------------------------- /ui/ui_inputdata.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ################################################################################ 4 | ## Form generated from reading UI file 'inputdata.ui' 5 | ## 6 | ## Created by: Qt User Interface Compiler version 6.3.0 7 | ## 8 | ## WARNING! All changes made in this file will be lost when recompiling UI file! 9 | ################################################################################ 10 | 11 | from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, 12 | QMetaObject, QObject, QPoint, QRect, 13 | QSize, QTime, QUrl, Qt) 14 | from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, 15 | QFont, QFontDatabase, QGradient, QIcon, 16 | QImage, QKeySequence, QLinearGradient, QPainter, 17 | QPalette, QPixmap, QRadialGradient, QTransform) 18 | from PySide6.QtWidgets import (QApplication, QHBoxLayout, QHeaderView, QLabel, 19 | QMainWindow, QPushButton, QSizePolicy, QTableWidget, 20 | QTableWidgetItem, QTextEdit, QVBoxLayout, QWidget) 21 | 22 | class Ui_MainWindow(object): 23 | def setupUi(self, MainWindow): 24 | if not MainWindow.objectName(): 25 | MainWindow.setObjectName(u"MainWindow") 26 | MainWindow.resize(800, 600) 27 | self.centralwidget = QWidget(MainWindow) 28 | self.centralwidget.setObjectName(u"centralwidget") 29 | self.verticalLayout = QVBoxLayout(self.centralwidget) 30 | self.verticalLayout.setObjectName(u"verticalLayout") 31 | self.widget = QWidget(self.centralwidget) 32 | self.widget.setObjectName(u"widget") 33 | self.horizontalLayout = QHBoxLayout(self.widget) 34 | self.horizontalLayout.setObjectName(u"horizontalLayout") 35 | self.dataTableWidget = QTableWidget(self.widget) 36 | if (self.dataTableWidget.columnCount() < 3): 37 | self.dataTableWidget.setColumnCount(3) 38 | __qtablewidgetitem = QTableWidgetItem() 39 | self.dataTableWidget.setHorizontalHeaderItem(0, __qtablewidgetitem) 40 | __qtablewidgetitem1 = QTableWidgetItem() 41 | self.dataTableWidget.setHorizontalHeaderItem(1, __qtablewidgetitem1) 42 | __qtablewidgetitem2 = QTableWidgetItem() 43 | self.dataTableWidget.setHorizontalHeaderItem(2, __qtablewidgetitem2) 44 | self.dataTableWidget.setObjectName(u"dataTableWidget") 45 | self.dataTableWidget.setTabletTracking(False) 46 | 47 | self.horizontalLayout.addWidget(self.dataTableWidget) 48 | 49 | 50 | self.verticalLayout.addWidget(self.widget) 51 | 52 | self.widget_2 = QWidget(self.centralwidget) 53 | self.widget_2.setObjectName(u"widget_2") 54 | self.horizontalLayout_2 = QHBoxLayout(self.widget_2) 55 | self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") 56 | self.label = QLabel(self.widget_2) 57 | self.label.setObjectName(u"label") 58 | 59 | self.horizontalLayout_2.addWidget(self.label) 60 | 61 | self.pushButton = QPushButton(self.widget_2) 62 | self.pushButton.setObjectName(u"pushButton") 63 | sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) 64 | sizePolicy.setHorizontalStretch(0) 65 | sizePolicy.setVerticalStretch(0) 66 | sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth()) 67 | self.pushButton.setSizePolicy(sizePolicy) 68 | 69 | self.horizontalLayout_2.addWidget(self.pushButton) 70 | 71 | 72 | self.verticalLayout.addWidget(self.widget_2) 73 | 74 | self.widget_3 = QWidget(self.centralwidget) 75 | self.widget_3.setObjectName(u"widget_3") 76 | self.horizontalLayout_3 = QHBoxLayout(self.widget_3) 77 | self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") 78 | self.textEdit = QTextEdit(self.widget_3) 79 | self.textEdit.setObjectName(u"textEdit") 80 | self.textEdit.setReadOnly(True) 81 | 82 | self.horizontalLayout_3.addWidget(self.textEdit) 83 | 84 | 85 | self.verticalLayout.addWidget(self.widget_3) 86 | 87 | MainWindow.setCentralWidget(self.centralwidget) 88 | 89 | self.retranslateUi(MainWindow) 90 | self.pushButton.clicked.connect(MainWindow.back_to_main) 91 | 92 | QMetaObject.connectSlotsByName(MainWindow) 93 | # setupUi 94 | 95 | def retranslateUi(self, MainWindow): 96 | MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"\u5bfc\u5165\u6570\u636e", None)) 97 | ___qtablewidgetitem = self.dataTableWidget.horizontalHeaderItem(0) 98 | ___qtablewidgetitem.setText(QCoreApplication.translate("MainWindow", u"\u6587\u4ef6\u540d", None)); 99 | ___qtablewidgetitem1 = self.dataTableWidget.horizontalHeaderItem(1) 100 | ___qtablewidgetitem1.setText(QCoreApplication.translate("MainWindow", u"\u6587\u4ef6\u8def\u5f84", None)); 101 | ___qtablewidgetitem2 = self.dataTableWidget.horizontalHeaderItem(2) 102 | ___qtablewidgetitem2.setText(QCoreApplication.translate("MainWindow", u"\u64cd\u4f5c", None)); 103 | self.label.setText(QCoreApplication.translate("MainWindow", u"\u8bf7\u53cc\u51fb\u5de6\u4e0a\u89d2\u7684\u8868\u683c\u6765\u5bfc\u5165\u5bf9\u5e94\u7684\u97f3\u9891\u548c\u5b57\u5e55\n" 104 | "\u6ce8\u610f\uff1a\u97f3\u9891\u53ea\u652f\u6301wav,acc\u548cmp3\u683c\u5f0f\n" 105 | "\u4e14\u97f3\u9891\u548c\u5b57\u5e55\u7684\u6587\u4ef6\u540d\u5fc5\u987b\u76f8\u540c\uff0c\u540e\u7f00\u53ef\u4ee5\u4e0d\u540c", None)) 106 | self.pushButton.setText(QCoreApplication.translate("MainWindow", u"\u8fd4\u56de\u5165\u53e3", None)) 107 | # retranslateUi 108 | 109 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sqlite3 3 | from pathlib import Path 4 | 5 | from pydub import AudioSegment 6 | import time 7 | 8 | import global_obj 9 | 10 | 11 | class LiteDB: 12 | def __init__(self, dbpath='db/data.db'): 13 | check_mkdir("/".join(dbpath.replace("\\", "/").split("/")[:-1])) 14 | self.conn = sqlite3.connect(dbpath) 15 | print("数据库打开成功") 16 | 17 | def close(self): 18 | self.conn.close() 19 | print("数据库已关闭") 20 | 21 | def create_sound_table(self, sound_name): 22 | c = self.conn.cursor() 23 | c.execute(f'''CREATE TABLE "{sound_name}" ( 24 | "sound_id" integer NOT NULL, 25 | "sound_text" TEXT NOT NULL, 26 | "sound_start" integer NOT NULL, 27 | "sound_end" integer NOT NULL, 28 | "checked" integer NOT NULL DEFAULT 0, 29 | "can_use" integer NOT NULL DEFAULT 1, 30 | "sound_file_path" TEXT NOT NULL, 31 | PRIMARY KEY ("sound_id"));''') 32 | print(f"数据表 {sound_name} 创建成功") 33 | self.conn.commit() 34 | 35 | def delete_sound_table(self, sound_name): 36 | c = self.conn.cursor() 37 | now_time = time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime()) 38 | c.execute(f'''ALTER TABLE '{sound_name}' RENAME TO {'_' + sound_name + '_' + now_time};''') 39 | print(f"数据表 {sound_name} 被改名为 {'_' + sound_name + '_' + now_time}") 40 | self.conn.commit() 41 | 42 | def select_all(self): 43 | c = self.conn.cursor() 44 | result = c.execute("select * from sound") 45 | return result 46 | 47 | def select_unchecked(self): 48 | c = self.conn.cursor() 49 | result = c.execute("SELECT sound_text,sound_start,sound_end,checked,can_use FROM sound") 50 | return result 51 | 52 | def select_tables_list(self): 53 | """ 搜索都有什么表 """ 54 | c = self.conn.cursor() 55 | result = c.execute("SELECT name FROM sqlite_master WHERE type = 'table'") 56 | result_list = [] 57 | for row in result: 58 | result_list.append(row[0]) 59 | return result_list 60 | 61 | def select_sound_path(self, name): 62 | """ 根据sound name(即表名)搜索音频文件位置 """ 63 | c = self.conn.cursor() 64 | result = c.execute(f"SELECT sound_file_path FROM '{name}' limit 1") 65 | result_list = [] 66 | for row in result: 67 | return row[0] 68 | 69 | def select_dataset_data(self, name, num=4): 70 | """ 搜索某个数据集里的全部信息 """ 71 | c = self.conn.cursor() 72 | # result = c.execute(f"SELECT ROW_NUMBER() OVER(ORDER BY sound_start ASC)-1 AS xuhao ,sound_text,sound_start,sound_end,checked,can_use FROM {name} ORDER BY sound_start ASC") 73 | result = c.execute( 74 | f"SELECT sound_id,sound_text,sound_start,sound_end,checked,can_use FROM '{name}' WHERE LENGTH(sound_text)>{num} ORDER BY sound_start ASC") 75 | return list(result) 76 | 77 | def select_dataset_row(self, name, id, num=4): 78 | """ 搜索数据集里的其中一条数据 """ 79 | c = self.conn.cursor() 80 | result = c.execute( 81 | f"SELECT sound_id,sound_text,sound_start,sound_end,checked,can_use FROM '{name}' WHERE sound_id = {id}") 82 | return list(result)[0] 83 | 84 | def select_output_data(self, name, num=4): 85 | """ 搜索指定数据集要导出的数据 """ 86 | result_dict = {} 87 | c = self.conn.cursor() 88 | result = c.execute( 89 | f"SELECT sound_text,sound_start,sound_end FROM '{name}' WHERE LENGTH(sound_text)>{num} AND checked=1 AND can_use=1 ORDER BY sound_start ASC") 90 | result_dict["data_list"] = list(result) 91 | result_dict["path"] = list(c.execute(f"SELECT sound_file_path FROM '{name}' limit 1"))[0][0] # 顺序很重要 92 | return result_dict 93 | 94 | def insert_sound_line(self, input_list, path, name): 95 | """ 新增一条语音记录 """ 96 | c = self.conn.cursor() 97 | for row in input_list: 98 | c.execute( 99 | f"INSERT INTO '{name}' (sound_text, sound_start, sound_end, sound_file_path) VALUES ('{row[0]}', {row[1]}, {row[2]}, '{path}')") 100 | self.conn.commit() 101 | print("数据插入成功") 102 | 103 | def update_sound(self, sound_obj, name): 104 | """ 更新标注信息 """ 105 | c = self.conn.cursor() 106 | c.execute( 107 | f"UPDATE '{name}' SET sound_text = '{sound_obj.text}', sound_start = {sound_obj.start}, sound_end = {sound_obj.end}, checked = {sound_obj.checked}, can_use = {sound_obj.can_use} WHERE sound_id = {sound_obj.id}") 108 | self.conn.commit() 109 | print(f"数据 {sound_obj.text} 更新成功") 110 | 111 | 112 | class MySound: 113 | def __init__(self, info_list): 114 | self.id = info_list[0] 115 | self.text = info_list[1] 116 | self.start = info_list[2] 117 | self.end = info_list[3] 118 | self.checked = info_list[4] 119 | self.can_use = info_list[5] 120 | 121 | 122 | class WorkSpaceData: 123 | def __init__(self, name, path): 124 | self.name = name 125 | self.sound_list = [] 126 | self.refresh_sound_list() 127 | self.sound_path = path 128 | self.sound = AudioSegment.from_file(path) 129 | self.now_sound_index = 0 130 | 131 | def refresh_sound_list(self): 132 | db = global_obj.get_value("db") 133 | sound_list = [] 134 | for row in db.select_dataset_data(self.name): 135 | sound_list.append(MySound(row)) 136 | self.sound_list = sound_list 137 | print("数据集信息已更新") 138 | 139 | 140 | # class MySRT: 141 | # def __init__(self, file_path): 142 | # self.srt_path = file_path 143 | # self.srt_list = [] 144 | # srt_text = file_r(file_path) 145 | # srt_row = [] 146 | # for line in srt_text.split("\n"): 147 | # print(line) 148 | # pass 149 | 150 | 151 | # def get_sound(file_path): 152 | # file_type = file_path.split(".")[-1:][0] 153 | # if file_type == "mp3": 154 | # return AudioSegment.from_mp3(file_path) 155 | # elif file_type == "wav": 156 | # return AudioSegment.from_wav(file_path) 157 | 158 | 159 | def cut_sound(sound, start, end): 160 | return sound[start:end] 161 | 162 | 163 | def listdir(path, list_name, file_end=""): # 传入存储的list 164 | """ 165 | 将目录下的文件名读存储在list中 166 | :param file_end: 167 | :param path: 168 | :param list_name: 169 | :return: 170 | """ 171 | for file in os.listdir(path): 172 | file_path = os.path.join(path, file) 173 | if os.path.isdir(file_path): 174 | listdir(file_path, list_name) 175 | else: 176 | if file_path.endswith(file_end): 177 | if file_path.find(".DS_Store") != -1: 178 | continue 179 | list_name.append(file_path.replace("\\", "/")) 180 | 181 | 182 | def dictdir(path, dict_name, file_end=""): # 传入存储的dict 183 | """ 184 | 将目录下的文件名读存储在list中 185 | :param path: 186 | :param dict_name: 187 | :param file_end: 188 | :return: 189 | """ 190 | for file in os.listdir(path): 191 | file_path = os.path.join(path, file) 192 | if os.path.isdir(file_path): 193 | dictdir(file_path, dict_name) 194 | else: 195 | if file_path.endswith(file_end): 196 | if file_path.find(".DS_Store") != -1: 197 | continue 198 | dict_name[file_path.replace("\\", "/").split("/")[-1]] = file_path.replace("\\", "/") 199 | 200 | 201 | def file_r(path): 202 | with open(path, 'r', encoding="UTF-8") as f: 203 | return f.read() 204 | 205 | 206 | def is_sound_file_ok(path): 207 | return Path(path).is_file() 208 | # is_ok = False 209 | # try: 210 | # AudioSegment.from_file(path) 211 | # except: 212 | # print(f"{path} 文件未找到,无法进入数据集") 213 | # else: 214 | # is_ok = True 215 | # return is_ok 216 | 217 | 218 | def check_mkdir(path): 219 | """ 检查一个目录是否存在,不存在则新建 """ 220 | if not os.path.exists(path): 221 | os.makedirs(path) 222 | 223 | 224 | if __name__ == "__main__": 225 | pass 226 | -------------------------------------------------------------------------------- /ui/guiclass.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from threading import Thread 4 | from time import sleep 5 | 6 | import pyaudio 7 | import pysrt 8 | from PySide6.QtCore import Qt 9 | from PySide6.QtGui import QFont 10 | from pydub import AudioSegment 11 | from pydub.playback import play 12 | from pydub.utils import make_chunks 13 | 14 | import global_obj 15 | 16 | import utils 17 | 18 | from PySide6.QtWidgets import QApplication, QMainWindow, QFrame, QPushButton, QTableWidgetItem, QWidget, QMessageBox, \ 19 | QButtonGroup 20 | 21 | from ui import ui_main, ui_gui, ui_inputdata, ui_wait 22 | 23 | import traceback 24 | 25 | 26 | class WorkSpaceWindow(QFrame): 27 | def __init__(self): 28 | super(WorkSpaceWindow, self).__init__() 29 | self.ui = ui_gui.Ui_Mainwindow() 30 | self.ui.setupUi(self) 31 | self.work_space_data = None 32 | self.ui.tableWidget.setRowHeight(1, 10) 33 | font1 = QFont() 34 | font1.setPointSize(10) 35 | self.ui.tableWidget.setFont(font1) 36 | self.btn_group = QButtonGroup(self.ui.groupBox_2) 37 | self.btn_group.addButton(self.ui.radioButton, 0) 38 | self.btn_group.addButton(self.ui.radioButton_2, 1) 39 | 40 | def click_change_start_BTN(self, mtime): 41 | try: 42 | curmtime = int(self.ui.lineEdit_2.text()) 43 | # print(curmtime,mtime) 44 | curmtime = curmtime + int(mtime) 45 | except: 46 | curmtime = 0 47 | traceback.print_exc() 48 | pass 49 | self.ui.lineEdit_2.setText(str(curmtime)) 50 | 51 | def click_change_end_BTN(self, mtime): 52 | try: 53 | curmtime = int(self.ui.lineEdit_3.text()) 54 | curmtime = curmtime + int(mtime) 55 | except: 56 | curmtime = 0 57 | traceback.print_exc() 58 | pass 59 | self.ui.lineEdit_3.setText(str(curmtime)) 60 | 61 | def click_refreshBTN(self): 62 | """ 点击刷新数据列表按钮后触发的槽函数 """ 63 | print("刷新表格") 64 | self.ui.pushButton_4.setEnabled(False) 65 | self.ui.pushButton_4.setText("请稍等") 66 | self.ui.pushButton_4.style() 67 | self.refresh_data(self.work_space_data.name) 68 | self.ui.pushButton_4.setEnabled(True) 69 | self.ui.pushButton_4.setText("刷新数据列表") 70 | self.ui.pushButton_4.style() 71 | 72 | def click_play_soundBTN(self): 73 | """ 点击播放音频后触发的槽函数 """ 74 | print("播放声音") 75 | 76 | play_thread = Thread(target=self.new_play_sound) 77 | play_thread.start() 78 | # play_thread.join() # 多线程 永远的神 不加界面就阻塞了 79 | 80 | def play_sound(self): 81 | """" 播放音频 同时检查是不是正常的数字 """ 82 | try: 83 | start = int(self.ui.lineEdit_2.text()) 84 | end = int(self.ui.lineEdit_3.text()) 85 | except: 86 | print("请输入以毫秒为单位的纯数字") 87 | else: 88 | play(self.work_space_data.sound[start:end]) 89 | 90 | def new_play_sound(self): 91 | """" 在指定音频设备上播放音频 同时检查是不是正常的数字 """ 92 | try: 93 | start = int(self.ui.lineEdit_2.text()) 94 | end = int(self.ui.lineEdit_3.text()) 95 | except: 96 | print("请输入以毫秒为单位的纯数字") 97 | else: 98 | seg = self.work_space_data.sound[start:end] 99 | device_map = global_obj.get_value("device_map") 100 | index = device_map[self.ui.comboBox.currentText()] 101 | import pyaudio 102 | 103 | p = pyaudio.PyAudio() 104 | stream = p.open(format=p.get_format_from_width(seg.sample_width), 105 | channels=seg.channels, 106 | rate=seg.frame_rate, 107 | output=True, 108 | output_device_index=index) 109 | 110 | # Just in case there were any exceptions/interrupts, we release the resource 111 | # So as not to raise OSError: Device Unavailable should play() be used again 112 | try: 113 | # break audio into half-second chunks (to allows keyboard interrupts) 114 | for chunk in make_chunks(seg, 500): 115 | stream.write(chunk._data) 116 | finally: 117 | stream.stop_stream() 118 | stream.close() 119 | 120 | p.terminate() 121 | 122 | def click_backBTN(self): 123 | print(f"返回上一个声音 序号{self.work_space_data.now_sound_index - 1}") 124 | self.goto_sound(self.work_space_data.now_sound_index - 1) # 进行一个代码的复用 125 | 126 | def click_nextBTN(self): 127 | print(f"继续下一个声音 序号{self.work_space_data.now_sound_index + 1}") 128 | self.goto_sound(self.work_space_data.now_sound_index + 1) # 进行一个代码的复用 129 | 130 | def click_checkBTN(self): 131 | """ 将本条信息标注,修改数据库的内容且将状态切换为已标注 """ 132 | print("确定本条声音") 133 | db = global_obj.get_value("db") 134 | index = self.work_space_data.now_sound_index 135 | now_sound_info = self.work_space_data.sound_list[index] 136 | now_sound_info.text = self.ui.lineEdit.text() 137 | now_sound_info.start = self.ui.lineEdit_2.text() 138 | now_sound_info.end = self.ui.lineEdit_3.text() 139 | now_sound_info.checked = 1 140 | if self.btn_group.checkedId() == -1: 141 | now_sound_info.can_use = 1 142 | else: 143 | now_sound_info.can_use = self.btn_group.checkedId() 144 | db.update_sound(now_sound_info, self.work_space_data.name) 145 | self.refresh_table_line() 146 | if self.ui.checkBox_2.isChecked(): 147 | if self.ui.tableWidget.rowCount() - 1 != self.work_space_data.now_sound_index: 148 | self.click_nextBTN() 149 | 150 | def refresh_table_line(self): 151 | """ 刷新表格中的一条数据的信息,从数据库中取值,但不改变表格中的跳转按钮状态 """ 152 | # 试图用子线程给界面加元素,但是加的所有widget及其子类都被添加到新窗口里了,加不到老窗口里,故作罢 153 | index = self.work_space_data.now_sound_index 154 | now_sound_info = self.work_space_data.sound_list[index] 155 | db = global_obj.get_value("db") 156 | select_sound_info = db.select_dataset_row(self.work_space_data.name, now_sound_info.id) 157 | item_text1 = "已标注" 158 | if select_sound_info[4] == 0: 159 | item_text1 = "未标注" 160 | item_text2 = "可用" 161 | if select_sound_info[5] == 0: 162 | item_text2 = "不可用" 163 | self.ui.tableWidget.item(self.work_space_data.now_sound_index, 0).setText(select_sound_info[1]) 164 | self.ui.tableWidget.item(self.work_space_data.now_sound_index, 1).setText(item_text1) 165 | self.ui.tableWidget.item(self.work_space_data.now_sound_index, 2).setText(item_text2) 166 | self.ui.tableWidget.resizeColumnsToContents() # 表格列宽自动调整 167 | 168 | def refresh_data(self, name): 169 | """ 刷新表格信息 """ 170 | # 清空表格 171 | while self.ui.tableWidget.rowCount() != 0: 172 | self.ui.tableWidget.removeRow(0) 173 | db = global_obj.get_value("db") 174 | path = db.select_sound_path(name) 175 | self.work_space_data = utils.WorkSpaceData(name, path) 176 | i = 0 177 | for sound_obj in self.work_space_data.sound_list: 178 | self.sound_obj_to_row(sound_obj, i) 179 | i = i + 1 # 半自动经典for循环 index不好用 180 | self.refresh_now_sound() 181 | self.ui.tableWidget.resizeColumnsToContents() # 表格列宽自动调整 182 | 183 | # 获取所有音频播放设备 184 | cbox = self.ui.comboBox 185 | cbox.clear() 186 | p = pyaudio.PyAudio() 187 | audio_device_map = {} 188 | device_index = 0 189 | 190 | for i in range(p.get_device_count()): 191 | device = p.get_device_info_by_index(i) 192 | if device.get('maxOutputChannels', 0) > 0: 193 | index = device.get("index") 194 | audio_device_map[str(index) + ":" + device.get("name")] = device.get("index") 195 | 196 | # cbox.addItem('默认设备') 197 | for i in audio_device_map: 198 | cbox.addItem(i) 199 | 200 | global_obj.set_value("device_map", audio_device_map) 201 | 202 | def sound_obj_to_row(self, sound_obj, sound_id): 203 | """ 传入一个sound_obj,给表格中加一行 """ 204 | # sound_obj = utils.MySound() 205 | row_count = self.ui.tableWidget.rowCount() 206 | self.ui.tableWidget.insertRow(row_count) 207 | item1 = QTableWidgetItem() 208 | item1.setText(sound_obj.text) 209 | item1.setFlags(Qt.ItemIsEnabled) # 禁止编辑 210 | 211 | item2 = QTableWidgetItem() 212 | item_text1 = "已标注" 213 | if sound_obj.checked == 0: 214 | item_text1 = "未标注" 215 | item2.setText(item_text1) 216 | item2.setFlags(Qt.ItemIsEnabled) 217 | 218 | item3 = QTableWidgetItem() 219 | item_text2 = "可用" 220 | if sound_obj.can_use == 0: 221 | item_text2 = "不可用" 222 | item3.setText(item_text2) 223 | item3.setFlags(Qt.ItemIsEnabled) 224 | 225 | self.ui.tableWidget.setItem(row_count, 0, item1) 226 | self.ui.tableWidget.setItem(row_count, 1, item2) 227 | self.ui.tableWidget.setItem(row_count, 2, item3) 228 | self.ui.tableWidget.setCellWidget(row_count, 3, self.button_goto_for_row(sound_id)) 229 | 230 | def button_goto_for_row(self, sound_id): 231 | """ 返回一个用于跳转到对应音频信息的btn """ 232 | input_btn = QPushButton('跳转') 233 | input_btn.clicked.connect(lambda: self.goto_sound(sound_id)) # 不那么复杂的参数传递 234 | if self.work_space_data.now_sound_index == sound_id: 235 | input_btn.setEnabled(False) 236 | return input_btn 237 | 238 | def goto_sound(self, sound_id): 239 | """ 表格中的跳转按钮点击后对应的槽函数 """ 240 | old_id = self.work_space_data.now_sound_index 241 | self.work_space_data.now_sound_index = sound_id 242 | self.refresh_now_sound() 243 | self.refresh_table_gotoBTN(old_id, sound_id) 244 | self.ui.tableWidget.selectRow(sound_id) # 如果不加这个会导致点击按钮后选中按钮下一行的第一个单元格,猜测原因是本应选中按钮,但是按钮被置灰光标自动后移 245 | if self.ui.checkBox.isChecked(): 246 | self.click_play_soundBTN() # 灵活运用槽 247 | 248 | def refresh_table_gotoBTN(self, old_id, new_id): 249 | """ 用于刷新表格中的跳转按钮状态""" 250 | self.ui.tableWidget.cellWidget(old_id, 3).setEnabled(True) 251 | self.ui.tableWidget.cellWidget(new_id, 3).setEnabled(False) 252 | 253 | def refresh_now_sound(self): 254 | """ 更新当前页面中的音频信息,不改变表格中的按钮状态 """ 255 | index = self.work_space_data.now_sound_index 256 | now_sound_info = self.work_space_data.sound_list[index] 257 | print(f"现在的音频信息为:{now_sound_info.text}") 258 | self.ui.lineEdit_2.setText(str(now_sound_info.start)) 259 | self.ui.lineEdit_3.setText(str(now_sound_info.end)) 260 | self.ui.lineEdit.setText(now_sound_info.text) 261 | self.ui.label_5.setText(f"当前编号:{index + 1}") 262 | if now_sound_info.can_use == 0: 263 | self.ui.radioButton.setChecked(True) 264 | elif now_sound_info.can_use == 1: 265 | self.ui.radioButton_2.setChecked(True) 266 | 267 | # 刷新上一条下一条按钮状态 268 | if self.ui.tableWidget.rowCount() - 1 == self.work_space_data.now_sound_index: 269 | self.ui.pushButton_2.setEnabled(False) 270 | else: 271 | self.ui.pushButton_2.setEnabled(True) 272 | 273 | if self.work_space_data.now_sound_index == 0: 274 | self.ui.pushButton.setEnabled(False) 275 | else: 276 | self.ui.pushButton.setEnabled(True) 277 | 278 | def click_output_now(self): 279 | """ 导出当前的音频文件,如果不指定则导出到filepath/output下,命名为数据集名+日期 """ 280 | # 不知为何 槽函数接收到信号的时候顺便还接收到了一个参数 值为false 但是我不知道这个false是哪来的 281 | path = "filepath/output" 282 | path = path.replace("\\", "/") 283 | if not path.endswith("/"): 284 | path = path + "/" 285 | utils.check_mkdir(path) 286 | try: 287 | start = int(self.ui.lineEdit_2.text()) 288 | end = int(self.ui.lineEdit_3.text()) 289 | except: 290 | print("请输入以毫秒为单位的纯数字") 291 | else: 292 | out_sound = self.work_space_data.sound[start:end] 293 | out_sound = out_sound.set_frame_rate(16000).set_channels(1) # 设置为16k采样率,单声道 294 | out_sound.export( 295 | path + self.work_space_data.name + '_' + time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime()) + ".wav", 296 | format="wav", bitrate="16k", codec='pcm_s16le') 297 | print("导出当前文件为:" + path + self.work_space_data.name + '_' + time.strftime("%Y_%m_%d_%H_%M_%S", 298 | time.localtime()) + ".wav") 299 | 300 | def click_back_to_main(self): 301 | """ 返回首页窗口 """ 302 | window2.close() 303 | window1.show() 304 | # 清空表格,节约内存 节省了10m不到的内存 没意义 305 | # window2.work_space_data = None 306 | # while window2.ui.tableWidget.rowCount() != 0: 307 | # window2.ui.tableWidget.removeRow(0) 308 | 309 | 310 | class MainWindow(QMainWindow): 311 | def __init__(self): 312 | super(MainWindow, self).__init__() 313 | self.ui = ui_main.Ui_MainWindow() 314 | self.ui.setupUi(self) 315 | 316 | def to_inputfile(self): 317 | print("前往导入文件窗口") 318 | window1.close() 319 | window3.refresh_data() 320 | window3.show() 321 | 322 | def to_outputfile(self, name): 323 | """ 324 | 根据数据集名导出数据集,导出的路径为filepath/output/数据集名_日期时间/ 325 | 音频路径为data/wav/数据集名_编号.wav 326 | 文本路径为data/trans/sample.txt 327 | """ 328 | print(f"导出数据集{name}") 329 | path = "filepath/output" 330 | path = path.replace("\\", "/") 331 | if not path.endswith("/"): 332 | path = path + "/" 333 | path = path + name + '_' + time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime()) + "/" 334 | utils.check_mkdir(path + "data/wav/") 335 | utils.check_mkdir(path + "data/trans/") 336 | db = global_obj.get_value("db") 337 | result_dict = db.select_output_data(name) 338 | # print(result_dict) 339 | try: 340 | all_sound = AudioSegment.from_file(result_dict["path"]).set_channels(1) 341 | except: 342 | print(f"{result_dict['path']} 文件未找到,无法导出数据集") 343 | 344 | i = 0 345 | write_str = "" 346 | for row in result_dict["data_list"]: 347 | i = i + 1 348 | all_sound[row[1]:row[2]].export(path + "data/wav/" + f"{name}_" + str(i) + ".wav", format="wav", 349 | # bitrate="16k", 350 | codec='pcm_s16le') 351 | write_str = write_str + f"{name}_" + str(i) + ".wav" + "\t" + row[0] + "\n" 352 | 353 | with open(path + "data/trans/sample.txt", "a", encoding="UTF-8") as f: 354 | f.write(write_str) 355 | is_delete = QMessageBox.information(self, "导出完成", f"导出数据集{name}成功\n请前往 {path} 查看", 356 | QMessageBox.Yes, QMessageBox.Yes) 357 | print(f"导出数据集{name}成功") 358 | 359 | def to_workspace(self, name): 360 | print(f"前往数据标注窗口 {name}") 361 | window1.close() 362 | # window4.ui.label_2.setText("加载中,请稍等...") # 很奇怪 这个窗口里的东西都加载不出来 363 | window4.show() 364 | window2.refresh_data(name) 365 | window4.close() 366 | window2.show() 367 | 368 | def refresh_data(self): 369 | self.table_refresh() 370 | 371 | def table_refresh(self): 372 | # 清空表格 373 | while window1.ui.tableWidget.rowCount() != 0: 374 | window1.ui.tableWidget.removeRow(0) 375 | 376 | for row in self.get_row_info(): 377 | row_count = window1.ui.tableWidget.rowCount() 378 | window1.ui.tableWidget.insertRow(row_count) 379 | 380 | item1 = QTableWidgetItem() 381 | item1.setText(row[0]) 382 | item1.setFlags(Qt.ItemIsEnabled) 383 | 384 | item2 = QTableWidgetItem() 385 | item2.setText(row[1]) 386 | item2.setFlags(Qt.ItemIsEnabled) 387 | 388 | window1.ui.tableWidget.setItem(row_count, 0, item1) 389 | window1.ui.tableWidget.setItem(row_count, 1, item2) 390 | window1.ui.tableWidget.setCellWidget(row_count, 2, self.button_workspace_for_row(str(row[0]), str(row[1]))) 391 | window1.ui.tableWidget.setCellWidget(row_count, 3, self.button_output_for_row(str(row[0]), str(row[1]))) 392 | window1.ui.tableWidget.setCellWidget(row_count, 4, self.button_delete_for_row(str(row[0]))) 393 | 394 | window1.ui.tableWidget.resizeColumnsToContents() # 表格列宽自动调整 395 | 396 | def button_workspace_for_row(self, name, path): 397 | input_btn = QPushButton('进入') 398 | input_btn.clicked.connect(lambda: self.to_workspace(name)) 399 | if not utils.is_sound_file_ok(path): 400 | input_btn.setEnabled(False) 401 | input_btn.setText("音频缺失") 402 | 403 | return input_btn 404 | 405 | def button_delete_for_row(self, name): 406 | input_btn = QPushButton('删除') 407 | input_btn.clicked.connect(lambda: self.is_delete_box(name)) 408 | return input_btn 409 | 410 | def button_output_for_row(self, name, path): 411 | input_btn = QPushButton('导出数据集') 412 | input_btn.clicked.connect(lambda: self.to_outputfile(name)) 413 | if not utils.is_sound_file_ok(path): 414 | input_btn.setEnabled(False) 415 | input_btn.setText("音频缺失") 416 | return input_btn 417 | 418 | def get_row_info(self): 419 | db = global_obj.get_value("db") 420 | row_info = [] 421 | tables_list = db.select_tables_list() 422 | for table in tables_list: 423 | if table.startswith("_"): 424 | continue 425 | file_path = db.select_sound_path(table) 426 | row_info.append([table, file_path]) 427 | return row_info 428 | 429 | def is_delete_box(self, name): 430 | # 看来不是这么改的 431 | # yes_btn = QMessageBox.Yes 432 | # yes_btn.setText("是") 433 | # no_btn = QMessageBox.No 434 | # no_btn.setText("否") 435 | is_delete = QMessageBox.question(self, "删除数据集", 436 | f"确定删除数据集 {name} ?\n删除后你可以在数据库中手动将其找回", 437 | QMessageBox.Yes | QMessageBox.No, 438 | QMessageBox.No) 439 | if is_delete == QMessageBox.Yes: 440 | self.delete_table(name) 441 | 442 | def delete_table(self, name): 443 | db = global_obj.get_value("db") 444 | db.delete_sound_table(name) 445 | self.table_refresh() 446 | 447 | 448 | class InputDataWindow(QMainWindow): 449 | def __init__(self): 450 | super(InputDataWindow, self).__init__() 451 | self.ui = ui_inputdata.Ui_MainWindow() 452 | self.ui.setupUi(self) 453 | 454 | def refresh_data(self): 455 | sound_dict = global_obj.get_value("sound_dict") 456 | tables_list = global_obj.get_value("db").select_tables_list() 457 | 458 | # 清空表格 459 | while window3.ui.dataTableWidget.rowCount() != 0: 460 | window3.ui.dataTableWidget.removeRow(0) 461 | 462 | for key in sound_dict.keys(): 463 | # print(key) 464 | if sound_dict[key][0] == "" or sound_dict[key][1] == "": 465 | continue 466 | if sound_dict[key][1].count("/output/") != 0: 467 | continue 468 | row_count = window3.ui.dataTableWidget.rowCount() 469 | window3.ui.dataTableWidget.insertRow(row_count) 470 | item1 = QTableWidgetItem() 471 | item1.setText(key) 472 | item1.setFlags(Qt.ItemIsEnabled) 473 | item2 = QTableWidgetItem() 474 | item2.setText(sound_dict[key][0] + "," + sound_dict[key][1]) 475 | item2.setFlags(Qt.ItemIsEnabled) 476 | 477 | window3.ui.dataTableWidget.setItem(row_count, 0, item1) 478 | window3.ui.dataTableWidget.setItem(row_count, 1, item2) 479 | window3.ui.dataTableWidget.setCellWidget(row_count, 2, self.button_for_row(str(key), tables_list)) 480 | window3.ui.dataTableWidget.resizeColumnsToContents() # 宽高自适应 481 | 482 | def input_file(self, name, input_btn): 483 | print(f"导入文件 {name}") 484 | db = global_obj.get_value("db") 485 | db.create_sound_table(name) 486 | file_path = global_obj.get_value("sound_dict")[name] 487 | mysrt = pysrt.open(file_path[0]) 488 | input_list = [] 489 | for part in mysrt: 490 | input_list.append([part.text, part.start.ordinal, part.end.ordinal]) 491 | db.insert_sound_line(input_list, file_path[1], name) 492 | if db.select_tables_list().count(name) != 0: 493 | input_btn.setEnabled(False) 494 | input_btn.setText("已导入") 495 | 496 | def double_clicked_file(self, a): 497 | print(f"导入文件 {a}") 498 | 499 | def back_to_main(self): 500 | print(f"返回首页") 501 | window3.close() 502 | window1.refresh_data() 503 | window1.show() 504 | 505 | def button_for_row(self, name, tables_list): 506 | if tables_list.count(name) == 0: 507 | input_btn = QPushButton('导入') 508 | input_btn.clicked.connect(lambda: self.input_file(name, input_btn)) 509 | else: 510 | input_btn = QPushButton('已导入') 511 | input_btn.clicked.connect(lambda: self.input_file(name, input_btn)) 512 | input_btn.setEnabled(False) 513 | return input_btn 514 | 515 | 516 | class WaitWindow(QFrame): # 注意这里要写QFrame 具体请看QT设计师里的父窗口类名 517 | def __init__(self): 518 | super(WaitWindow, self).__init__() 519 | self.ui = ui_wait.Ui_widget() 520 | self.ui.setupUi(self) 521 | 522 | 523 | def main(): 524 | app = QApplication([]) 525 | 526 | # coder 不怎么机灵 527 | global window1 528 | global window2 529 | global window3 530 | global window4 531 | window1 = MainWindow() 532 | window1.refresh_data() 533 | window2 = WorkSpaceWindow() 534 | window3 = InputDataWindow() 535 | window4 = WaitWindow() 536 | window1.show() 537 | # window4.show() 538 | 539 | app.exec() 540 | # sys.exit(app.exec()) 541 | 542 | 543 | if __name__ == '__main__': 544 | main() 545 | -------------------------------------------------------------------------------- /ui/ui_gui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ################################################################################ 4 | ## Form generated from reading UI file 'gui.ui' 5 | ## 6 | ## Created by: Qt User Interface Compiler version 6.3.0 7 | ## 8 | ## WARNING! All changes made in this file will be lost when recompiling UI file! 9 | ################################################################################ 10 | 11 | from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, 12 | QMetaObject, QObject, QPoint, QRect, 13 | QSize, QTime, QUrl, Qt) 14 | from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, 15 | QFont, QFontDatabase, QGradient, QIcon, 16 | QImage, QKeySequence, QLinearGradient, QPainter, 17 | QPalette, QPixmap, QRadialGradient, QTransform) 18 | from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QGridLayout, 19 | QGroupBox, QHBoxLayout, QHeaderView, QLabel, 20 | QLayout, QLineEdit, QPushButton, QRadioButton, 21 | QSizePolicy, QTableWidget, QTableWidgetItem, QVBoxLayout, 22 | QWidget) 23 | 24 | class Ui_Mainwindow(object): 25 | def setupUi(self, Mainwindow): 26 | if not Mainwindow.objectName(): 27 | Mainwindow.setObjectName(u"Mainwindow") 28 | Mainwindow.resize(723, 799) 29 | Mainwindow.setMinimumSize(QSize(0, 0)) 30 | self.verticalLayout = QVBoxLayout(Mainwindow) 31 | self.verticalLayout.setObjectName(u"verticalLayout") 32 | self.verticalLayout.setSizeConstraint(QLayout.SetMinAndMaxSize) 33 | self.groupBox_6 = QGroupBox(Mainwindow) 34 | self.groupBox_6.setObjectName(u"groupBox_6") 35 | font = QFont() 36 | font.setPointSize(16) 37 | self.groupBox_6.setFont(font) 38 | self.gridLayout = QGridLayout(self.groupBox_6) 39 | self.gridLayout.setObjectName(u"gridLayout") 40 | self.verticalLayout_2 = QVBoxLayout() 41 | self.verticalLayout_2.setObjectName(u"verticalLayout_2") 42 | self.widget_2 = QWidget(self.groupBox_6) 43 | self.widget_2.setObjectName(u"widget_2") 44 | self.verticalLayout_5 = QVBoxLayout(self.widget_2) 45 | self.verticalLayout_5.setObjectName(u"verticalLayout_5") 46 | self.widget_4 = QWidget(self.widget_2) 47 | self.widget_4.setObjectName(u"widget_4") 48 | self.horizontalLayout_3 = QHBoxLayout(self.widget_4) 49 | self.horizontalLayout_3.setSpacing(6) 50 | self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") 51 | self.horizontalLayout_3.setContentsMargins(2, 2, 2, 2) 52 | self.label_2 = QLabel(self.widget_4) 53 | self.label_2.setObjectName(u"label_2") 54 | 55 | self.horizontalLayout_3.addWidget(self.label_2) 56 | 57 | self.lineEdit_2 = QLineEdit(self.widget_4) 58 | self.lineEdit_2.setObjectName(u"lineEdit_2") 59 | 60 | self.horizontalLayout_3.addWidget(self.lineEdit_2) 61 | 62 | self.pushButton_start_100 = QPushButton(self.widget_4) 63 | self.pushButton_start_100.setObjectName(u"pushButton_start_100") 64 | font1 = QFont() 65 | font1.setPointSize(10) 66 | self.pushButton_start_100.setFont(font1) 67 | self.pushButton_start_100.setIconSize(QSize(14, 14)) 68 | 69 | self.horizontalLayout_3.addWidget(self.pushButton_start_100) 70 | 71 | self.pushButton_start_200 = QPushButton(self.widget_4) 72 | self.pushButton_start_200.setObjectName(u"pushButton_start_200") 73 | self.pushButton_start_200.setFont(font1) 74 | self.pushButton_start_200.setIconSize(QSize(14, 14)) 75 | 76 | self.horizontalLayout_3.addWidget(self.pushButton_start_200) 77 | 78 | self.pushButton_start_500 = QPushButton(self.widget_4) 79 | self.pushButton_start_500.setObjectName(u"pushButton_start_500") 80 | self.pushButton_start_500.setFont(font1) 81 | self.pushButton_start_500.setIconSize(QSize(14, 14)) 82 | 83 | self.horizontalLayout_3.addWidget(self.pushButton_start_500) 84 | 85 | self.pushButton_start_100_n = QPushButton(self.widget_4) 86 | self.pushButton_start_100_n.setObjectName(u"pushButton_start_100_n") 87 | self.pushButton_start_100_n.setFont(font1) 88 | self.pushButton_start_100_n.setIconSize(QSize(14, 14)) 89 | 90 | self.horizontalLayout_3.addWidget(self.pushButton_start_100_n) 91 | 92 | self.pushButton_start_200_n = QPushButton(self.widget_4) 93 | self.pushButton_start_200_n.setObjectName(u"pushButton_start_200_n") 94 | self.pushButton_start_200_n.setFont(font1) 95 | self.pushButton_start_200_n.setIconSize(QSize(14, 14)) 96 | 97 | self.horizontalLayout_3.addWidget(self.pushButton_start_200_n) 98 | 99 | self.pushButton_start_500_n = QPushButton(self.widget_4) 100 | self.pushButton_start_500_n.setObjectName(u"pushButton_start_500_n") 101 | self.pushButton_start_500_n.setFont(font1) 102 | self.pushButton_start_500_n.setIconSize(QSize(14, 14)) 103 | 104 | self.horizontalLayout_3.addWidget(self.pushButton_start_500_n) 105 | 106 | 107 | self.verticalLayout_5.addWidget(self.widget_4) 108 | 109 | self.widget_5 = QWidget(self.widget_2) 110 | self.widget_5.setObjectName(u"widget_5") 111 | self.horizontalLayout_4 = QHBoxLayout(self.widget_5) 112 | self.horizontalLayout_4.setObjectName(u"horizontalLayout_4") 113 | self.horizontalLayout_4.setContentsMargins(2, 2, 2, 2) 114 | self.label_3 = QLabel(self.widget_5) 115 | self.label_3.setObjectName(u"label_3") 116 | 117 | self.horizontalLayout_4.addWidget(self.label_3) 118 | 119 | self.lineEdit_3 = QLineEdit(self.widget_5) 120 | self.lineEdit_3.setObjectName(u"lineEdit_3") 121 | 122 | self.horizontalLayout_4.addWidget(self.lineEdit_3) 123 | 124 | self.pushButton_end_100 = QPushButton(self.widget_5) 125 | self.pushButton_end_100.setObjectName(u"pushButton_end_100") 126 | self.pushButton_end_100.setFont(font1) 127 | self.pushButton_end_100.setIconSize(QSize(14, 14)) 128 | 129 | self.horizontalLayout_4.addWidget(self.pushButton_end_100) 130 | 131 | self.pushButton_end_200 = QPushButton(self.widget_5) 132 | self.pushButton_end_200.setObjectName(u"pushButton_end_200") 133 | self.pushButton_end_200.setFont(font1) 134 | self.pushButton_end_200.setIconSize(QSize(14, 14)) 135 | 136 | self.horizontalLayout_4.addWidget(self.pushButton_end_200) 137 | 138 | self.pushButton_end_500 = QPushButton(self.widget_5) 139 | self.pushButton_end_500.setObjectName(u"pushButton_end_500") 140 | self.pushButton_end_500.setFont(font1) 141 | self.pushButton_end_500.setIconSize(QSize(14, 14)) 142 | 143 | self.horizontalLayout_4.addWidget(self.pushButton_end_500) 144 | 145 | self.pushButton_end_100_n = QPushButton(self.widget_5) 146 | self.pushButton_end_100_n.setObjectName(u"pushButton_end_100_n") 147 | self.pushButton_end_100_n.setFont(font1) 148 | self.pushButton_end_100_n.setIconSize(QSize(14, 14)) 149 | 150 | self.horizontalLayout_4.addWidget(self.pushButton_end_100_n) 151 | 152 | self.pushButton_end_200_n = QPushButton(self.widget_5) 153 | self.pushButton_end_200_n.setObjectName(u"pushButton_end_200_n") 154 | self.pushButton_end_200_n.setFont(font1) 155 | self.pushButton_end_200_n.setIconSize(QSize(14, 14)) 156 | 157 | self.horizontalLayout_4.addWidget(self.pushButton_end_200_n) 158 | 159 | self.pushButton_end_500_n = QPushButton(self.widget_5) 160 | self.pushButton_end_500_n.setObjectName(u"pushButton_end_500_n") 161 | self.pushButton_end_500_n.setFont(font1) 162 | self.pushButton_end_500_n.setIconSize(QSize(14, 14)) 163 | 164 | self.horizontalLayout_4.addWidget(self.pushButton_end_500_n) 165 | 166 | 167 | self.verticalLayout_5.addWidget(self.widget_5) 168 | 169 | self.widget_6 = QWidget(self.widget_2) 170 | self.widget_6.setObjectName(u"widget_6") 171 | self.horizontalLayout_5 = QHBoxLayout(self.widget_6) 172 | self.horizontalLayout_5.setObjectName(u"horizontalLayout_5") 173 | self.label_4 = QLabel(self.widget_6) 174 | self.label_4.setObjectName(u"label_4") 175 | self.label_4.setFont(font1) 176 | 177 | self.horizontalLayout_5.addWidget(self.label_4) 178 | 179 | self.pushButton_4 = QPushButton(self.widget_6) 180 | self.pushButton_4.setObjectName(u"pushButton_4") 181 | 182 | self.horizontalLayout_5.addWidget(self.pushButton_4) 183 | 184 | self.widget_8 = QWidget(self.widget_6) 185 | self.widget_8.setObjectName(u"widget_8") 186 | sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) 187 | sizePolicy.setHorizontalStretch(0) 188 | sizePolicy.setVerticalStretch(0) 189 | sizePolicy.setHeightForWidth(self.widget_8.sizePolicy().hasHeightForWidth()) 190 | self.widget_8.setSizePolicy(sizePolicy) 191 | self.widget_8.setMinimumSize(QSize(0, 0)) 192 | self.widget_8.setFont(font1) 193 | self.widget_8.setLayoutDirection(Qt.LeftToRight) 194 | self.verticalLayout_6 = QVBoxLayout(self.widget_8) 195 | self.verticalLayout_6.setSpacing(0) 196 | self.verticalLayout_6.setObjectName(u"verticalLayout_6") 197 | self.verticalLayout_6.setContentsMargins(0, 0, 0, 0) 198 | self.checkBox = QCheckBox(self.widget_8) 199 | self.checkBox.setObjectName(u"checkBox") 200 | font2 = QFont() 201 | font2.setPointSize(12) 202 | self.checkBox.setFont(font2) 203 | 204 | self.verticalLayout_6.addWidget(self.checkBox) 205 | 206 | self.checkBox_2 = QCheckBox(self.widget_8) 207 | self.checkBox_2.setObjectName(u"checkBox_2") 208 | self.checkBox_2.setFont(font2) 209 | 210 | self.verticalLayout_6.addWidget(self.checkBox_2) 211 | 212 | 213 | self.horizontalLayout_5.addWidget(self.widget_8) 214 | 215 | 216 | self.verticalLayout_5.addWidget(self.widget_6) 217 | 218 | 219 | self.verticalLayout_2.addWidget(self.widget_2) 220 | 221 | self.pushButton_5 = QPushButton(self.groupBox_6) 222 | self.pushButton_5.setObjectName(u"pushButton_5") 223 | sizePolicy1 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) 224 | sizePolicy1.setHorizontalStretch(3) 225 | sizePolicy1.setVerticalStretch(0) 226 | sizePolicy1.setHeightForWidth(self.pushButton_5.sizePolicy().hasHeightForWidth()) 227 | self.pushButton_5.setSizePolicy(sizePolicy1) 228 | self.pushButton_5.setFont(font) 229 | 230 | self.verticalLayout_2.addWidget(self.pushButton_5) 231 | 232 | self.widget = QWidget(self.groupBox_6) 233 | self.widget.setObjectName(u"widget") 234 | sizePolicy2 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) 235 | sizePolicy2.setHorizontalStretch(0) 236 | sizePolicy2.setVerticalStretch(0) 237 | sizePolicy2.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth()) 238 | self.widget.setSizePolicy(sizePolicy2) 239 | self.horizontalLayout_2 = QHBoxLayout(self.widget) 240 | self.horizontalLayout_2.setSpacing(6) 241 | self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") 242 | self.horizontalLayout_2.setSizeConstraint(QLayout.SetDefaultConstraint) 243 | self.horizontalLayout_2.setContentsMargins(9, -1, -1, 9) 244 | self.pushButton = QPushButton(self.widget) 245 | self.pushButton.setObjectName(u"pushButton") 246 | sizePolicy3 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) 247 | sizePolicy3.setHorizontalStretch(2) 248 | sizePolicy3.setVerticalStretch(0) 249 | sizePolicy3.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth()) 250 | self.pushButton.setSizePolicy(sizePolicy3) 251 | self.pushButton.setFont(font) 252 | 253 | self.horizontalLayout_2.addWidget(self.pushButton) 254 | 255 | self.pushButton_3 = QPushButton(self.widget) 256 | self.pushButton_3.setObjectName(u"pushButton_3") 257 | sizePolicy1.setHeightForWidth(self.pushButton_3.sizePolicy().hasHeightForWidth()) 258 | self.pushButton_3.setSizePolicy(sizePolicy1) 259 | self.pushButton_3.setFont(font) 260 | 261 | self.horizontalLayout_2.addWidget(self.pushButton_3) 262 | 263 | self.pushButton_2 = QPushButton(self.widget) 264 | self.pushButton_2.setObjectName(u"pushButton_2") 265 | sizePolicy3.setHeightForWidth(self.pushButton_2.sizePolicy().hasHeightForWidth()) 266 | self.pushButton_2.setSizePolicy(sizePolicy3) 267 | self.pushButton_2.setFont(font) 268 | 269 | self.horizontalLayout_2.addWidget(self.pushButton_2) 270 | 271 | 272 | self.verticalLayout_2.addWidget(self.widget) 273 | 274 | 275 | self.gridLayout.addLayout(self.verticalLayout_2, 1, 0, 1, 1) 276 | 277 | 278 | self.verticalLayout.addWidget(self.groupBox_6) 279 | 280 | self.groupBox = QGroupBox(Mainwindow) 281 | self.groupBox.setObjectName(u"groupBox") 282 | self.groupBox.setFont(font) 283 | self.gridLayout_2 = QGridLayout(self.groupBox) 284 | self.gridLayout_2.setObjectName(u"gridLayout_2") 285 | self.lineEdit = QLineEdit(self.groupBox) 286 | self.lineEdit.setObjectName(u"lineEdit") 287 | 288 | self.gridLayout_2.addWidget(self.lineEdit, 0, 0, 1, 1) 289 | 290 | self.widget_3 = QWidget(self.groupBox) 291 | self.widget_3.setObjectName(u"widget_3") 292 | self.horizontalLayout = QHBoxLayout(self.widget_3) 293 | self.horizontalLayout.setObjectName(u"horizontalLayout") 294 | self.groupBox_2 = QGroupBox(self.widget_3) 295 | self.groupBox_2.setObjectName(u"groupBox_2") 296 | sizePolicy4 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) 297 | sizePolicy4.setHorizontalStretch(0) 298 | sizePolicy4.setVerticalStretch(0) 299 | sizePolicy4.setHeightForWidth(self.groupBox_2.sizePolicy().hasHeightForWidth()) 300 | self.groupBox_2.setSizePolicy(sizePolicy4) 301 | self.verticalLayout_3 = QVBoxLayout(self.groupBox_2) 302 | self.verticalLayout_3.setObjectName(u"verticalLayout_3") 303 | self.radioButton = QRadioButton(self.groupBox_2) 304 | self.radioButton.setObjectName(u"radioButton") 305 | 306 | self.verticalLayout_3.addWidget(self.radioButton) 307 | 308 | self.radioButton_2 = QRadioButton(self.groupBox_2) 309 | self.radioButton_2.setObjectName(u"radioButton_2") 310 | 311 | self.verticalLayout_3.addWidget(self.radioButton_2) 312 | 313 | self.label_6 = QLabel(self.groupBox_2) 314 | self.label_6.setObjectName(u"label_6") 315 | self.label_6.setFont(font1) 316 | 317 | self.verticalLayout_3.addWidget(self.label_6) 318 | 319 | self.comboBox = QComboBox(self.groupBox_2) 320 | self.comboBox.addItem("") 321 | self.comboBox.setObjectName(u"comboBox") 322 | sizePolicy5 = QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) 323 | sizePolicy5.setHorizontalStretch(0) 324 | sizePolicy5.setVerticalStretch(0) 325 | sizePolicy5.setHeightForWidth(self.comboBox.sizePolicy().hasHeightForWidth()) 326 | self.comboBox.setSizePolicy(sizePolicy5) 327 | self.comboBox.setMaximumSize(QSize(16777215, 16777215)) 328 | self.comboBox.setFont(font1) 329 | self.comboBox.setIconSize(QSize(16, 16)) 330 | 331 | self.verticalLayout_3.addWidget(self.comboBox) 332 | 333 | self.label = QLabel(self.groupBox_2) 334 | self.label.setObjectName(u"label") 335 | self.label.setFont(font1) 336 | 337 | self.verticalLayout_3.addWidget(self.label) 338 | 339 | self.label_5 = QLabel(self.groupBox_2) 340 | self.label_5.setObjectName(u"label_5") 341 | sizePolicy2.setHeightForWidth(self.label_5.sizePolicy().hasHeightForWidth()) 342 | self.label_5.setSizePolicy(sizePolicy2) 343 | self.label_5.setFont(font2) 344 | 345 | self.verticalLayout_3.addWidget(self.label_5) 346 | 347 | self.pushButton_6 = QPushButton(self.groupBox_2) 348 | self.pushButton_6.setObjectName(u"pushButton_6") 349 | self.pushButton_6.setFont(font2) 350 | 351 | self.verticalLayout_3.addWidget(self.pushButton_6) 352 | 353 | self.pushButton_7 = QPushButton(self.groupBox_2) 354 | self.pushButton_7.setObjectName(u"pushButton_7") 355 | self.pushButton_7.setFont(font2) 356 | 357 | self.verticalLayout_3.addWidget(self.pushButton_7) 358 | 359 | 360 | self.horizontalLayout.addWidget(self.groupBox_2) 361 | 362 | self.groupBox_3 = QGroupBox(self.widget_3) 363 | self.groupBox_3.setObjectName(u"groupBox_3") 364 | self.groupBox_3.setMaximumSize(QSize(525, 16777215)) 365 | self.groupBox_3.setFont(font) 366 | self.verticalLayout_4 = QVBoxLayout(self.groupBox_3) 367 | self.verticalLayout_4.setObjectName(u"verticalLayout_4") 368 | self.widget_7 = QWidget(self.groupBox_3) 369 | self.widget_7.setObjectName(u"widget_7") 370 | self.widget_7.setFont(font1) 371 | self.horizontalLayout_6 = QHBoxLayout(self.widget_7) 372 | self.horizontalLayout_6.setObjectName(u"horizontalLayout_6") 373 | self.tableWidget = QTableWidget(self.widget_7) 374 | if (self.tableWidget.columnCount() < 4): 375 | self.tableWidget.setColumnCount(4) 376 | __qtablewidgetitem = QTableWidgetItem() 377 | self.tableWidget.setHorizontalHeaderItem(0, __qtablewidgetitem) 378 | __qtablewidgetitem1 = QTableWidgetItem() 379 | self.tableWidget.setHorizontalHeaderItem(1, __qtablewidgetitem1) 380 | __qtablewidgetitem2 = QTableWidgetItem() 381 | self.tableWidget.setHorizontalHeaderItem(2, __qtablewidgetitem2) 382 | __qtablewidgetitem3 = QTableWidgetItem() 383 | self.tableWidget.setHorizontalHeaderItem(3, __qtablewidgetitem3) 384 | if (self.tableWidget.rowCount() < 2): 385 | self.tableWidget.setRowCount(2) 386 | __qtablewidgetitem4 = QTableWidgetItem() 387 | self.tableWidget.setVerticalHeaderItem(0, __qtablewidgetitem4) 388 | __qtablewidgetitem5 = QTableWidgetItem() 389 | self.tableWidget.setVerticalHeaderItem(1, __qtablewidgetitem5) 390 | __qtablewidgetitem6 = QTableWidgetItem() 391 | self.tableWidget.setItem(0, 0, __qtablewidgetitem6) 392 | __qtablewidgetitem7 = QTableWidgetItem() 393 | self.tableWidget.setItem(0, 1, __qtablewidgetitem7) 394 | __qtablewidgetitem8 = QTableWidgetItem() 395 | self.tableWidget.setItem(0, 2, __qtablewidgetitem8) 396 | self.tableWidget.setObjectName(u"tableWidget") 397 | self.tableWidget.setMaximumSize(QSize(16777215, 16777215)) 398 | self.tableWidget.setFont(font1) 399 | self.tableWidget.viewport().setProperty("cursor", QCursor(Qt.ArrowCursor)) 400 | self.tableWidget.setFocusPolicy(Qt.StrongFocus) 401 | self.tableWidget.setContextMenuPolicy(Qt.DefaultContextMenu) 402 | 403 | self.horizontalLayout_6.addWidget(self.tableWidget) 404 | 405 | 406 | self.verticalLayout_4.addWidget(self.widget_7) 407 | 408 | 409 | self.horizontalLayout.addWidget(self.groupBox_3) 410 | 411 | self.horizontalLayout.setStretch(0, 1) 412 | self.horizontalLayout.setStretch(1, 5) 413 | 414 | self.gridLayout_2.addWidget(self.widget_3, 1, 0, 1, 1) 415 | 416 | 417 | self.verticalLayout.addWidget(self.groupBox) 418 | 419 | 420 | self.retranslateUi(Mainwindow) 421 | self.pushButton_4.clicked.connect(Mainwindow.click_refreshBTN) 422 | self.pushButton_5.clicked.connect(Mainwindow.click_play_soundBTN) 423 | self.pushButton.clicked.connect(Mainwindow.click_backBTN) 424 | self.pushButton_2.clicked.connect(Mainwindow.click_nextBTN) 425 | self.pushButton_3.clicked.connect(Mainwindow.click_checkBTN) 426 | self.pushButton_6.clicked.connect(Mainwindow.click_output_now) 427 | self.pushButton_7.clicked.connect(Mainwindow.click_back_to_main) 428 | self.pushButton_start_100.clicked.connect(Mainwindow.click_change_start_BTN) 429 | self.pushButton_start_200.clicked.connect(Mainwindow.click_change_start_BTN) 430 | self.pushButton_start_500.clicked.connect(Mainwindow.click_change_start_BTN) 431 | self.pushButton_start_500_n.clicked.connect(Mainwindow.click_change_start_BTN) 432 | self.pushButton_start_200_n.clicked.connect(Mainwindow.click_change_start_BTN) 433 | self.pushButton_start_100_n.clicked.connect(Mainwindow.click_change_start_BTN) 434 | self.pushButton_end_100.clicked.connect(Mainwindow.click_change_end_BTN) 435 | self.pushButton_end_200.clicked.connect(Mainwindow.click_change_end_BTN) 436 | self.pushButton_end_500.clicked.connect(Mainwindow.click_change_end_BTN) 437 | self.pushButton_end_500_n.clicked.connect(Mainwindow.click_change_end_BTN) 438 | self.pushButton_end_200_n.clicked.connect(Mainwindow.click_change_end_BTN) 439 | self.pushButton_end_100_n.clicked.connect(Mainwindow.click_change_end_BTN) 440 | 441 | QMetaObject.connectSlotsByName(Mainwindow) 442 | # setupUi 443 | 444 | def retranslateUi(self, Mainwindow): 445 | Mainwindow.setWindowTitle(QCoreApplication.translate("Mainwindow", u"\u8bed\u97f3\u6807\u8bb0", None)) 446 | self.groupBox_6.setTitle(QCoreApplication.translate("Mainwindow", u"\u97f3\u9891\u4fe1\u606f", None)) 447 | self.label_2.setText(QCoreApplication.translate("Mainwindow", u"\u5f00\u59cb\u65f6\u95f4", None)) 448 | self.pushButton_start_100.setText(QCoreApplication.translate("Mainwindow", u"+100", None)) 449 | self.pushButton_start_200.setText(QCoreApplication.translate("Mainwindow", u"+200", None)) 450 | self.pushButton_start_500.setText(QCoreApplication.translate("Mainwindow", u"+500", None)) 451 | self.pushButton_start_100_n.setText(QCoreApplication.translate("Mainwindow", u"-100", None)) 452 | self.pushButton_start_200_n.setText(QCoreApplication.translate("Mainwindow", u"-200", None)) 453 | self.pushButton_start_500_n.setText(QCoreApplication.translate("Mainwindow", u"-500", None)) 454 | self.label_3.setText(QCoreApplication.translate("Mainwindow", u"\u7ed3\u675f\u65f6\u95f4", None)) 455 | self.pushButton_end_100.setText(QCoreApplication.translate("Mainwindow", u"+100", None)) 456 | self.pushButton_end_200.setText(QCoreApplication.translate("Mainwindow", u"+200", None)) 457 | self.pushButton_end_500.setText(QCoreApplication.translate("Mainwindow", u"+500", None)) 458 | self.pushButton_end_100_n.setText(QCoreApplication.translate("Mainwindow", u"-100", None)) 459 | self.pushButton_end_200_n.setText(QCoreApplication.translate("Mainwindow", u"-200", None)) 460 | self.pushButton_end_500_n.setText(QCoreApplication.translate("Mainwindow", u"-500", None)) 461 | self.label_4.setText(QCoreApplication.translate("Mainwindow", u"\u5982\u679c\u4f60\u89c9\u5f97\u65f6\u95f4\u5207\u7684\u4e0d\u597d\uff0c\u8bf7\u4fee\u6539\u8fd9\u91cc\u7684\u8d77\u6b62\u65f6\u95f4\n" 462 | "\uff08\u5355\u4f4d\uff1a\u6beb\u79d2\uff09\u4fee\u6539\u540e\u70b9\u51fb\u64ad\u653e\u97f3\u9891\u53ef\u4ee5\u67e5\u770b\u6548\u679c\n" 463 | "\uff0c\u622a\u53d6\u5408\u9002\u540e\u70b9\u51fb\u786e\u5b9a\u6807\u6ce8\u624d\u80fd\u4fdd\u5b58\u4fee\u6539", None)) 464 | self.pushButton_4.setText(QCoreApplication.translate("Mainwindow", u"\u5237\u65b0\u6570\u636e\u5217\u8868", None)) 465 | self.checkBox.setText(QCoreApplication.translate("Mainwindow", u"\u5207\u6362\u6761\u76ee\u540e\u81ea\u52a8\u64ad\u653e", None)) 466 | self.checkBox_2.setText(QCoreApplication.translate("Mainwindow", u"\u786e\u5b9a\u6807\u6ce8\u540e\u81ea\u52a8\u8df3\u5230\u4e0b\u4e00\u6761", None)) 467 | self.pushButton_5.setText(QCoreApplication.translate("Mainwindow", u"\u64ad\u653e\u97f3\u9891(W)", None)) 468 | #if QT_CONFIG(shortcut) 469 | self.pushButton_5.setShortcut(QCoreApplication.translate("Mainwindow", u"W", None)) 470 | #endif // QT_CONFIG(shortcut) 471 | self.pushButton.setText(QCoreApplication.translate("Mainwindow", u"\u4e0a\u4e00\u6761(A)", None)) 472 | #if QT_CONFIG(shortcut) 473 | self.pushButton.setShortcut(QCoreApplication.translate("Mainwindow", u"A", None)) 474 | #endif // QT_CONFIG(shortcut) 475 | self.pushButton_3.setText(QCoreApplication.translate("Mainwindow", u"\u786e\u5b9a\u6807\u6ce8(S)", None)) 476 | #if QT_CONFIG(shortcut) 477 | self.pushButton_3.setShortcut(QCoreApplication.translate("Mainwindow", u"S", None)) 478 | #endif // QT_CONFIG(shortcut) 479 | self.pushButton_2.setText(QCoreApplication.translate("Mainwindow", u"\u4e0b\u4e00\u6761(D)", None)) 480 | #if QT_CONFIG(shortcut) 481 | self.pushButton_2.setShortcut(QCoreApplication.translate("Mainwindow", u"D", None)) 482 | #endif // QT_CONFIG(shortcut) 483 | self.groupBox.setTitle(QCoreApplication.translate("Mainwindow", u"\u6807\u6ce8\u4fe1\u606f", None)) 484 | self.groupBox_2.setTitle(QCoreApplication.translate("Mainwindow", u"\u662f\u5426\u53ef\u7528", None)) 485 | self.radioButton.setText(QCoreApplication.translate("Mainwindow", u"\u4e0d\u53ef\u7528", None)) 486 | self.radioButton_2.setText(QCoreApplication.translate("Mainwindow", u"\u53ef\u7528", None)) 487 | self.label_6.setText(QCoreApplication.translate("Mainwindow", u"\u9009\u62e9\u97f3\u9891\u64ad\u653e\u8bbe\u5907\n" 488 | "\u6ce8\uff1a\u7b2c\u4e00\u4e2a\u4e3a\u7cfb\u7edf\u9ed8\u8ba4\u8bbe\u5907", None)) 489 | self.comboBox.setItemText(0, QCoreApplication.translate("Mainwindow", u"123", None)) 490 | 491 | self.label.setText(QCoreApplication.translate("Mainwindow", u"\u5982\u679c\u4f60\u89c9\u5f97\u8fd9\u6761\u6548\u679c\n" 492 | "\u592a\u5dee\u4e86\u8bf7\u9009\u62e9\u4e0d\u53ef\u7528", None)) 493 | self.label_5.setText(QCoreApplication.translate("Mainwindow", u"\u5f53\u524d\u7f16\u53f7\uff1a1024", None)) 494 | self.pushButton_6.setText(QCoreApplication.translate("Mainwindow", u"\u5bfc\u51fa\u5f53\u524d\u97f3\u9891", None)) 495 | self.pushButton_7.setText(QCoreApplication.translate("Mainwindow", u"\u8fd4\u56de\u9996\u9875", None)) 496 | self.groupBox_3.setTitle(QCoreApplication.translate("Mainwindow", u"\u6570\u636e\u5217\u8868", None)) 497 | ___qtablewidgetitem = self.tableWidget.horizontalHeaderItem(0) 498 | ___qtablewidgetitem.setText(QCoreApplication.translate("Mainwindow", u"\u6587\u672c", None)); 499 | ___qtablewidgetitem1 = self.tableWidget.horizontalHeaderItem(1) 500 | ___qtablewidgetitem1.setText(QCoreApplication.translate("Mainwindow", u"\u68c0\u67e5\u72b6\u6001", None)); 501 | ___qtablewidgetitem2 = self.tableWidget.horizontalHeaderItem(2) 502 | ___qtablewidgetitem2.setText(QCoreApplication.translate("Mainwindow", u"\u53ef\u7528", None)); 503 | ___qtablewidgetitem3 = self.tableWidget.horizontalHeaderItem(3) 504 | ___qtablewidgetitem3.setText(QCoreApplication.translate("Mainwindow", u"\u64cd\u4f5c", None)); 505 | ___qtablewidgetitem4 = self.tableWidget.verticalHeaderItem(0) 506 | ___qtablewidgetitem4.setText(QCoreApplication.translate("Mainwindow", u"\u65b0\u5efa\u884c", None)); 507 | ___qtablewidgetitem5 = self.tableWidget.verticalHeaderItem(1) 508 | ___qtablewidgetitem5.setText(QCoreApplication.translate("Mainwindow", u"\u65b0\u5efa\u884c", None)); 509 | 510 | __sortingEnabled = self.tableWidget.isSortingEnabled() 511 | self.tableWidget.setSortingEnabled(False) 512 | ___qtablewidgetitem6 = self.tableWidget.item(0, 0) 513 | ___qtablewidgetitem6.setText(QCoreApplication.translate("Mainwindow", u"\u4f60\u597d", None)); 514 | ___qtablewidgetitem7 = self.tableWidget.item(0, 1) 515 | ___qtablewidgetitem7.setText(QCoreApplication.translate("Mainwindow", u"3", None)); 516 | ___qtablewidgetitem8 = self.tableWidget.item(0, 2) 517 | ___qtablewidgetitem8.setText(QCoreApplication.translate("Mainwindow", u"4", None)); 518 | self.tableWidget.setSortingEnabled(__sortingEnabled) 519 | 520 | # retranslateUi 521 | 522 | -------------------------------------------------------------------------------- /ui/gui.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mainwindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 723 10 | 799 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 语音标记 21 | 22 | 23 | 24 | QLayout::SetMinAndMaxSize 25 | 26 | 27 | 28 | 29 | 30 | 16 31 | 32 | 33 | 34 | 音频信息 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 6 47 | 48 | 49 | 2 50 | 51 | 52 | 2 53 | 54 | 55 | 2 56 | 57 | 58 | 2 59 | 60 | 61 | 62 | 63 | 开始时间 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 10 75 | 76 | 77 | 78 | +100 79 | 80 | 81 | 82 | 14 83 | 14 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 10 93 | 94 | 95 | 96 | +200 97 | 98 | 99 | 100 | 14 101 | 14 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 10 111 | 112 | 113 | 114 | +500 115 | 116 | 117 | 118 | 14 119 | 14 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 10 129 | 130 | 131 | 132 | -100 133 | 134 | 135 | 136 | 14 137 | 14 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 10 147 | 148 | 149 | 150 | -200 151 | 152 | 153 | 154 | 14 155 | 14 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 10 165 | 166 | 167 | 168 | -500 169 | 170 | 171 | 172 | 14 173 | 14 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 2 186 | 187 | 188 | 2 189 | 190 | 191 | 2 192 | 193 | 194 | 2 195 | 196 | 197 | 198 | 199 | 结束时间 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 10 211 | 212 | 213 | 214 | +100 215 | 216 | 217 | 218 | 14 219 | 14 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 10 229 | 230 | 231 | 232 | +200 233 | 234 | 235 | 236 | 14 237 | 14 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 10 247 | 248 | 249 | 250 | +500 251 | 252 | 253 | 254 | 14 255 | 14 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 10 265 | 266 | 267 | 268 | -100 269 | 270 | 271 | 272 | 14 273 | 14 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 10 283 | 284 | 285 | 286 | -200 287 | 288 | 289 | 290 | 14 291 | 14 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 10 301 | 302 | 303 | 304 | -500 305 | 306 | 307 | 308 | 14 309 | 14 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 10 325 | 326 | 327 | 328 | 如果你觉得时间切的不好,请修改这里的起止时间 329 | (单位:毫秒)修改后点击播放音频可以查看效果 330 | ,截取合适后点击确定标注才能保存修改 331 | 332 | 333 | 334 | 335 | 336 | 337 | 刷新数据列表 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 0 346 | 0 347 | 348 | 349 | 350 | 351 | 0 352 | 0 353 | 354 | 355 | 356 | 357 | 10 358 | 359 | 360 | 361 | Qt::LeftToRight 362 | 363 | 364 | 365 | 0 366 | 367 | 368 | 0 369 | 370 | 371 | 0 372 | 373 | 374 | 0 375 | 376 | 377 | 0 378 | 379 | 380 | 381 | 382 | 383 | 12 384 | 385 | 386 | 387 | 切换条目后自动播放 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 12 396 | 397 | 398 | 399 | 确定标注后自动跳到下一条 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 3 417 | 0 418 | 419 | 420 | 421 | 422 | 16 423 | 424 | 425 | 426 | 播放音频(W) 427 | 428 | 429 | W 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 0 438 | 0 439 | 440 | 441 | 442 | 443 | 6 444 | 445 | 446 | QLayout::SetDefaultConstraint 447 | 448 | 449 | 9 450 | 451 | 452 | 9 453 | 454 | 455 | 456 | 457 | 458 | 2 459 | 0 460 | 461 | 462 | 463 | 464 | 16 465 | 466 | 467 | 468 | 上一条(A) 469 | 470 | 471 | A 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 3 480 | 0 481 | 482 | 483 | 484 | 485 | 16 486 | 487 | 488 | 489 | 确定标注(S) 490 | 491 | 492 | S 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 2 501 | 0 502 | 503 | 504 | 505 | 506 | 16 507 | 508 | 509 | 510 | 下一条(D) 511 | 512 | 513 | D 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 16 530 | 531 | 532 | 533 | 标注信息 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 0 547 | 0 548 | 549 | 550 | 551 | 是否可用 552 | 553 | 554 | 555 | 556 | 557 | 不可用 558 | 559 | 560 | 561 | 562 | 563 | 564 | 可用 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 10 573 | 574 | 575 | 576 | 选择音频播放设备 577 | 注:第一个为系统默认设备 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 0 586 | 0 587 | 588 | 589 | 590 | 591 | 16777215 592 | 16777215 593 | 594 | 595 | 596 | 597 | 10 598 | 599 | 600 | 601 | 602 | 16 603 | 16 604 | 605 | 606 | 607 | 608 | 123 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 10 618 | 619 | 620 | 621 | 如果你觉得这条效果 622 | 太差了请选择不可用 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 0 631 | 0 632 | 633 | 634 | 635 | 636 | 12 637 | 638 | 639 | 640 | 当前编号:1024 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 12 649 | 650 | 651 | 652 | 导出当前音频 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 12 661 | 662 | 663 | 664 | 返回首页 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 525 676 | 16777215 677 | 678 | 679 | 680 | 681 | 16 682 | 683 | 684 | 685 | 数据列表 686 | 687 | 688 | 689 | 690 | 691 | 692 | 10 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 16777215 701 | 16777215 702 | 703 | 704 | 705 | 706 | 10 707 | 708 | 709 | 710 | ArrowCursor 711 | 712 | 713 | Qt::StrongFocus 714 | 715 | 716 | Qt::DefaultContextMenu 717 | 718 | 719 | 720 | 新建行 721 | 722 | 723 | 724 | 725 | 新建行 726 | 727 | 728 | 729 | 730 | 文本 731 | 732 | 733 | 734 | 735 | 检查状态 736 | 737 | 738 | 739 | 740 | 可用 741 | 742 | 743 | 744 | 745 | 操作 746 | 747 | 748 | 749 | 750 | 你好 751 | 752 | 753 | 754 | 755 | 3 756 | 757 | 758 | 759 | 760 | 4 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | pushButton_4 783 | clicked() 784 | Mainwindow 785 | click_refreshBTN() 786 | 787 | 788 | 478 789 | 190 790 | 791 | 792 | 289 793 | 217 794 | 795 | 796 | 797 | 798 | pushButton_5 799 | clicked() 800 | Mainwindow 801 | click_play_soundBTN() 802 | 803 | 804 | 665 805 | 239 806 | 807 | 808 | 667 809 | 207 810 | 811 | 812 | 813 | 814 | pushButton 815 | clicked() 816 | Mainwindow 817 | click_backBTN() 818 | 819 | 820 | 197 821 | 283 822 | 823 | 824 | 181 825 | 535 826 | 827 | 828 | 829 | 830 | pushButton_2 831 | clicked() 832 | Mainwindow 833 | click_nextBTN() 834 | 835 | 836 | 708 837 | 307 838 | 839 | 840 | 667 841 | 534 842 | 843 | 844 | 845 | 846 | pushButton_3 847 | clicked() 848 | Mainwindow 849 | click_checkBTN() 850 | 851 | 852 | 511 853 | 307 854 | 855 | 856 | 440 857 | 534 858 | 859 | 860 | 861 | 862 | pushButton_6 863 | clicked() 864 | Mainwindow 865 | click_output_now() 866 | 867 | 868 | 154 869 | 725 870 | 871 | 872 | 5 873 | 661 874 | 875 | 876 | 877 | 878 | pushButton_7 879 | clicked() 880 | Mainwindow 881 | click_back_to_main() 882 | 883 | 884 | 154 885 | 760 886 | 887 | 888 | 5 889 | 720 890 | 891 | 892 | 893 | 894 | pushButton_start_100 895 | clicked() 896 | Mainwindow 897 | click_change_start_BTN() 898 | 899 | 900 | 253 901 | 61 902 | 903 | 904 | 239 905 | 3 906 | 907 | 908 | 909 | 910 | pushButton_start_200 911 | clicked() 912 | Mainwindow 913 | click_change_start_BTN() 914 | 915 | 916 | 313 917 | 62 918 | 919 | 920 | 292 921 | -3 922 | 923 | 924 | 925 | 926 | pushButton_start_500 927 | clicked() 928 | Mainwindow 929 | click_change_start_BTN() 930 | 931 | 932 | 411 933 | 66 934 | 935 | 936 | 381 937 | 0 938 | 939 | 940 | 941 | 942 | pushButton_start_500_n 943 | clicked() 944 | Mainwindow 945 | click_change_start_BTN() 946 | 947 | 948 | 706 949 | 84 950 | 951 | 952 | 483 953 | -7 954 | 955 | 956 | 957 | 958 | pushButton_start_200_n 959 | clicked() 960 | Mainwindow 961 | click_change_start_BTN() 962 | 963 | 964 | 588 965 | 66 966 | 967 | 968 | 568 969 | 5 970 | 971 | 972 | 973 | 974 | pushButton_start_100_n 975 | clicked() 976 | Mainwindow 977 | click_change_start_BTN() 978 | 979 | 980 | 544 981 | 84 982 | 983 | 984 | 648 985 | -1 986 | 987 | 988 | 989 | 990 | pushButton_end_100 991 | clicked() 992 | Mainwindow 993 | click_change_end_BTN() 994 | 995 | 996 | 301 997 | 126 998 | 999 | 1000 | 746 1001 | 27 1002 | 1003 | 1004 | 1005 | 1006 | pushButton_end_200 1007 | clicked() 1008 | Mainwindow 1009 | click_change_end_BTN() 1010 | 1011 | 1012 | 347 1013 | 108 1014 | 1015 | 1016 | 781 1017 | 39 1018 | 1019 | 1020 | 1021 | 1022 | pushButton_end_500 1023 | clicked() 1024 | Mainwindow 1025 | click_change_end_BTN() 1026 | 1027 | 1028 | 463 1029 | 126 1030 | 1031 | 1032 | 751 1033 | 55 1034 | 1035 | 1036 | 1037 | 1038 | pushButton_end_500_n 1039 | clicked() 1040 | Mainwindow 1041 | click_change_end_BTN() 1042 | 1043 | 1044 | 706 1045 | 126 1046 | 1047 | 1048 | 772 1049 | 81 1050 | 1051 | 1052 | 1053 | 1054 | pushButton_end_200_n 1055 | clicked() 1056 | Mainwindow 1057 | click_change_end_BTN() 1058 | 1059 | 1060 | 607 1061 | 113 1062 | 1063 | 1064 | 758 1065 | 103 1066 | 1067 | 1068 | 1069 | 1070 | pushButton_end_100_n 1071 | clicked() 1072 | Mainwindow 1073 | click_change_end_BTN() 1074 | 1075 | 1076 | 544 1077 | 126 1078 | 1079 | 1080 | 796 1081 | 129 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | click_refreshBTN() 1088 | click_play_soundBTN() 1089 | click_backBTN() 1090 | click_nextBTN() 1091 | click_checkBTN() 1092 | click_table() 1093 | click_output_now() 1094 | click_back_to_main() 1095 | click_change_start_BTN() 1096 | click_change_end_BTN() 1097 | 1098 | 1099 | --------------------------------------------------------------------------------