Commit 4f8ebab8 by Yuhaibo

1

parent 21a67d1a
......@@ -1240,6 +1240,9 @@ class MainWindow(
# 默认显示第一个子页面(数据采集)
self.datasetStackWidget.setCurrentIndex(0)
# 连接切换信号,实现切换时刷新文件列表
self.datasetStackWidget.currentChanged.connect(self._onDatasetSubPageChanged)
page_layout.addWidget(self.datasetStackWidget)
return page
......@@ -1369,6 +1372,21 @@ class MainWindow(
self.datasetStackWidget.setCurrentIndex(2) # 切换到数据标注子页面
self.statusBar().showMessage(self.tr("当前页面: 数据集管理 - 数据标注"))
def _onDatasetSubPageChanged(self, index):
"""
数据集子页面切换时的回调
Args:
index: 当前子页面索引(0=数据采集, 1=数据预处理, 2=数据标注, 3=模型训练)
"""
# 刷新数据采集和数据预处理页面的左侧文件列表
if index == 0: # 数据采集
if hasattr(self, 'dataCollectionPanel') and self.dataCollectionPanel:
self.dataCollectionPanel.refreshFolders()
elif index == 1: # 数据预处理
if hasattr(self, 'dataPreprocessPanel') and self.dataPreprocessPanel:
self.dataPreprocessPanel.refreshFolders()
def _showModelSetsTab(self):
"""显示模型集管理选项卡"""
self.showModelPage() # 先切换到模型管理页面
......
......@@ -184,12 +184,12 @@ class DataCollectionChannelHandler:
if channel_config:
success = self._connectRealChannel(channel_config)
if not success:
error_detail = f"无法连接到配置的通道 {channel_source}\n请检查:\n1. 相机是否已开机并连接到网络\n2. IP地址和端口是否正确"
error_detail = f"无法连接到配置的通道 {channel_source}\n请检查:\n 相机是否已开机并连接到网络\n2. IP地址和端口是否正确"
else:
# 如果没有配置,尝试直接连接USB通道
success = self._connectUSBChannel(channel_source)
if not success:
error_detail = f"无法连接到USB通道 {channel_source}\n请检查:\n1. USB相机是否已连接\n2. 相机驱动是否已安装\n3. 相机是否被其他程序占用"
error_detail = f"无法连接到USB通道 {channel_source}\n请检查:\nUSB相机是否已连接\n2. 相机驱动是否已安装\n3. 相机是否被其他程序占用"
else:
# 如果是RTSP地址,直接连接
success = self._connectRTSPChannel(channel_source)
......@@ -853,6 +853,9 @@ class DataCollectionChannelHandler:
self._dc_video_writer.release()
self._dc_video_writer = None
# 等待文件系统完成写入(确保文件完全写入磁盘)
time.sleep(0.5)
return True
except Exception as e:
......
......@@ -116,14 +116,21 @@ class SettingsHandler:
def showAbout(self):
"""显示关于对话框"""
QtWidgets.QMessageBox.about(
self,
self.tr("关于"),
self.tr(
"<h2>帕特智能油液位检测</h2>"
"<p>版本: 1.0</p>"
)
try:
from widgets.style_manager import DialogManager
except ImportError:
DialogManager = None
message = (
"<h2>帕特智能油液位检测</h2>"
"<p>版本: 1.0</p>"
)
if DialogManager:
DialogManager.show_about(self, "关于", message)
else:
# 降级方案:使用标准对话框
QtWidgets.QMessageBox.about(self, "关于", message)
def showDocumentation(self):
"""显示帮助文档 - 打开用户手册"""
......
......@@ -511,6 +511,7 @@ class DataCollectionPanel(QtWidgets.QWidget):
folder_path = osp.join(self._root_path, folder_name)
if not osp.exists(folder_path):
print(f"[数据采集] 文件夹不存在: {folder_path}")
return
try:
......@@ -519,6 +520,8 @@ class DataCollectionPanel(QtWidgets.QWidget):
if osp.isfile(osp.join(folder_path, f))]
files.sort()
print(f"[数据采集] 在文件夹 {folder_name} 中找到 {len(files)} 个文件")
# 添加到列表
for file in files:
file_path = osp.join(folder_path, file)
......@@ -543,8 +546,9 @@ class DataCollectionPanel(QtWidgets.QWidget):
if thumbnail:
item.setIcon(QtGui.QIcon(thumbnail))
else:
# 缩略图生成失败,不显示图标(避免在录制过程中显示播放按钮)
item.setIcon(QtGui.QIcon()) # 空图标
# 缩略图生成失败,使用默认视频图标
icon = self.style().standardIcon(QtWidgets.QStyle.SP_MediaPlay)
item.setIcon(icon)
item.setText(f"\n{display_name}")
elif file_ext in ['.jpg', '.jpeg', '.png', '.bmp']:
# 图片文件 - 加载图片作为缩略图
......@@ -575,11 +579,19 @@ class DataCollectionPanel(QtWidgets.QWidget):
"""生成视频缩略图(提取第一帧)"""
try:
import cv2
import time
# 打开视频文件
cap = cv2.VideoCapture(video_path)
# 尝试多次打开视频文件(刚录制完成的文件可能需要等待)
cap = None
for attempt in range(3):
cap = cv2.VideoCapture(video_path)
if cap.isOpened():
break
if cap:
cap.release()
time.sleep(0.1) # 等待100ms后重试
if not cap.isOpened():
if not cap or not cap.isOpened():
return None
# 读取第一帧
......@@ -589,6 +601,11 @@ class DataCollectionPanel(QtWidgets.QWidget):
if not ret or frame is None:
return None
# 检查 QGuiApplication 是否存在(避免应用关闭时出错)
from qtpy.QtWidgets import QApplication
if not QApplication.instance():
return None
# 转换颜色空间 BGR -> RGB
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
......@@ -613,6 +630,11 @@ class DataCollectionPanel(QtWidgets.QWidget):
def _generateImageThumbnail(self, image_path):
"""生成图片缩略图"""
try:
# 检查 QGuiApplication 是否存在(避免应用关闭时出错)
from qtpy.QtWidgets import QApplication
if not QApplication.instance():
return None
# 加载图片
pixmap = QtGui.QPixmap(image_path)
......@@ -635,11 +657,11 @@ class DataCollectionPanel(QtWidgets.QWidget):
"""检查文件是否正在被录制"""
try:
# 检查父窗口是否有录制状态信息
if not hasattr(self._parent, '_dc_save_flag'):
if not hasattr(self._parent, '_dc_video_recording'):
return False
# 如果没有在录制,返回False
if not getattr(self._parent, '_dc_save_flag', False):
if not getattr(self._parent, '_dc_video_recording', False):
return False
# 检查是否是当前录制的文件
......@@ -657,7 +679,7 @@ class DataCollectionPanel(QtWidgets.QWidget):
except (IOError, OSError):
# 文件被占用,可能正在录制
# 但只有在确实在录制状态时才返回True
return getattr(self._parent, '_dc_save_flag', False)
return getattr(self._parent, '_dc_video_recording', False)
except Exception as e:
# 发生异常时,为安全起见不隐藏文件
......@@ -923,7 +945,7 @@ class DataCollectionPanel(QtWidgets.QWidget):
if self._current_folder:
self._loadFolderContent(self._current_folder)
self._showInformation("成功", f"文件已删除\n{file_name}")
except Exception as e:
self._showCritical("错误", f"删除文件失败:\n{str(e)}")
......@@ -1152,9 +1174,12 @@ class DataCollectionPanel(QtWidgets.QWidget):
self.btn_record_video.clicked.connect(self._onRecordVideo)
if success:
print(f"[数据采集] 录制停止成功,准备刷新文件列表")
print(f"[数据采集] 当前文件夹: {self._current_folder}")
# 刷新内容列表(显示新录制的视频)
if self._current_folder:
self._loadFolderContent(self._current_folder)
print(f"[数据采集] 文件列表已刷新")
else:
self._showWarning("录制失败", "录制时间过短,未能保存任何视频帧\n请确保录制时间足够长")
else:
......
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