Commit 69305eb1 authored by xuanweiace's avatar xuanweiace

upd 新增对字幕和旁白表格的支持 并支持毫秒级视频运行时间的展示

parent 23b4ef50
# accessibility_movie_2
二期的无障碍电影制作工具,主要包含旁白区间检测和旁白及字幕导出两个功能; 二期主要提升用户体验、产品功能与易用性,设计成熟的操作界面进行人机交互,另外为了方便用户使用,使用pyinstaller进行打包。
\ No newline at end of file
二期的无障碍电影制作工具,主要包含旁白区间检测和旁白及字幕导出两个功能; 二期主要提升用户体验、产品功能与易用性,设计成熟的操作界面进行人机交互,另外为了方便用户使用,使用pyinstaller进行打包。
注意要自行下载mp4的解码器,不然无法播放视频
\ No newline at end of file
......@@ -34,6 +34,7 @@ def create_sheet(path: str, sheet_name: str, value: list):
"""
index = len(value)
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = sheet_name
# 将字幕对应的那一列扩宽一些
......@@ -109,6 +110,8 @@ def detect_with_asr(video_path: str, book_path: str, start_time=0, end_time=-1,
if __name__ == '__main__':
create_sheet("./xxxxxx.xlsx", "abc", [["起始时间", "终止时间", "字幕", '建议', '解说脚本']])
# write_to_sheet("./xxx.xlsx", "abc", ["qssj", "zzsj", "zm", 'jy', 'pb'])
pass
# start_time = time.time()
# # 给定待处理的视频路径
......
......@@ -2,10 +2,11 @@ import time
import os
import cv2
from PyQt5.QtWidgets import QMainWindow, QFileDialog
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QTableWidget, QTableWidgetItem
import utils
from management import RunThread
from utils import validate_and_get_filepath
from management import RunThread, ProjectContext, Element
from detect_dialog import Detect_Dialog
from assemble_dialog import Assemble_Dialog
from synthesis import SynthesisProcessor
......@@ -20,6 +21,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
super(MainWindow, self).__init__()
self.setupUi(self)
self.statusbar.showMessage("hello", 5000)
self.projectContext = ProjectContext()
# 语音合成相关组件
# todo:后续改成QThread的组件
......@@ -30,21 +32,24 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.detect_dialog.start_detect_signal.connect(self.start_detect)
#合成对话框
self.assemble_dialog = Assemble_Dialog()
self.assemble_dialog.start_assemble_signal.connect(self.synthesis.synthesis_slot)
# 菜单栏的动作
self.actiona_3.triggered.connect(self.show_detect_dialog)
self.actiona_4.triggered.connect(self.show_assemble_dialog)
self.action_save.triggered.connect(self.save_project)
self.import_movie.triggered.connect(self.import_slot)
#视频时长,全局变量
self.video_duration = None
self.sld_video_pressed=False #判断当前进度条识别否被鼠标点击
self.videoFullScreen = False # 判断当前widget是否全屏
self.videoFullScreenWidget = myVideoWidget() # 创建一个全屏的widget
self.player = QMediaPlayer()
self.player.setVideoOutput(self.wgt_video) # 视频播放输出的widget,就是上面定义的
self.btn_open.clicked.connect(self.openVideoFile) # 打开视频文件按钮
self.btn_open.clicked.connect(self.open_excel) # 打开视频文件按钮
self.btn_play.clicked.connect(self.playVideo) # play
self.btn_stop.clicked.connect(self.pauseVideo) # pause
self.player.positionChanged.connect(self.changeSlide) # change Slide
......@@ -75,6 +80,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
replp = QtWidgets.QMessageBox.question(self, u'警告', msg,
QtWidgets.QMessageBox.Yes)
def import_slot(self):
video_path = self.openVideoFile()
self.init_ProjectContext_VideoPath(video_path)
def start_detect(self, video_path, book_path):
......@@ -108,7 +116,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# self.show_warning_msg_box("请确认结束时间是否正确")
# return
print("daozhele")
# 获取视频的时长等信息,初始化开始结束时间
startTime = "00:00:00"
......@@ -128,7 +135,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.show_warning_msg_box("开始时间不得大于等于结束时间,请重新填写")
return
print("daozhele11111")
video_fps = cv2.VideoCapture(video_path).get(cv2.CAP_PROP_FPS)
if (end_time - start_time) * video_fps < 150:
self.show_warning_msg_box("您想要检测的片段太短,请重新输入开始时间和结束时间!")
......@@ -217,20 +223,25 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.player.setVolume(volume)
self.lab_audio.setText("volume:"+str(volume)+"%")
# postion 取值[0,100]
def clickedSlider(self, position):
if self.player.duration() > 0: # 开始播放后才允许进行跳转
video_position = int((position / 100) * self.player.duration())
self.player.setPosition(video_position)
self.lab_video.setText("%.2f%%" % position)
# print("pos:", position, "总时长:", self.player.duration())
# self.lab_video.setText("%.2f%%" % position)
self.lab_video.setText(utils.transfer_second_to_time(str(video_position)))
else:
self.sld_video.setValue(0)
# position 取值[0,100]
def moveSlider(self, position):
self.sld_video_pressed = True
if self.player.duration() > 0: # 开始播放后才允许进行跳转
video_position = int((position / 100) * self.player.duration())
self.player.setPosition(video_position)
self.lab_video.setText("%.2f%%" % position)
# self.lab_video.setText("%.2f%%" % position)
self.lab_video.setText(utils.transfer_second_to_time(str(video_position)))
def pressSlider(self):
self.sld_video_pressed = True
......@@ -239,16 +250,28 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def releaseSlider(self):
self.sld_video_pressed = False
# position 取值[0,总时长]
def changeSlide(self, position):
if not self.sld_video_pressed: # 进度条被鼠标点击时不更新
self.vidoeLength = self.player.duration()+0.1
self.sld_video.setValue(round((position/self.vidoeLength)*100))
self.lab_video.setText("%.2f%%" % ((position/self.vidoeLength)*100))
self.lab_video.setText(utils.transfer_second_to_time(str(position/1000)))
# self.lab_video.setText("%.2f%%" % ((position/self.vidoeLength)*100))
def openVideoFile(self):
self.player.setMedia(QMediaContent(QFileDialog.getOpenFileUrl()[0])) # 选取视频文件
path = QFileDialog.getOpenFileUrl()[0]
self.player.setMedia(QMediaContent(path)) # 选取视频文件
self.player.play() # 播放视频
print(self.player.availableMetaData())
return path
# 在初始化工程时
def init_ProjectContext_VideoPath(self, path):
# video_dir = os.path.dirname(path)
# video_name = os.path.basename(path)
# self.projectContext.Init(video_dir, video_name)
self.projectContext.setVideoPath(path)
def playVideo(self):
self.player.play()
......@@ -268,3 +291,41 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.player.setVideoOutput(self.videoFullScreenWidget)
self.videoFullScreenWidget.setFullScreen(1)
self.videoFullScreen = True
def open_excel(self):
file_info = QFileDialog.getOpenFileNames(self, '选择表格路径', os.getcwd(), "All Files(*);;Text Files(*.txt)")
file_path, ok = validate_and_get_filepath(file_info)
# path = QFileDialog.getOpenFileUrl()
print("表格路径:" , file_path)
if ok == False:
return
self.projectContext.setExcelPath(file_path)
self.projectContext.load_excel_from_path()
self.set_table_to_window()
def set_table_to_window(self):
header = self.projectContext.header
subtitle_list = self.projectContext.subtitle_list
aside_list = self.projectContext.aside_list
self.zm_tableWidget.setRowCount(len(subtitle_list))
self.zm_tableWidget.setColumnCount(len(header))
self.zm_tableWidget.setHorizontalHeaderLabels(header)
for i in range(len(subtitle_list)):
self.setElememtToTable(self.zm_tableWidget, subtitle_list[i], i)
self.pb_tableWidget.setRowCount(len(aside_list))
self.pb_tableWidget.setColumnCount(len(header))
self.pb_tableWidget.setHorizontalHeaderLabels(header)
for i in range(len(aside_list)):
self.setElememtToTable(self.pb_tableWidget, aside_list[i], i)
def setElememtToTable(self, table: QTableWidget, elem: Element, idx: int):
elem_list = elem.to_list()
for j in range(len(elem_list)):
table.setItem(idx, j, QTableWidgetItem(elem_list[j]))
def save_project(self):
self.projectContext.save_project()
......@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>939</width>
<height>755</height>
<height>763</height>
</rect>
</property>
<property name="windowTitle">
......@@ -30,7 +30,7 @@
<layout class="QHBoxLayout" name="shuiping" stretch="3,1">
<item>
<widget class="QWidget" name="verticalWidget_3" native="true">
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="8,1">
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="8,0">
<item>
<widget class="myVideoWidget" name="wgt_video" native="true">
<property name="minimumSize">
......@@ -127,7 +127,7 @@
</size>
</property>
<property name="text">
<string>打开视频文件</string>
<string>打开表格文件</string>
</property>
</widget>
<widget class="QPushButton" name="btn_play">
......@@ -276,7 +276,7 @@ QPushButton:pressed {
<enum>QTabWidget::Triangular</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<property name="iconSize">
<size>
......@@ -293,15 +293,25 @@ QPushButton:pressed {
<property name="tabBarAutoHide">
<bool>false</bool>
</property>
<widget class="QWidget" name="tab">
<widget class="QWidget" name="zm_tab">
<attribute name="title">
<string>字幕</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTableWidget" name="zm_tableWidget"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<widget class="QWidget" name="pb_tab">
<attribute name="title">
<string>旁白</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QTableWidget" name="pb_tableWidget"/>
</item>
</layout>
</widget>
</widget>
</item>
......@@ -455,10 +465,10 @@ QPushButton:pressed {
<addaction name="actionxinjian"/>
<addaction name="actiona"/>
<addaction name="separator"/>
<addaction name="actiona_2"/>
<addaction name="import_movie"/>
<addaction name="actions"/>
<addaction name="separator"/>
<addaction name="actions_2"/>
<addaction name="action_save"/>
</widget>
<widget class="QMenu" name="menu_2">
<property name="title">
......@@ -489,7 +499,7 @@ QPushButton:pressed {
<string>打开</string>
</property>
</action>
<action name="actiona_2">
<action name="import_movie">
<property name="text">
<string>视频导入</string>
</property>
......@@ -499,7 +509,7 @@ QPushButton:pressed {
<string>内容导出</string>
</property>
</action>
<action name="actions_2">
<action name="action_save">
<property name="text">
<string>工程保存</string>
</property>
......
......@@ -12,7 +12,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(939, 755)
MainWindow.resize(939, 763)
MainWindow.setStyleSheet("QMainWindow:{\n"
" border: 2px groove gray;\n"
" border-radius: 25px;\n"
......@@ -141,7 +141,6 @@ class Ui_MainWindow(object):
self.label_2.setObjectName("label_2")
self.verticalLayout_3.addWidget(self.splitter)
self.verticalLayout_3.setStretch(0, 8)
self.verticalLayout_3.setStretch(1, 1)
self.shuiping.addWidget(self.verticalWidget_3)
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
......@@ -153,12 +152,26 @@ class Ui_MainWindow(object):
self.tabWidget.setMovable(False)
self.tabWidget.setTabBarAutoHide(False)
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.tabWidget.addTab(self.tab, "")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.zm_tab = QtWidgets.QWidget()
self.zm_tab.setObjectName("zm_tab")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.zm_tab)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.zm_tableWidget = QtWidgets.QTableWidget(self.zm_tab)
self.zm_tableWidget.setObjectName("zm_tableWidget")
self.zm_tableWidget.setColumnCount(0)
self.zm_tableWidget.setRowCount(0)
self.horizontalLayout_2.addWidget(self.zm_tableWidget)
self.tabWidget.addTab(self.zm_tab, "")
self.pb_tab = QtWidgets.QWidget()
self.pb_tab.setObjectName("pb_tab")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.pb_tab)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.pb_tableWidget = QtWidgets.QTableWidget(self.pb_tab)
self.pb_tableWidget.setObjectName("pb_tableWidget")
self.pb_tableWidget.setColumnCount(0)
self.pb_tableWidget.setRowCount(0)
self.horizontalLayout_3.addWidget(self.pb_tableWidget)
self.tabWidget.addTab(self.pb_tab, "")
self.shuiping.addWidget(self.tabWidget)
self.shuiping.setStretch(0, 3)
self.shuiping.setStretch(1, 1)
......@@ -248,12 +261,12 @@ class Ui_MainWindow(object):
self.actionxinjian.setObjectName("actionxinjian")
self.actiona = QtWidgets.QAction(MainWindow)
self.actiona.setObjectName("actiona")
self.actiona_2 = QtWidgets.QAction(MainWindow)
self.actiona_2.setObjectName("actiona_2")
self.import_movie = QtWidgets.QAction(MainWindow)
self.import_movie.setObjectName("import_movie")
self.actions = QtWidgets.QAction(MainWindow)
self.actions.setObjectName("actions")
self.actions_2 = QtWidgets.QAction(MainWindow)
self.actions_2.setObjectName("actions_2")
self.action_save = QtWidgets.QAction(MainWindow)
self.action_save.setObjectName("action_save")
self.actionchexiao = QtWidgets.QAction(MainWindow)
self.actionchexiao.setObjectName("actionchexiao")
self.actionchongzuo = QtWidgets.QAction(MainWindow)
......@@ -265,10 +278,10 @@ class Ui_MainWindow(object):
self.menu.addAction(self.actionxinjian)
self.menu.addAction(self.actiona)
self.menu.addSeparator()
self.menu.addAction(self.actiona_2)
self.menu.addAction(self.import_movie)
self.menu.addAction(self.actions)
self.menu.addSeparator()
self.menu.addAction(self.actions_2)
self.menu.addAction(self.action_save)
self.menu_2.addAction(self.actionchexiao)
self.menu_2.addAction(self.actionchongzuo)
self.menu_3.addAction(self.actiona_3)
......@@ -278,19 +291,19 @@ class Ui_MainWindow(object):
self.menubar.addAction(self.menu_3.menuAction())
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(1)
self.tabWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.btn_open.setText(_translate("MainWindow", "打开视频文件"))
self.btn_open.setText(_translate("MainWindow", "打开表格文件"))
self.btn_play.setText(_translate("MainWindow", "播放"))
self.btn_stop.setText(_translate("MainWindow", "暂停"))
self.lab_audio.setText(_translate("MainWindow", "volume:100%"))
self.label_2.setText(_translate("MainWindow", "00:00/12:34"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "字幕"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "旁白"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.zm_tab), _translate("MainWindow", "字幕"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.pb_tab), _translate("MainWindow", "旁白"))
self.zm_label.setText(_translate("MainWindow", "字幕时间轴"))
self.lab_video.setText(_translate("MainWindow", "0%"))
self.pb_label.setText(_translate("MainWindow", "旁白时间轴"))
......@@ -299,9 +312,9 @@ class Ui_MainWindow(object):
self.menu_3.setTitle(_translate("MainWindow", "功能按键"))
self.actionxinjian.setText(_translate("MainWindow", "新建"))
self.actiona.setText(_translate("MainWindow", "打开"))
self.actiona_2.setText(_translate("MainWindow", "视频导入"))
self.import_movie.setText(_translate("MainWindow", "视频导入"))
self.actions.setText(_translate("MainWindow", "内容导出"))
self.actions_2.setText(_translate("MainWindow", "工程保存"))
self.action_save.setText(_translate("MainWindow", "工程保存"))
self.actionchexiao.setText(_translate("MainWindow", "撤销"))
self.actionchongzuo.setText(_translate("MainWindow", "重做"))
self.actiona_3.setText(_translate("MainWindow", "旁白区间检测"))
......
import os.path
import threading
import traceback
import sys
from enum import Enum
import openpyxl
from openpyxl.styles import PatternFill, Alignment
from utils import replace_path_suffix
class RunThread(threading.Thread):
"""复写线程类,用于解决主线程无法捕捉子线程中异常的问题
"""
......@@ -42,4 +51,148 @@ class RunThread(threading.Thread):
try:
self._funcName(*self._args)
except Exception as e:
raise e
\ No newline at end of file
raise e
# 计划支持两种操作符,修改和删除(目前还是仅支持修改)
# todo:删除是指对字幕Element的删除(比如重复的进行合并)
class Operation(Enum):
Modify = 0
# Delete = 1
# 维护一条历史记录
# 目前仅支持对旁白做修改
class OperateRecord:
def __init__(self, operation: Operation, old: str, new: str):
self.operation = operation
self.old_str = old
self.new_str = new
# 每一行的具体信息,"起始时间", "终止时间", "字幕", '建议', '解说脚本'
class Element:
def __init__(self, st_time_sec: float, ed_time_sec: float, subtitle, suggest, aside):
self.st_time_sec = st_time_sec
self.ed_time_sec = ed_time_sec
self.subtitle = subtitle
self.suggest = suggest
self.aside = aside
self.history_records = []
# 判断当前元素是否是字幕
def is_subtitle(self):
return self.subtitle != None and self.subtitle != ""
# 判断当前元素是否是旁白
def is_aside(self):
return not self.is_subtitle()
def to_list(self):
return [self.st_time_sec, self.ed_time_sec, self.subtitle, self.suggest, self.aside]
class ProjectContext:
def __init__(self):
self.project_base_dir = None
self.video_path = None
self.excel_path = None
self.subtitle_list = []
self.aside_list = []
# 一些常量
self.header = ["起始时间", "终止时间", "字幕", '建议', '解说脚本']
self.excel_sheet_name = "旁白插入位置建议"
def Init(self, project_dir, video_name):
self.project_base_dir = project_dir
self.video_path = os.path.join(project_dir, video_name)
self.excel_path = replace_path_suffix(self.video_path, ".xlsx")
def Init(self, project_dir, video_path, excel_path):
self.project_base_dir = project_dir
self.video_path = video_path
self.excel_path = excel_path
def setVideoPath(self, video_path):
self.video_path = video_path
def setExcelPath(self, excel_path):
self.excel_path = excel_path
# 目前只是把excel保存到文件中
def save_project(self):
all_element = self.subtitle_list + self.aside_list
all_element.sort(lambda x, y: (x.st_time_sec < y.st_time_sec))
for element in all_element:
write_to_sheet(self.excel_path, self.excel_sheet_name, element.to_list)
# 加载整个工程,填充到ProjectContext上下文中
def load_project(self):
pass
def load_excel_from_path(self):
d = read_sheet(self.excel_path)
# todo:现在是只用None判断是否是字幕,后续是否也需要用""来?
for i in range(len(d["字幕"])):
st_time_sec, ed_time_sec, subtitle, suggest, aside = [d[x][i] for x in self.header]
if d["字幕"][i] != None:
self.subtitle_list.append(Element(st_time_sec, ed_time_sec, subtitle, suggest, aside))
else:
self.aside_list.append(Element(st_time_sec, ed_time_sec, subtitle, suggest, aside))
def write_to_sheet(path: str, sheet_name: str, value: list):
"""向已存在的表格中写入一行数据
Args:
path (str): 表格(book)的存储位置
sheet_name (str): excel表内的表(sheet)的名字
value (list): 要插入表内的一行数据
"""
index = len(value)
workbook = openpyxl.load_workbook(path)
sheet = workbook.get_sheet_by_name(sheet_name)
cur_row = sheet.max_row
for j in range(0, index):
sheet.cell(row=cur_row + 1, column=j + 1, value=str(value[j]))
if value[j] == '' or '插入旁白' in str(value[j]):
sheet.cell(row=cur_row + 1, column=j + 1).fill = PatternFill(fill_type='solid', fgColor='ffff00')
if j == 2:
sheet.cell(row=cur_row + 1, column=j + 1).alignment = Alignment(wrapText=True)
workbook.save(path)
def read_sheet(book_path: str, sheet_name: str = "") -> dict:
"""读表
从表格中读出所有的内容,用dict保存(表格的格式固定,第一行为表头(起始时间|终止时间|字幕|建议|解说脚本))
Args:
book_path (str): 表格的存储路径
sheet_name (str, optional): 想要读取的表在excel表格中的名字. Defaults to "".
Returns:
dict: 表格中的所有内容,key为该列表头,value为列中的数据
"""
workbook = openpyxl.load_workbook(book_path)
sheet = workbook.active
rows = sheet.max_row
cols = sheet.max_column
sheet_content = {}
# 读取xlsx中每列的内容,默认第一行是各列的列名
for i in range(1, rows + 1):
for j in range(1, cols + 1):
if i == 1:
sheet_content[sheet.cell(1, j).value] = []
else:
sheet_content[sheet.cell(1, j).value].append(
sheet.cell(i, j).value)
return sheet_content
if __name__ == '__main__':
# d = read_sheet("test37second.xlsx")
# print(d["字幕"])
# print(d.keys())
ctx = ProjectContext()
ctx.setExcelPath("d:/123")
print(ctx.excel_path)
\ No newline at end of file
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem, QAbstractItemView)
class myTableWidget(QWidget):
def __init__(self):
super(myTableWidget,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget演示")
self.resize(430, 230);
layout = QHBoxLayout()
tablewidget = QTableWidget()
tablewidget.setRowCount(4)
tablewidget.setColumnCount(6)
layout.addWidget(tablewidget)
tablewidget.setHorizontalHeaderLabels(['时间','文字'])
nameItem = QTableWidgetItem("0:00")
tablewidget.setItem(0,0,nameItem)
ageItem = QTableWidgetItem("24")
tablewidget.setItem(0,1,ageItem)
jgItem = QTableWidgetItem("北京")
tablewidget.setItem(0,2,jgItem)
# 禁止编辑
# tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
# 整行选择
tablewidget.setSelectionBehavior(QAbstractItemView.SelectRows)
# 调整列和行
tablewidget.resizeColumnsToContents()
tablewidget.resizeRowsToContents()
# tablewidget.horizontalHeader().setVisible(False)
# tablewidget.verticalHeader().setVisible(False)
tablewidget.setVerticalHeaderLabels(["a","b"])
# 隐藏表格线
tablewidget.setShowGrid(False)
self.setLayout(layout)
tablewidget.itemClicked.connect(self.show_data)
def show_data(self, Item):
# 如果单元格对象为空
if Item is None:
return
else:
row = Item.row() # 获取行数
col = Item.column() # 获取列数 注意是column而不是col哦
text = Item.text() # 获取内容
# 输出测试
print('row = ', row)
print('col =', col)
print('text = ', text)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = myTableWidget()
example.show()
sys.exit(app.exec_())
......@@ -7,4 +7,15 @@ def f(a,b,c,d):
data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]
name, shares, price, date = data
print(name)
\ No newline at end of file
print(name)
from enum import Enum
class Operation(Enum):
Modify = 0
Delete = 1
# print(Operation.Delete)
print(Operation(('修改', "xiugai")))
\ No newline at end of file
......@@ -403,10 +403,13 @@ def ss_and_export(video_path: str, sheet_path: str, output_dir: str, speed: floa
if __name__ == '__main__':
video_path = r'D:/Downloads/zhanlang.rmvb'
sheet_path = r'D:/Downloads/战狼.xlsx'
output_dir = r'D:/AddCaption/last_version/accessibility_movie/zhanlang'
speed = 1.25
caption_file = './zhanlang/zhanlang.srt'
speaker_name = '晓秋'
ss_and_export(video_path, sheet_path, output_dir, speed, caption_file, speaker_name)
# video_path = r'D:/Downloads/zhanlang.rmvb'
# sheet_path = r'D:/Downloads/战狼.xlsx'
# output_dir = r'D:/AddCaption/last_version/accessibility_movie/zhanlang'
# speed = 1.25
# caption_file = './zhanlang/zhanlang.srt'
# speaker_name = '晓秋'
# ss_and_export(video_path, sheet_path, output_dir, speed, caption_file, speaker_name)
import pprint
d = read_sheet("./test37second.xlsx")
pprint.pprint(d)
\ No newline at end of file
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem, QAbstractItemView)
from PyQt5.QtCore import Qt
class TableWidget(QWidget):
def __init__(self):
super(TableWidget,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget演示")
self.resize(430, 230);
layout = QHBoxLayout()
tablewidget = QTableWidget()
tablewidget.setRowCount(4)
tablewidget.setColumnCount(6)
layout.addWidget(tablewidget)
tablewidget.setHorizontalHeaderLabels(['时间','文字'])
nameItem = QTableWidgetItem("0:00")
# nameItem.setFlags()
tablewidget.setItem(0,0,nameItem)
ageItem = QTableWidgetItem("24")
tablewidget.setItem(0,1,ageItem)
jgItem = QTableWidgetItem("北京")
# jgItem.setFlags(Qt.ItemIsEnabled)
jgItem.setFlags(Qt.ItemFlags(32))
# jgItem.checkState()
tablewidget.setItem(0,2,jgItem)
# 禁止编辑
# tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
# 整行选择
tablewidget.setSelectionBehavior(QAbstractItemView.SelectRows)
# 调整列和行
tablewidget.resizeColumnsToContents()
tablewidget.resizeRowsToContents()
# tablewidget.horizontalHeader().setVisible(False)
# tablewidget.verticalHeader().setVisible(False)
tablewidget.setVerticalHeaderLabels(["a","b"])
# 隐藏表格线
tablewidget.setShowGrid(False)
self.setLayout(layout)
tablewidget.itemClicked.connect(self.show_data)
def show_data(self, Item):
# 如果单元格对象为空
if Item is None:
return
else:
print(Item.checkState())
row = Item.row() # 获取行数
col = Item.column() # 获取列数 注意是column而不是col哦
text = Item.text() # 获取内容
# 输出测试
print('row = ', row)
print('col =', col)
print('text = ', text)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = TableWidget()
example.show()
sys.exit(app.exec_())
......@@ -25,7 +25,15 @@ def trans_to_seconds(timePoint: str) -> float:
units *= 60
return time_in_seconds
def transfer_second_to_time(sec: str) -> str:
duration = int(float(sec))
minutes = int(duration / 60)
seconds = int(duration - 60 * minutes)
idx = sec.find('.')
if(idx == -1):
idx = len(sec)
time = "%02d:%02d%s" % (minutes, seconds, sec[idx:])
return time
def replace_path_suffix(path, new_suffix):
return path.replace(os.path.splitext(path)[-1], new_suffix)
......@@ -66,4 +74,9 @@ def get_sheetHead(book_path: str) -> list:
if rows > 1:
for j in range(1, cols + 1):
sheet_head.append(sheet.cell(1, j).value)
return sheet_head
\ No newline at end of file
return sheet_head
if __name__ == '__main__':
x = transfer_second_to_time("12000.923")
print(x)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment