上传文件至 /

This commit is contained in:
ChengQiqian 2025-07-09 19:18:56 +08:00
commit 609a2d8254
2 changed files with 800 additions and 0 deletions

498
picture_upload.py Normal file
View File

@ -0,0 +1,498 @@
import os
import sys
import requests
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QComboBox, QPushButton, QFileDialog,
QGroupBox, QDateTimeEdit, QDoubleSpinBox, QSpinBox, QTextEdit,
QTabWidget, QScrollArea, QMessageBox, QCalendarWidget,QGridLayout)
from PyQt5.QtCore import Qt, QDateTime, QTimer
from PyQt5.QtGui import QFont, QIcon
class NoWheelComboBox(QComboBox):
def wheelEvent(self, event):
event.ignore()
class NoWheelSpinBox(QSpinBox):
def wheelEvent(self, event):
event.ignore()
class NoWheelDoubleSpinBox(QDoubleSpinBox):
def wheelEvent(self, event):
event.ignore()
class ImageUploaderApp(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("图片批量上传工具")
self.setWindowIcon(QIcon("upload_icon.png")) # 替换为您自己的图标或删除此行
self.setGeometry(100, 100, 850, 650)
# 初始化参数
self.base_url = "http://pms.dtyx.net:9158/image"
self.default_part_id = "a3b4b81c5973a1895a4d95d50dd8351c"
self.file_paths = []
self.upload_in_progress = False
# 初始化UI
self.init_ui()
def init_ui(self):
# 创建主窗口部件
main_widget = QWidget()
self.setCentralWidget(main_widget)
# 主布局
main_layout = QVBoxLayout()
main_widget.setLayout(main_layout)
# 创建标签页
tab_widget = QTabWidget()
main_layout.addWidget(tab_widget)
# 基本参数标签页
basic_tab = QWidget()
tab_widget.addTab(basic_tab, "基本参数")
self.setup_basic_tab(basic_tab)
# 高级参数标签页
advanced_tab = QWidget()
tab_widget.addTab(advanced_tab, "高级参数")
self.setup_advanced_tab(advanced_tab)
# 底部按钮区域
button_layout = QHBoxLayout()
self.upload_btn = QPushButton("开始上传")
self.upload_btn.setFont(QFont("Arial", 12, QFont.Bold))
self.upload_btn.setStyleSheet("background-color: #4CAF50; color: white; padding: 10px;")
self.upload_btn.clicked.connect(self.start_upload)
self.clear_btn = QPushButton("清空选择")
self.clear_btn.setFont(QFont("Arial", 12))
self.clear_btn.setStyleSheet("background-color: #f44336; color: white; padding: 10px;")
self.clear_btn.clicked.connect(self.clear_selection)
button_layout.addWidget(self.upload_btn)
button_layout.addWidget(self.clear_btn)
main_layout.addLayout(button_layout)
# 日志输出
self.log_text = QTextEdit()
self.log_text.setReadOnly(True)
self.log_text.setFont(QFont("Consolas", 10))
self.log_text.setStyleSheet("background-color: #f5f5f5;")
main_layout.addWidget(self.log_text)
def setup_basic_tab(self, tab):
layout = QVBoxLayout()
tab.setLayout(layout)
# Part ID设置
part_id_group = QGroupBox("部件ID设置")
part_id_layout = QVBoxLayout()
self.part_id_input = QLineEdit(self.default_part_id)
part_id_layout.addWidget(QLabel("部件ID:"))
part_id_layout.addWidget(self.part_id_input)
part_id_group.setLayout(part_id_layout)
layout.addWidget(part_id_group)
# 图片源选择
source_group = QGroupBox("图片源设置")
source_layout = QVBoxLayout()
self.source_combo = NoWheelComboBox()
self.source_combo.addItems(["图像采集", "外部工作", "内部工作", "防雷工作"])
self.source_combo.setCurrentText("内部工作")
source_layout.addWidget(QLabel("图片源类型:"))
source_layout.addWidget(self.source_combo)
source_group.setLayout(source_layout)
layout.addWidget(source_group)
# 图片类型选择
type_group = QGroupBox("图片类型设置")
type_layout = QVBoxLayout()
self.type_combo = NoWheelComboBox()
self.type_combo.addItems(["", "缺陷影像", "典型影像", "其他影像"])
type_layout.addWidget(QLabel("图片类型:"))
type_layout.addWidget(self.type_combo)
type_group.setLayout(type_layout)
layout.addWidget(type_group)
# 拍摄方式选择
method_group = QGroupBox("拍摄方式设置")
method_layout = QVBoxLayout()
self.method_combo = NoWheelComboBox()
self.method_combo.addItems(["", "无人机航拍", "手持相机拍摄"])
method_layout.addWidget(QLabel("拍摄方式:"))
method_layout.addWidget(self.method_combo)
method_group.setLayout(method_layout)
layout.addWidget(method_group)
# 天气选择
weather_group = QGroupBox("天气设置")
weather_layout = QVBoxLayout()
self.weather_combo = NoWheelComboBox()
weather_options = [
"", "晴天", "多云", "阴天", "小雨", "中雨", "大雨", "暴雨",
"阵雨", "雷阵雨", "雷电", "冰雹", "轻雾", "", "浓雾",
"", "雨夹雪", "小雪", "中雪", "大雪", "暴雪", "冻雨"
]
self.weather_combo.addItems(weather_options)
weather_layout.addWidget(QLabel("天气情况:"))
weather_layout.addWidget(self.weather_combo)
weather_group.setLayout(weather_layout)
layout.addWidget(weather_group)
# 文件选择按钮
self.select_files_btn = QPushButton("选择图片文件")
self.select_files_btn.setFont(QFont("Arial", 12))
self.select_files_btn.setStyleSheet("background-color: #2196F3; color: white; padding: 8px;")
self.select_files_btn.clicked.connect(self.select_files)
layout.addWidget(self.select_files_btn)
# 选中的文件列表
self.file_list_label = QLabel("已选择 0 个文件")
self.file_list_label.setFont(QFont("Arial", 10))
layout.addWidget(self.file_list_label)
# 添加弹性空间
layout.addStretch()
def setup_advanced_tab(self, tab):
scroll = QScrollArea()
scroll.setWidgetResizable(True)
tab.layout = QVBoxLayout(tab)
tab.layout.addWidget(scroll)
container = QWidget()
scroll.setWidget(container)
layout = QVBoxLayout()
container.setLayout(layout)
# 采集员信息
collector_group = QGroupBox("采集员信息")
collector_layout = QVBoxLayout()
self.collector_id_input = QLineEdit()
self.collector_name_input = QLineEdit()
collector_layout.addWidget(QLabel("采集员ID:"))
collector_layout.addWidget(self.collector_id_input)
collector_layout.addWidget(QLabel("采集员姓名:"))
collector_layout.addWidget(self.collector_name_input)
collector_group.setLayout(collector_layout)
layout.addWidget(collector_group)
# 拍摄时间
time_group = QGroupBox("拍摄时间")
time_layout = QVBoxLayout()
# 开始时间
start_time_group = QGroupBox("开始时间")
start_time_layout = QVBoxLayout()
self.start_calendar = QCalendarWidget()
self.start_time_edit = QDateTimeEdit()
self.start_time_edit.setDisplayFormat("HH:mm:ss")
self.start_time_edit.setTime(QDateTime.currentDateTime().time())
start_time_layout.addWidget(self.start_calendar)
start_time_layout.addWidget(self.start_time_edit)
start_time_group.setLayout(start_time_layout)
# 结束时间
end_time_group = QGroupBox("结束时间")
end_time_layout = QVBoxLayout()
self.end_calendar = QCalendarWidget()
self.end_time_edit = QDateTimeEdit()
self.end_time_edit.setDisplayFormat("HH:mm:ss")
self.end_time_edit.setTime(QDateTime.currentDateTime().time())
end_time_layout.addWidget(self.end_calendar)
end_time_layout.addWidget(self.end_time_edit)
end_time_group.setLayout(end_time_layout)
time_layout.addWidget(start_time_group)
time_layout.addWidget(end_time_group)
time_group.setLayout(time_layout)
layout.addWidget(time_group)
# 环境参数
env_group = QGroupBox("环境参数")
env_layout = QGridLayout()
self.humidity_spin = NoWheelSpinBox()
self.humidity_spin.setRange(0, 100)
self.humidity_spin.setSpecialValueText("未设置")
self.humidity_spin.setValue(0)
self.temp_min_spin = NoWheelDoubleSpinBox()
self.temp_min_spin.setRange(-50, 50)
self.temp_min_spin.setSpecialValueText("未设置")
self.temp_min_spin.setValue(-50)
self.temp_max_spin = NoWheelDoubleSpinBox()
self.temp_max_spin.setRange(-50, 50)
self.temp_max_spin.setSpecialValueText("未设置")
self.temp_max_spin.setValue(-50)
self.wind_level_spin = NoWheelSpinBox()
self.wind_level_spin.setRange(0, 12)
self.wind_level_spin.setSpecialValueText("未设置")
self.wind_level_spin.setValue(0)
self.distance_spin = NoWheelSpinBox()
self.distance_spin.setRange(0, 1000)
self.distance_spin.setSpecialValueText("未设置")
self.distance_spin.setValue(0)
env_layout.addWidget(QLabel("湿度(%):"), 0, 0)
env_layout.addWidget(self.humidity_spin, 0, 1)
env_layout.addWidget(QLabel("最低温度(℃):"), 1, 0)
env_layout.addWidget(self.temp_min_spin, 1, 1)
env_layout.addWidget(QLabel("最高温度(℃):"), 2, 0)
env_layout.addWidget(self.temp_max_spin, 2, 1)
env_layout.addWidget(QLabel("风力等级:"), 3, 0)
env_layout.addWidget(self.wind_level_spin, 3, 1)
env_layout.addWidget(QLabel("拍摄距离(m):"), 4, 0)
env_layout.addWidget(self.distance_spin, 4, 1)
env_group.setLayout(env_layout)
layout.addWidget(env_group)
# 添加弹性空间
layout.addStretch()
def select_files(self):
options = QFileDialog.Options()
files, _ = QFileDialog.getOpenFileNames(
self, "选择图片文件", "",
"图片文件 (*.jpg *.jpeg *.png *.bmp *.gif)",
options=options
)
if files:
self.file_paths = files
self.file_list_label.setText(f"已选择 {len(files)} 个文件")
self.log_message(f"已选择 {len(files)} 个图片文件")
def clear_selection(self):
self.file_paths = []
self.file_list_label.setText("已选择 0 个文件")
self.log_message("已清空文件选择")
def log_message(self, message):
self.log_text.append(f"[{QDateTime.currentDateTime().toString('yyyy-MM-dd hh:mm:ss')}] {message}")
def start_upload(self):
if self.upload_in_progress:
QMessageBox.warning(self, "警告", "已有上传任务在进行中!")
return
if not self.file_paths:
QMessageBox.warning(self, "警告", "请先选择要上传的图片文件!")
return
self.upload_in_progress = True
self.upload_btn.setEnabled(False)
self.clear_btn.setEnabled(False)
# 使用QTimer在事件循环中启动上传避免界面卡住
QTimer.singleShot(100, self.upload_images)
def upload_images(self):
try:
# 准备参数
part_id = self.part_id_input.text().strip() or self.default_part_id
# 从日历和时间控件获取时间
start_date = self.start_calendar.selectedDate()
start_time = self.start_time_edit.time()
start_datetime = QDateTime(start_date, start_time)
end_date = self.end_calendar.selectedDate()
end_time = self.end_time_edit.time()
end_datetime = QDateTime(end_date, end_time)
# 构建参数字典,只包含有值的参数
params = {
"imageSource": ["collect", "out-work", "in-work", "lightning-protection-work"][
self.source_combo.currentIndex()],
}
# 添加可选参数
if self.type_combo.currentIndex() > 0:
params["imageType"] = ["", "DEFECT", "TYPICAL", "OTHER"][self.type_combo.currentIndex()]
if self.method_combo.currentIndex() > 0:
params["shootingMethod"] = ["", "UAV", "HANDHELD_CAMERA"][self.method_combo.currentIndex()]
if self.weather_combo.currentIndex() > 0:
weather_options = [
"", "SUNNY", "CLOUDY", "OVERCAST", "LIGHT_RAIN", "MODERATE_RAIN", "HEAVY_RAIN",
"CLOUDBURST", "SHOWER", "THUNDERSHOWER", "THUNDER", "HAIL", "LIGHT_FOG",
"FOG", "THICK_FOG", "HAZE", "SLEET", "LIGHT_SNOW", "MODERATE_SNOW",
"HEAVY_SNOW", "BLIZZARD", "FREEZING_RAIN"
]
params["weather"] = weather_options[self.weather_combo.currentIndex()]
collector_id = self.collector_id_input.text().strip()
if collector_id:
params["collectorId"] = collector_id
collector_name = self.collector_name_input.text().strip()
if collector_name:
params["collectorName"] = collector_name
params["shootingTimeBegin"] = start_datetime.toString("yyyy-MM-dd hh:mm:ss")
params["shootingTimeEnd"] = end_datetime.toString("yyyy-MM-dd hh:mm:ss")
# 环境参数
if self.humidity_spin.value() > 0:
params["humidness"] = self.humidity_spin.value()
if self.temp_min_spin.value() > -50:
params["temperatureMin"] = self.temp_min_spin.value()
if self.temp_max_spin.value() > -50:
params["temperatureMax"] = self.temp_max_spin.value()
if self.wind_level_spin.value() > 0:
params["windLevel"] = self.wind_level_spin.value()
if self.distance_spin.value() > 0:
params["shootingDistance"] = self.distance_spin.value()
# 构建URL
url = f"{self.base_url}/{params['imageSource']}/upload-batch/{part_id}"
# 准备图片列表参数
for i, file_path in enumerate(self.file_paths):
file_name = os.path.basename(file_path)
params[f"imageList[{i}].imageName"] = file_name
params[f"imageList[{i}].imagePath"] = file_path
if "imageType" in params:
params[f"imageList[{i}].imageType"] = params["imageType"]
if "shootingMethod" in params:
params[f"imageList[{i}].shootingMethod"] = params["shootingMethod"]
if "weather" in params:
params[f"imageList[{i}].weather"] = params["weather"]
# 准备文件数据
files = []
for file_path in self.file_paths:
file_name = os.path.basename(file_path)
files.append(('files', (file_name, open(file_path, 'rb'), 'image/jpeg')))
self.log_message(f"开始上传 {len(self.file_paths)} 张图片...")
self.log_message(f"请求URL: {url}")
self.log_message(f"请求参数: {params}")
# 显示上传进度对话框
self.progress = QMessageBox(self)
self.progress.setWindowTitle("上传中")
self.progress.setText(f"正在上传 {len(self.file_paths)} 张图片,请稍候...")
self.progress.setStandardButtons(QMessageBox.Cancel)
self.progress.buttonClicked.connect(self.cancel_upload)
self.progress.show()
# 确保UI更新
QApplication.processEvents()
response = requests.post(
url,
headers={"Authorization": "null"},
params=params,
files=files
)
self.progress.close()
if response.status_code == 200:
self.log_message("上传成功!")
self.log_message(f"响应数据: {response.text}")
QMessageBox.information(self, "成功", "图片上传成功!")
else:
self.log_message(f"上传失败,状态码: {response.status_code}")
self.log_message(f"响应内容: {response.text}")
QMessageBox.critical(self, "错误", f"上传失败: {response.text}")
except Exception as e:
self.log_message(f"上传过程中发生错误: {str(e)}")
QMessageBox.critical(self, "错误", f"上传过程中发生错误: {str(e)}")
finally:
# 确保所有文件都被关闭
if 'files' in locals():
for file in files:
file[1][1].close()
self.upload_in_progress = False
self.upload_btn.setEnabled(True)
self.clear_btn.setEnabled(True)
def cancel_upload(self):
self.upload_in_progress = False
self.log_message("用户取消了上传操作")
self.progress.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
# 设置全局样式
app.setStyle("Fusion")
app.setStyleSheet("""
QMainWindow {
background-color: #f5f5f5;
}
QGroupBox {
font-weight: bold;
border: 1px solid #ccc;
border-radius: 5px;
margin-top: 10px;
padding-top: 15px;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 10px;
padding: 0 3px;
}
QLabel {
font-size: 12px;
}
QComboBox, QLineEdit, QDateTimeEdit, QSpinBox, QDoubleSpinBox {
padding: 5px;
border: 1px solid #ccc;
border-radius: 3px;
min-width: 200px;
}
QTextEdit {
border: 1px solid #ccc;
border-radius: 3px;
}
QCalendarWidget {
border: 1px solid #ccc;
border-radius: 3px;
}
""")
window = ImageUploaderApp()
window.show()
sys.exit(app.exec_())

302
video_upload.py Normal file
View File

@ -0,0 +1,302 @@
import os
import sys
import re
import requests
from datetime import datetime
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton, QListWidget, QMessageBox,
QProgressBar, QFileDialog, QGroupBox, QFormLayout)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
class VideoUploadThread(QThread):
progress_updated = pyqtSignal(int, str)
upload_finished = pyqtSignal(int, int)
def __init__(self, files, params, parent=None):
super().__init__(parent)
self.files = files
self.params = params
self.base_url = "http://pms.dtyx.net:9158"
self.upload_endpoint = "/video-file-info/batch-upload"
self.running = True
def run(self):
successful_uploads = 0
failed_uploads = 0
for index, file_path in enumerate(self.files):
if not self.running:
break
try:
# 从文件名中提取拍摄时间
shooting_time = self.extract_time_from_filename(file_path)
params = self.params.copy()
if shooting_time:
params["shootingTime"] = shooting_time.strftime("%Y-%m-%d %H:%M:%S")
else:
# 如果没有提取到时间,使用当前时间
params["shootingTime"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 读取文件内容
with open(file_path, 'rb') as f:
files = {'file': (os.path.basename(file_path), f, 'video/mp4')}
# 发送请求
response = requests.post(
url=f"{self.base_url}{self.upload_endpoint}",
params=params,
files=files,
headers={"Authorization": None} # token为null
)
# 处理响应
if response.status_code == 200:
result = response.json()
if result.get("success"):
self.progress_updated.emit(index + 1, f"上传成功: {os.path.basename(file_path)}")
successful_uploads += 1
else:
self.progress_updated.emit(index + 1,
f"上传失败: {os.path.basename(file_path)} - {result.get('msg', '未知错误')}")
failed_uploads += 1
else:
self.progress_updated.emit(index + 1,
f"上传失败: {os.path.basename(file_path)} - HTTP状态码: {response.status_code}")
failed_uploads += 1
except Exception as e:
self.progress_updated.emit(index + 1, f"上传异常: {os.path.basename(file_path)} - {str(e)}")
failed_uploads += 1
self.upload_finished.emit(successful_uploads, failed_uploads)
def extract_time_from_filename(self, file_path):
"""从文件名中提取时间信息"""
filename = os.path.basename(file_path)
# 匹配类似 VID_20250611_144614 的格式
match = re.search(r'(?:VID|VIDEO|视频)_?(\d{4})(\d{2})(\d{2})_?(\d{2})(\d{2})(\d{2})', filename, re.IGNORECASE)
if match:
year, month, day, hour, minute, second = match.groups()
try:
return datetime(
year=int(year),
month=int(month),
day=int(day),
hour=int(hour),
minute=int(minute),
second=int(second)
)
except:
pass
# 匹配其他常见日期格式
date_patterns = [
r'(\d{4})-(\d{2})-(\d{2})[ _](\d{2})-(\d{2})-(\d{2})', # 2025-06-11 14-46-14
r'(\d{4})(\d{2})(\d{2})[ _](\d{2})(\d{2})(\d{2})', # 20250611 144614
r'(\d{4})_(\d{2})_(\d{2})[ _](\d{2})_(\d{2})_(\d{2})', # 2025_06_11 14_46_14
]
for pattern in date_patterns:
match = re.search(pattern, filename)
if match:
year, month, day, hour, minute, second = match.groups()
try:
return datetime(
year=int(year),
month=int(month),
day=int(day),
hour=int(hour),
minute=int(minute),
second=int(second)
)
except:
continue
return None
def stop(self):
self.running = False
class VideoUploaderApp(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("防雷工作视频批量上传工具")
self.setGeometry(100, 100, 800, 600)
self.upload_thread = None
self.init_ui()
def init_ui(self):
# 主窗口布局
main_widget = QWidget()
main_layout = QVBoxLayout()
# 参数设置区域
params_group = QGroupBox("上传参数设置")
params_layout = QFormLayout()
self.part_id_input = QLineEdit("81d2bcdf0db9b0e986b61f986c5d520d")
self.location_input = QLineEdit()
self.test_point_input = QLineEdit()
self.worker_id_input = QLineEdit()
params_layout.addRow(QLabel("部件ID:"), self.part_id_input)
params_layout.addRow(QLabel("拍摄地点:"), self.location_input)
params_layout.addRow(QLabel("测试点:"), self.test_point_input)
params_layout.addRow(QLabel("作业人员ID:"), self.worker_id_input)
params_group.setLayout(params_layout)
# 文件选择区域
file_group = QGroupBox("视频文件选择")
file_layout = QVBoxLayout()
self.file_list = QListWidget()
self.select_btn = QPushButton("选择视频文件")
self.select_btn.clicked.connect(self.select_videos)
self.clear_btn = QPushButton("清空列表")
self.clear_btn.clicked.connect(self.clear_file_list)
file_layout.addWidget(self.file_list)
file_btn_layout = QHBoxLayout()
file_btn_layout.addWidget(self.select_btn)
file_btn_layout.addWidget(self.clear_btn)
file_layout.addLayout(file_btn_layout)
file_group.setLayout(file_layout)
# 上传控制区域
control_layout = QHBoxLayout()
self.upload_btn = QPushButton("开始上传")
self.upload_btn.clicked.connect(self.start_upload)
self.stop_btn = QPushButton("停止上传")
self.stop_btn.clicked.connect(self.stop_upload)
self.stop_btn.setEnabled(False)
control_layout.addWidget(self.upload_btn)
control_layout.addWidget(self.stop_btn)
# 进度显示区域
self.progress_bar = QProgressBar()
self.progress_bar.setAlignment(Qt.AlignCenter)
self.status_label = QLabel("准备就绪")
self.status_label.setAlignment(Qt.AlignCenter)
# 组装主布局
main_layout.addWidget(params_group)
main_layout.addWidget(file_group)
main_layout.addLayout(control_layout)
main_layout.addWidget(self.progress_bar)
main_layout.addWidget(self.status_label)
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
def select_videos(self):
"""选择视频文件"""
file_dialog = QFileDialog()
file_dialog.setFileMode(QFileDialog.ExistingFiles)
file_dialog.setNameFilter("视频文件 (*.mp4 *.avi *.mov *.mkv)")
if file_dialog.exec_():
file_paths = file_dialog.selectedFiles()
for file_path in file_paths:
self.file_list.addItem(file_path)
self.status_label.setText(f"已选择 {len(file_paths)} 个视频文件")
def clear_file_list(self):
"""清空文件列表"""
self.file_list.clear()
self.status_label.setText("文件列表已清空")
def start_upload(self):
"""开始上传视频"""
if self.file_list.count() == 0:
QMessageBox.warning(self, "警告", "请先选择要上传的视频文件!")
return
# 获取参数
params = {
"partId": self.part_id_input.text().strip(),
"qualified": 1, # 默认合格
"location": self.location_input.text().strip() or None,
"testPoint": self.test_point_input.text().strip() or None,
"workerUserId": self.worker_id_input.text().strip() or None
}
# 验证部件ID
if not params["partId"]:
QMessageBox.warning(self, "警告", "部件ID不能为空!")
return
# 获取文件列表
file_paths = [self.file_list.item(i).text() for i in range(self.file_list.count())]
# 设置UI状态
self.upload_btn.setEnabled(False)
self.stop_btn.setEnabled(True)
self.progress_bar.setMaximum(len(file_paths))
self.progress_bar.setValue(0)
self.status_label.setText("开始上传...")
# 创建并启动上传线程
self.upload_thread = VideoUploadThread(file_paths, params)
self.upload_thread.progress_updated.connect(self.update_progress)
self.upload_thread.upload_finished.connect(self.upload_finished)
self.upload_thread.start()
def stop_upload(self):
"""停止上传"""
if self.upload_thread and self.upload_thread.isRunning():
self.upload_thread.stop()
self.status_label.setText("上传已停止")
self.upload_btn.setEnabled(True)
self.stop_btn.setEnabled(False)
def update_progress(self, value, message):
"""更新上传进度"""
self.progress_bar.setValue(value)
self.status_label.setText(message)
def upload_finished(self, success_count, fail_count):
"""上传完成处理"""
self.upload_btn.setEnabled(True)
self.stop_btn.setEnabled(False)
msg = f"上传完成! 成功: {success_count} 个, 失败: {fail_count}"
self.status_label.setText(msg)
QMessageBox.information(self, "上传完成", msg)
# 重置进度条
self.progress_bar.reset()
def closeEvent(self, event):
"""窗口关闭事件"""
if self.upload_thread and self.upload_thread.isRunning():
reply = QMessageBox.question(
self, '确认退出',
'上传正在进行中,确定要退出吗?',
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
)
if reply == QMessageBox.Yes:
self.upload_thread.stop()
self.upload_thread.wait()
event.accept()
else:
event.ignore()
else:
event.accept()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = VideoUploaderApp()
window.show()
sys.exit(app.exec_())