Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
Oil_Level_Recognition_System
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
柳青君
Oil_Level_Recognition_System
Commits
4f8ebab8
Commit
4f8ebab8
authored
Nov 27, 2025
by
Yuhaibo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1
parent
21a67d1a
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
71 additions
and
18 deletions
+71
-18
app.py
app.py
+18
-0
datacollection_channel_handler.py
handlers/datasetpage/datacollection_channel_handler.py
+5
-2
settings_handler.py
handlers/settings_handler.py
+14
-7
datacollection_panel.py
widgets/datasetpage/datacollection_panel.py
+34
-9
style_manager.py
widgets/style_manager.py
+0
-0
No files found.
app.py
View file @
4f8ebab8
...
...
@@ -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
()
# 先切换到模型管理页面
...
...
handlers/datasetpage/datacollection_channel_handler.py
View file @
4f8ebab8
...
...
@@ -184,12 +184,12 @@ class DataCollectionChannelHandler:
if
channel_config
:
success
=
self
.
_connectRealChannel
(
channel_config
)
if
not
success
:
error_detail
=
f
"无法连接到配置的通道 {channel_source}
\n
请检查:
\n
1.
相机是否已开机并连接到网络
\n
2. IP地址和端口是否正确"
error_detail
=
f
"无法连接到配置的通道 {channel_source}
\n
请检查:
\n
相机是否已开机并连接到网络
\n
2. IP地址和端口是否正确"
else
:
# 如果没有配置,尝试直接连接USB通道
success
=
self
.
_connectUSBChannel
(
channel_source
)
if
not
success
:
error_detail
=
f
"无法连接到USB通道 {channel_source}
\n
请检查:
\n
1.
USB相机是否已连接
\n
2. 相机驱动是否已安装
\n
3. 相机是否被其他程序占用"
error_detail
=
f
"无法连接到USB通道 {channel_source}
\n
请检查:
\n
USB相机是否已连接
\n
2. 相机驱动是否已安装
\n
3. 相机是否被其他程序占用"
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
:
...
...
handlers/settings_handler.py
View file @
4f8ebab8
...
...
@@ -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
):
"""显示帮助文档 - 打开用户手册"""
...
...
widgets/datasetpage/datacollection_panel.py
View file @
4f8ebab8
...
...
@@ -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_fla
g'
):
if
not
hasattr
(
self
.
_parent
,
'_dc_
video_recordin
g'
):
return
False
# 如果没有在录制,返回False
if
not
getattr
(
self
.
_parent
,
'_dc_
save_fla
g'
,
False
):
if
not
getattr
(
self
.
_parent
,
'_dc_
video_recordin
g'
,
False
):
return
False
# 检查是否是当前录制的文件
...
...
@@ -657,7 +679,7 @@ class DataCollectionPanel(QtWidgets.QWidget):
except
(
IOError
,
OSError
):
# 文件被占用,可能正在录制
# 但只有在确实在录制状态时才返回True
return
getattr
(
self
.
_parent
,
'_dc_
save_fla
g'
,
False
)
return
getattr
(
self
.
_parent
,
'_dc_
video_recordin
g'
,
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
:
...
...
widgets/style_manager.py
View file @
4f8ebab8
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment