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
Administrator
Oil_Level_Recognition_System
Commits
e8ce54c3
Commit
e8ce54c3
authored
Nov 29, 2025
by
Yuhaibo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1
parent
34bd34cc
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
572 additions
and
222 deletions
+572
-222
app.py
app.py
+12
-13
annotation_result.yaml
database/config/annotation_result.yaml
+5
-5
channel_config.yaml
database/config/channel_config.yaml
+12
-12
通道2_区域1.csv
database/mission_result/123_21/通道2_区域1.csv
+37
-1
通道1_区域1.csv
database/mission_result/1_2/通道1_区域1.csv
+163
-1
通道2_区域1.csv
database/mission_result/1_2/通道2_区域1.csv
+23
-0
通道1_区域1.csv
database/mission_result/1_222/通道1_区域1.csv
+0
-0
通道2_区域1.csv
database/mission_result/1_222/通道2_区域1.csv
+38
-1
通道3_区域1.csv
database/mission_result/1_222/通道3_区域1.csv
+51
-1
通道4_区域1.csv
database/mission_result/1_222/通道4_区域1.csv
+69
-1
channelpanel_handler.py
handlers/videopage/channelpanel_handler.py
+0
-14
curvepanel_handler.py
handlers/videopage/curvepanel_handler.py
+61
-21
missionpanel_handler.py
handlers/videopage/missionpanel_handler.py
+8
-119
storage_thread.py
handlers/videopage/thread_manager/threads/storage_thread.py
+8
-1
view_handler.py
handlers/view_handler.py
+48
-28
软件功能逻辑设计.md
rules/软件功能逻辑设计.md
+10
-1
channelpanel.py
widgets/videopage/channelpanel.py
+27
-3
No files found.
app.py
View file @
e8ce54c3
...
@@ -777,7 +777,7 @@ class MainWindow(
...
@@ -777,7 +777,7 @@ class MainWindow(
# 保存第一个面板的引用(兼容现有代码)
# 保存第一个面板的引用(兼容现有代码)
self
.
channelPanel
=
self
.
channelPanels
[
0
]
if
self
.
channelPanels
else
None
self
.
channelPanel
=
self
.
channelPanels
[
0
]
if
self
.
channelPanels
else
None
# 🔥 创建4个历史视频面板(用于曲线模式
的历史回放
布局)
# 🔥 创建4个历史视频面板(用于曲线模式
布局的历史回放子
布局)
try
:
try
:
from
.widgets.videopage
import
HistoryVideoPanel
from
.widgets.videopage
import
HistoryVideoPanel
except
ImportError
:
except
ImportError
:
...
@@ -804,8 +804,8 @@ class MainWindow(
...
@@ -804,8 +804,8 @@ class MainWindow(
"""创建曲线模式布局:左侧垂直排列通道 + 右侧曲线面板
"""创建曲线模式布局:左侧垂直排列通道 + 右侧曲线面板
包含两个子布局:
包含两个子布局:
- 子布局0:
实时检测模式
(带任务选择和底部按钮)
- 子布局0:
同步布局
(带任务选择和底部按钮)
- 子布局1:历史回放
模式
(无任务选择和底部按钮)
- 子布局1:历史回放
布局
(无任务选择和底部按钮)
🔥 两个子布局共用同一个CurvePanel(右侧)
🔥 两个子布局共用同一个CurvePanel(右侧)
"""
"""
...
@@ -836,12 +836,12 @@ class MainWindow(
...
@@ -836,12 +836,12 @@ class MainWindow(
# 🔥 创建左侧子布局栈(实时检测 vs 历史回放)
# 🔥 创建左侧子布局栈(实时检测 vs 历史回放)
self
.
curveLayoutStack
=
QtWidgets
.
QStackedWidget
()
self
.
curveLayoutStack
=
QtWidgets
.
QStackedWidget
()
self
.
curveLayoutStack
.
setFixedWidth
(
660
)
self
.
curveLayoutStack
.
setFixedWidth
(
660
)
self
.
_curve_sub_layout_mode
=
0
# 0=
实时检测, 1=历史回放
self
.
_curve_sub_layout_mode
=
0
# 0=
同步布局, 1=历史回放布局
# === 子布局0:
实时检测模式
(左侧通道列表)===
# === 子布局0:
同步布局
(左侧通道列表)===
self
.
_createRealtimeCurveSubLayout
()
self
.
_createRealtimeCurveSubLayout
()
# === 子布局1:历史回放
模式
(左侧历史视频面板容器)===
# === 子布局1:历史回放
布局
(左侧历史视频面板容器)===
self
.
_createHistoryCurveSubLayout
()
self
.
_createHistoryCurveSubLayout
()
# 布局结构:左侧子布局栈 + 右侧共用CurvePanel
# 布局结构:左侧子布局栈 + 右侧共用CurvePanel
...
@@ -873,7 +873,7 @@ class MainWindow(
...
@@ -873,7 +873,7 @@ class MainWindow(
self
.
curve_channel_layout
.
setContentsMargins
(
5
,
5
,
5
,
5
)
self
.
curve_channel_layout
.
setContentsMargins
(
5
,
5
,
5
,
5
)
self
.
curve_channel_layout
.
setSpacing
(
10
)
self
.
curve_channel_layout
.
setSpacing
(
10
)
# 初始化通道包裹容器列表(
实时检测模式
)
# 初始化通道包裹容器列表(
同步布局
)
self
.
channel_widgets_for_curve
=
[]
self
.
channel_widgets_for_curve
=
[]
# 创建4个通道容器(初始隐藏,等待CSV文件加载)
# 创建4个通道容器(初始隐藏,等待CSV文件加载)
...
@@ -916,7 +916,7 @@ class MainWindow(
...
@@ -916,7 +916,7 @@ class MainWindow(
self
.
history_channel_layout
.
setContentsMargins
(
5
,
5
,
5
,
5
)
self
.
history_channel_layout
.
setContentsMargins
(
5
,
5
,
5
,
5
)
self
.
history_channel_layout
.
setSpacing
(
10
)
self
.
history_channel_layout
.
setSpacing
(
10
)
# 初始化历史视频包裹容器列表(历史回放
模式
)
# 初始化历史视频包裹容器列表(历史回放
布局
)
self
.
history_channel_widgets_for_curve
=
[]
self
.
history_channel_widgets_for_curve
=
[]
# 创建4个历史视频容器(初始隐藏,等待CSV文件加载)
# 创建4个历史视频容器(初始隐藏,等待CSV文件加载)
...
@@ -965,10 +965,10 @@ class MainWindow(
...
@@ -965,10 +965,10 @@ class MainWindow(
# 🔥 根据检测状态决定显示逻辑(而不是依赖 getCurveLoadMode)
# 🔥 根据检测状态决定显示逻辑(而不是依赖 getCurveLoadMode)
if
detection_running
:
if
detection_running
:
# 🔥
实时检测模式
:只显示任务配置中使用的通道
# 🔥
同步布局
:只显示任务配置中使用的通道
selected_channels
=
self
.
_getTaskChannels
(
mission_name
)
selected_channels
=
self
.
_getTaskChannels
(
mission_name
)
else
:
else
:
# 🔥 历史回放
模式
:显示所有通道容器
# 🔥 历史回放
布局
:显示所有通道容器
selected_channels
=
[
'通道1'
,
'通道2'
,
'通道3'
,
'通道4'
]
selected_channels
=
[
'通道1'
,
'通道2'
,
'通道3'
,
'通道4'
]
self
.
_updateCurveChannelDisplay
(
selected_channels
)
self
.
_updateCurveChannelDisplay
(
selected_channels
)
...
@@ -1087,11 +1087,11 @@ class MainWindow(
...
@@ -1087,11 +1087,11 @@ class MainWindow(
# 🔥 根据当前曲线子布局模式选择要操作的容器
# 🔥 根据当前曲线子布局模式选择要操作的容器
if
hasattr
(
self
,
'_curve_sub_layout_mode'
):
if
hasattr
(
self
,
'_curve_sub_layout_mode'
):
if
self
.
_curve_sub_layout_mode
==
0
:
if
self
.
_curve_sub_layout_mode
==
0
:
#
实时检测模式
:操作channel_widgets_for_curve
#
同步布局
:操作channel_widgets_for_curve
target_widgets
=
self
.
channel_widgets_for_curve
if
hasattr
(
self
,
'channel_widgets_for_curve'
)
else
[]
target_widgets
=
self
.
channel_widgets_for_curve
if
hasattr
(
self
,
'channel_widgets_for_curve'
)
else
[]
target_container
=
self
.
curve_channel_container
if
hasattr
(
self
,
'curve_channel_container'
)
else
None
target_container
=
self
.
curve_channel_container
if
hasattr
(
self
,
'curve_channel_container'
)
else
None
else
:
else
:
# 历史回放
模式
:操作history_channel_widgets_for_curve
# 历史回放
布局
:操作history_channel_widgets_for_curve
target_widgets
=
self
.
history_channel_widgets_for_curve
if
hasattr
(
self
,
'history_channel_widgets_for_curve'
)
else
[]
target_widgets
=
self
.
history_channel_widgets_for_curve
if
hasattr
(
self
,
'history_channel_widgets_for_curve'
)
else
[]
target_container
=
self
.
history_channel_container
if
hasattr
(
self
,
'history_channel_container'
)
else
None
target_container
=
self
.
history_channel_container
if
hasattr
(
self
,
'history_channel_container'
)
else
None
else
:
else
:
...
@@ -1131,7 +1131,6 @@ class MainWindow(
...
@@ -1131,7 +1131,6 @@ class MainWindow(
if
target_container
:
if
target_container
:
target_container
.
setFixedSize
(
640
,
total_height
)
target_container
.
setFixedSize
(
640
,
total_height
)
print
(
f
"[曲线布局] 已更新通道显示,显示 {visible_count} 个通道"
)
def
_createModelPage
(
self
):
def
_createModelPage
(
self
):
"""创建模型管理页面"""
"""创建模型管理页面"""
...
...
database/config/annotation_result.yaml
View file @
e8ce54c3
...
@@ -5,14 +5,14 @@ channel1:
...
@@ -5,14 +5,14 @@ channel1:
height
:
20mm
height
:
20mm
name
:
通道1_区域1
name
:
通道1_区域1
boxes
:
boxes
:
-
-
8
81
-
-
8
55
-
7
99
-
7
37
-
192
-
192
fixed_bottoms
:
fixed_bottoms
:
-
8
75
-
8
13
fixed_tops
:
fixed_tops
:
-
722
-
660
last_updated
:
'
2025-11-29
1
6:02:16
'
last_updated
:
'
2025-11-29
1
7:01:13
'
channel2
:
channel2
:
annotation_count
:
1
annotation_count
:
1
areas
:
areas
:
...
...
database/config/channel_config.yaml
View file @
e8ce54c3
...
@@ -17,23 +17,23 @@ channels:
...
@@ -17,23 +17,23 @@ channels:
name
:
'
4'
name
:
'
4'
channel2
:
channel2
:
general
:
general
:
task_id
:
'
21
'
task_id
:
'
123
'
task_name
:
'
3
21'
task_name
:
'
21'
save_liquid_data_path
:
d:\restructure\liquid_level_line_detection_system\database\mission_result\
21_3
21
save_liquid_data_path
:
d:\restructure\liquid_level_line_detection_system\database\mission_result\
123_
21
channel3
:
channel3
:
general
:
general
:
task_id
:
'
21
'
task_id
:
'
123
'
task_name
:
'
3
21'
task_name
:
'
21'
save_liquid_data_path
:
d:\restructure\liquid_level_line_detection_system\database\mission_result\
21_3
21
save_liquid_data_path
:
d:\restructure\liquid_level_line_detection_system\database\mission_result\
123_
21
channel4
:
channel4
:
general
:
general
:
task_id
:
'
2
1'
task_id
:
'
1'
task_name
:
'
321
'
task_name
:
'
222
'
save_liquid_data_path
:
d:\restructure\liquid_level_line_detection_system\database\mission_result\
21_321
save_liquid_data_path
:
d:\restructure\liquid_level_line_detection_system\database\mission_result\
1_222
channel1
:
channel1
:
general
:
general
:
task_id
:
'
2
1'
task_id
:
'
1'
task_name
:
'
321
'
task_name
:
'
222
'
area_count
:
0
area_count
:
0
safe_low
:
2.0mm
safe_low
:
2.0mm
safe_high
:
10.0mm
safe_high
:
10.0mm
...
@@ -41,7 +41,7 @@ channel1:
...
@@ -41,7 +41,7 @@ channel1:
video_format
:
AVI
video_format
:
AVI
push_address
:
'
'
push_address
:
'
'
video_path
:
'
'
video_path
:
'
'
save_liquid_data_path
:
d:\restructure\liquid_level_line_detection_system\database\mission_result\
21_321
save_liquid_data_path
:
d:\restructure\liquid_level_line_detection_system\database\mission_result\
1_222
areas
:
areas
:
area_1
:
通道1_区域1
area_1
:
通道1_区域1
area_heights
:
area_heights
:
...
...
database/mission_result/123_21/通道2_区域1.csv
View file @
e8ce54c3
2025-
11-29-13:26:33.445 0.0
2025-
11-29-13:26:33.445 0.0
...
@@ -440,3 +440,39 @@
...
@@ -440,3 +440,39 @@
2025-11-29-13:28:03.293 16.6
2025-11-29-13:28:03.293 16.6
2025-11-29-13:28:03.550 17.1
2025-11-29-13:28:03.550 17.1
2025-11-29-13:28:03.718 16.3
2025-11-29-13:28:03.718 16.3
2025-11-29-16:41:31.498 0.0
2025-11-29-16:41:31.526 0.0
2025-11-29-16:41:31.858 0.0
2025-11-29-16:41:31.933 0.0
2025-11-29-16:41:32.136 0.0
2025-11-29-16:41:32.334 0.0
2025-11-29-16:41:32.548 0.0
2025-11-29-16:41:32.746 0.0
2025-11-29-16:41:32.943 0.0
2025-11-29-16:41:33.147 0.0
2025-11-29-16:41:33.348 0.0
2025-11-29-16:41:33.540 0.0
2025-11-29-16:41:33.750 0.0
2025-11-29-16:41:33.953 0.0
2025-11-29-16:41:34.146 0.0
2025-11-29-16:41:34.361 0.0
2025-11-29-16:41:34.554 0.0
2025-11-29-17:26:08.241 0.0
2025-11-29-17:26:08.278 0.0
2025-11-29-17:26:08.481 0.0
2025-11-29-17:26:08.684 0.0
2025-11-29-17:26:08.883 0.0
2025-11-29-17:26:09.085 0.0
2025-11-29-17:26:09.287 0.0
2025-11-29-17:26:09.484 0.0
2025-11-29-17:26:09.679 0.0
2025-11-29-17:26:09.998 0.0
2025-11-29-17:26:10.233 0.0
2025-11-29-17:26:10.298 0.0
2025-11-29-17:26:10.504 0.0
2025-11-29-17:26:10.708 0.0
2025-11-29-17:26:10.890 0.0
2025-11-29-17:26:11.101 0.0
2025-11-29-17:26:11.295 0.0
2025-11-29-17:26:11.496 0.0
2025-11-29-17:26:11.704 0.0
database/mission_result/1_2/通道1_区域1.csv
View file @
e8ce54c3
2025-
11-29-11:16:22.428 0.0
2025-
11-29-11:16:22.428 0.0
...
@@ -1710,3 +1710,165 @@
...
@@ -1710,3 +1710,165 @@
2025-11-29-13:51:30.788 0.0
2025-11-29-13:51:30.788 0.0
2025-11-29-13:51:30.985 0.0
2025-11-29-13:51:30.985 0.0
2025-11-29-13:51:31.195 0.0
2025-11-29-13:51:31.195 0.0
2025-11-29-16:14:35.854 0.0
2025-11-29-16:14:35.891 0.0
2025-11-29-16:14:36.123 0.0
2025-11-29-16:14:36.313 0.0
2025-11-29-16:14:36.518 0.0
2025-11-29-16:14:36.735 0.0
2025-11-29-16:14:36.956 0.0
2025-11-29-16:14:37.137 0.0
2025-11-29-16:14:37.337 0.0
2025-11-29-16:14:37.552 0.0
2025-11-29-16:14:37.765 0.0
2025-11-29-16:14:37.957 0.0
2025-11-29-16:14:38.163 0.0
2025-11-29-16:14:38.369 0.0
2025-11-29-16:14:38.577 0.0
2025-11-29-16:14:38.790 0.0
2025-11-29-16:14:38.979 0.0
2025-11-29-16:14:39.181 0.0
2025-11-29-16:14:39.378 0.0
2025-11-29-16:14:39.609 0.0
2025-11-29-16:14:39.808 0.0
2025-11-29-16:14:40.003 0.0
2025-11-29-16:14:40.221 0.0
2025-11-29-16:14:40.496 18.2
2025-11-29-16:14:40.626 0.0
2025-11-29-16:14:40.828 0.0
2025-11-29-16:14:41.026 0.0
2025-11-29-16:14:41.228 0.0
2025-11-29-16:14:41.427 0.0
2025-11-29-16:14:41.628 0.0
2025-11-29-16:14:41.837 0.0
2025-11-29-16:14:42.036 0.0
2025-11-29-16:14:42.241 0.0
2025-11-29-16:14:42.443 0.0
2025-11-29-16:14:42.661 0.0
2025-11-29-16:14:42.874 0.0
2025-11-29-16:14:43.076 0.0
2025-11-29-16:14:43.290 0.0
2025-11-29-16:14:43.491 0.0
2025-11-29-16:14:43.717 0.0
2025-11-29-16:14:43.908 0.0
2025-11-29-16:14:44.111 0.0
2025-11-29-16:14:44.336 0.0
2025-11-29-16:14:44.505 0.0
2025-11-29-16:14:44.719 0.0
2025-11-29-16:14:44.919 0.0
2025-11-29-16:14:45.180 0.0
2025-11-29-16:14:45.309 0.0
2025-11-29-16:14:45.519 0.0
2025-11-29-16:14:45.715 0.0
2025-11-29-16:14:45.929 0.0
2025-11-29-16:14:46.148 0.0
2025-11-29-16:14:46.335 0.0
2025-11-29-16:14:46.525 0.0
2025-11-29-16:14:46.724 0.0
2025-11-29-16:14:46.925 0.0
2025-11-29-16:14:47.116 0.0
2025-11-29-16:14:47.330 0.0
2025-11-29-16:14:47.540 0.0
2025-11-29-16:14:47.724 0.0
2025-11-29-16:14:47.929 0.0
2025-11-29-16:14:48.143 0.0
2025-11-29-16:14:48.346 0.0
2025-11-29-16:14:48.533 0.0
2025-11-29-16:14:48.744 0.0
2025-11-29-16:14:48.950 0.0
2025-11-29-16:14:49.159 0.0
2025-11-29-16:14:49.352 0.0
2025-11-29-16:14:49.552 0.0
2025-11-29-16:14:49.746 0.0
2025-11-29-16:14:49.933 0.0
2025-11-29-16:14:50.105 0.0
2025-11-29-16:14:50.316 0.0
2025-11-29-16:14:50.519 0.0
2025-11-29-16:14:50.722 0.0
2025-11-29-16:14:50.924 0.0
2025-11-29-16:14:51.137 0.0
2025-11-29-16:14:51.346 0.0
2025-11-29-16:14:51.538 0.0
2025-11-29-16:14:51.738 0.0
2025-11-29-16:14:51.943 0.0
2025-11-29-16:14:52.147 0.0
2025-11-29-16:14:52.364 0.0
2025-11-29-16:14:52.573 0.0
2025-11-29-16:14:52.771 0.0
2025-11-29-16:14:52.980 0.0
2025-11-29-16:14:53.182 0.0
2025-11-29-16:14:53.395 0.0
2025-11-29-16:14:53.595 0.0
2025-11-29-16:14:53.791 0.0
2025-11-29-16:14:53.999 0.0
2025-11-29-16:14:54.207 0.0
2025-11-29-16:14:54.415 0.0
2025-11-29-16:14:54.628 0.0
2025-11-29-16:14:54.850 0.0
2025-11-29-16:14:55.027 0.0
2025-11-29-16:14:55.234 0.0
2025-11-29-16:14:55.427 0.0
2025-11-29-16:14:55.641 0.0
2025-11-29-16:14:55.851 0.0
2025-11-29-16:14:56.033 0.0
2025-11-29-16:14:56.244 0.0
2025-11-29-16:14:56.445 0.0
2025-11-29-16:14:56.647 0.0
2025-11-29-16:14:56.851 0.0
2025-11-29-16:14:57.049 0.0
2025-11-29-16:14:57.254 0.0
2025-11-29-16:14:57.453 0.0
2025-11-29-16:14:57.655 0.0
2025-11-29-16:14:57.855 0.0
2025-11-29-16:14:58.054 0.0
2025-11-29-16:14:58.262 0.0
2025-11-29-16:14:58.458 0.0
2025-11-29-16:14:58.661 0.0
2025-11-29-16:14:58.864 0.0
2025-11-29-16:14:59.066 0.0
2025-11-29-16:14:59.269 0.0
2025-11-29-16:14:59.469 0.0
2025-11-29-16:14:59.675 0.0
2025-11-29-16:14:59.876 0.0
2025-11-29-16:15:00.082 0.0
2025-11-29-16:15:00.288 19.1
2025-11-29-16:15:00.508 0.0
2025-11-29-16:15:00.681 0.0
2025-11-29-16:15:00.901 0.0
2025-11-29-16:15:01.095 0.0
2025-11-29-16:15:01.302 19.2
2025-11-29-16:15:01.526 18.7
2025-11-29-16:15:01.695 0.0
2025-11-29-16:15:01.926 18.7
2025-11-29-16:15:02.125 18.3
2025-11-29-16:15:02.309 18.4
2025-11-29-16:15:02.509 0.0
2025-11-29-16:15:02.715 18.4
2025-11-29-16:15:02.940 18.7
2025-11-29-16:15:03.121 0.0
2025-11-29-16:15:03.318 0.0
2025-11-29-16:15:03.534 18.3
2025-11-29-16:15:03.719 0.0
2025-11-29-16:15:03.952 0.0
2025-11-29-16:15:04.117 0.0
2025-11-29-16:15:04.375 18.4
2025-11-29-16:15:04.554 18.3
2025-11-29-16:15:04.740 18.3
2025-11-29-16:15:04.944 0.0
2025-11-29-16:15:05.148 0.0
2025-11-29-16:15:05.356 0.0
2025-11-29-16:15:05.543 0.0
2025-11-29-16:15:05.826 0.0
2025-11-29-16:15:05.955 0.0
2025-11-29-16:15:06.113 0.0
2025-11-29-16:15:06.316 0.0
2025-11-29-16:15:06.521 0.0
2025-11-29-16:15:06.726 0.0
2025-11-29-16:15:06.914 0.0
2025-11-29-16:15:07.123 18.3
2025-11-29-16:15:07.318 0.0
2025-11-29-16:15:07.520 0.0
2025-11-29-16:15:07.725 0.0
2025-11-29-16:15:07.984 0.0
2025-11-29-16:15:08.186 0.0
2025-11-29-16:15:08.389 18.3
database/mission_result/1_2/通道2_区域1.csv
0 → 100644
View file @
e8ce54c3
2025-11-29-16:14:45.309 0.0
2025-11-29-16:14:45.309 0.0
2025-11-29-16:14:45.519 0.0
2025-11-29-16:14:45.715 0.0
2025-11-29-16:14:45.929 0.0
2025-11-29-16:14:46.148 0.0
2025-11-29-16:14:46.335 0.0
2025-11-29-16:14:46.525 0.0
2025-11-29-16:14:46.724 0.0
2025-11-29-16:14:46.925 0.0
2025-11-29-16:14:47.116 0.0
2025-11-29-16:14:47.330 0.0
2025-11-29-16:14:47.540 0.0
2025-11-29-16:14:47.724 0.0
2025-11-29-16:14:47.929 0.0
2025-11-29-16:14:48.143 0.0
2025-11-29-16:14:48.346 0.0
2025-11-29-16:14:48.533 0.0
2025-11-29-16:14:48.744 0.0
2025-11-29-16:14:48.950 0.0
2025-11-29-16:14:49.159 0.0
2025-11-29-16:14:49.352 0.0
2025-11-29-16:14:49.552 0.0
database/mission_result/1_222/通道1_区域1.csv
View file @
e8ce54c3
This source diff could not be displayed because it is too large. You can
view the blob
instead.
database/mission_result/1_222/通道2_区域1.csv
View file @
e8ce54c3
2025-
11-29-12:49:02.930 0.0
2025-
11-29-12:49:02.930 0.0
...
@@ -317,3 +317,40 @@
...
@@ -317,3 +317,40 @@
2025-11-29-15:49:07.323 0.0
2025-11-29-15:49:07.323 0.0
2025-11-29-15:49:07.844 0.0
2025-11-29-15:49:07.844 0.0
2025-11-29-15:49:08.416 0.0
2025-11-29-15:49:08.416 0.0
2025-11-29-16:16:55.866 0.0
2025-11-29-16:16:56.435 0.0
2025-11-29-16:16:57.084 0.0
2025-11-29-16:16:57.981 0.0
2025-11-29-16:16:58.641 0.0
2025-11-29-16:16:59.614 0.0
2025-11-29-16:17:00.740 0.0
2025-11-29-16:17:01.434 0.0
2025-11-29-16:17:01.711 0.0
2025-11-29-16:17:01.974 0.0
2025-11-29-16:17:02.249 0.0
2025-11-29-16:17:02.487 0.0
2025-11-29-16:17:02.683 0.0
2025-11-29-16:17:33.877 0.0
2025-11-29-16:17:34.285 0.0
2025-11-29-16:17:34.707 0.0
2025-11-29-16:17:34.989 0.0
2025-11-29-16:17:35.474 0.0
2025-11-29-16:17:35.846 0.0
2025-11-29-16:17:36.138 0.0
2025-11-29-16:17:36.596 0.0
2025-11-29-16:17:37.087 0.0
2025-11-29-16:17:37.601 0.0
2025-11-29-16:17:38.152 0.0
2025-11-29-16:17:38.675 0.0
2025-11-29-16:17:39.166 0.0
2025-11-29-16:17:39.598 0.0
2025-11-29-16:17:39.935 0.0
2025-11-29-16:17:40.111 0.0
2025-11-29-16:17:40.326 0.0
2025-11-29-16:17:40.516 0.0
2025-11-29-16:17:40.732 0.0
2025-11-29-16:17:40.815 0.0
2025-11-29-16:17:41.026 0.0
2025-11-29-16:17:41.215 0.0
2025-11-29-16:17:41.428 0.0
2025-11-29-16:17:41.634 0.0
database/mission_result/1_222/通道3_区域1.csv
View file @
e8ce54c3
2025-
11-29-15:48:49.971 0.0
2025-
11-29-15:48:49.971 0.0
...
@@ -52,3 +52,53 @@
...
@@ -52,3 +52,53 @@
2025-11-29-15:49:07.323 0.0
2025-11-29-15:49:07.323 0.0
2025-11-29-15:49:07.850 0.0
2025-11-29-15:49:07.850 0.0
2025-11-29-15:49:08.419 0.0
2025-11-29-15:49:08.419 0.0
2025-11-29-16:16:55.866 0.0
2025-11-29-16:16:56.435 0.0
2025-11-29-16:16:57.090 0.0
2025-11-29-16:16:57.981 0.0
2025-11-29-16:16:58.648 0.0
2025-11-29-16:16:59.614 0.0
2025-11-29-16:17:00.741 0.0
2025-11-29-16:17:01.434 0.0
2025-11-29-16:17:01.711 0.0
2025-11-29-16:17:01.974 0.0
2025-11-29-16:17:02.249 0.0
2025-11-29-16:17:02.487 0.0
2025-11-29-16:17:02.683 0.0
2025-11-29-16:17:02.871 0.0
2025-11-29-16:17:03.038 0.0
2025-11-29-16:17:03.197 0.0
2025-11-29-16:17:03.453 0.0
2025-11-29-16:17:03.642 0.0
2025-11-29-16:17:03.803 0.0
2025-11-29-16:17:04.008 0.0
2025-11-29-16:17:04.216 0.0
2025-11-29-16:17:30.725 0.0
2025-11-29-16:17:30.929 0.0
2025-11-29-16:17:31.273 0.0
2025-11-29-16:17:31.550 0.0
2025-11-29-16:17:31.856 0.0
2025-11-29-16:17:32.096 0.0
2025-11-29-16:17:32.411 0.0
2025-11-29-16:17:32.695 0.0
2025-11-29-16:17:32.941 0.0
2025-11-29-16:17:33.181 0.0
2025-11-29-16:17:33.477 0.0
2025-11-29-16:17:33.878 0.0
2025-11-29-16:17:34.285 0.0
2025-11-29-16:17:34.708 0.0
2025-11-29-16:17:34.989 0.0
2025-11-29-16:17:35.474 0.0
2025-11-29-16:17:35.838 20.0
2025-11-29-16:17:36.138 0.0
2025-11-29-16:17:36.596 0.0
2025-11-29-16:17:37.087 0.0
2025-11-29-16:17:37.601 0.0
2025-11-29-16:17:38.152 0.0
2025-11-29-16:17:38.675 0.0
2025-11-29-16:17:39.166 0.0
2025-11-29-16:17:39.599 0.0
2025-11-29-16:17:39.935 0.0
2025-11-29-16:17:40.111 0.0
2025-11-29-16:17:40.326 0.0
2025-11-29-16:17:40.516 0.0
database/mission_result/1_222/通道4_区域1.csv
View file @
e8ce54c3
2025-
11-29-15:49:00.891 0.0
2025-
11-29-15:49:00.891 0.0
...
@@ -11,3 +11,71 @@
...
@@ -11,3 +11,71 @@
2025-11-29-15:49:07.323 0.0
2025-11-29-15:49:07.323 0.0
2025-11-29-15:49:07.844 0.0
2025-11-29-15:49:07.844 0.0
2025-11-29-15:49:08.416 0.0
2025-11-29-15:49:08.416 0.0
2025-11-29-16:16:59.614 0.0
2025-11-29-16:17:00.741 20.0
2025-11-29-16:17:01.434 0.0
2025-11-29-16:17:01.711 0.0
2025-11-29-16:17:01.974 0.0
2025-11-29-16:17:02.249 0.0
2025-11-29-16:17:02.487 0.0
2025-11-29-16:17:02.683 0.0
2025-11-29-16:17:02.871 0.0
2025-11-29-16:17:03.038 20.0
2025-11-29-16:17:03.197 0.0
2025-11-29-16:17:03.453 0.0
2025-11-29-16:17:03.642 0.0
2025-11-29-16:17:03.803 0.0
2025-11-29-16:17:04.008 0.0
2025-11-29-16:17:04.216 0.0
2025-11-29-16:17:04.361 0.0
2025-11-29-16:17:04.556 0.0
2025-11-29-16:17:04.756 0.0
2025-11-29-16:17:04.963 0.0
2025-11-29-16:17:05.169 0.0
2025-11-29-16:17:05.368 0.0
2025-11-29-16:17:26.350 0.0
2025-11-29-16:17:26.478 0.0
2025-11-29-16:17:26.664 0.0
2025-11-29-16:17:26.852 0.0
2025-11-29-16:17:27.169 0.0
2025-11-29-16:17:27.260 0.0
2025-11-29-16:17:27.453 0.0
2025-11-29-16:17:27.729 0.0
2025-11-29-16:17:27.921 20.0
2025-11-29-16:17:28.099 0.0
2025-11-29-16:17:28.323 0.0
2025-11-29-16:17:28.482 0.0
2025-11-29-16:17:28.678 0.0
2025-11-29-16:17:28.888 0.0
2025-11-29-16:17:29.116 0.0
2025-11-29-16:17:29.340 0.0
2025-11-29-16:17:29.494 0.0
2025-11-29-16:17:29.831 0.0
2025-11-29-16:17:29.935 0.0
2025-11-29-16:17:30.166 0.0
2025-11-29-16:17:30.408 0.0
2025-11-29-16:17:30.725 0.0
2025-11-29-16:17:30.929 0.0
2025-11-29-16:17:31.273 0.0
2025-11-29-16:17:31.549 0.0
2025-11-29-16:17:31.855 0.0
2025-11-29-16:17:32.096 0.0
2025-11-29-16:17:32.411 0.0
2025-11-29-16:17:32.691 0.0
2025-11-29-16:17:32.941 0.0
2025-11-29-16:17:33.180 0.0
2025-11-29-16:17:33.477 0.0
2025-11-29-16:17:33.877 0.0
2025-11-29-16:17:34.285 0.0
2025-11-29-16:17:34.707 0.0
2025-11-29-16:17:34.989 0.0
2025-11-29-16:17:35.474 20.0
2025-11-29-16:17:35.846 0.0
2025-11-29-16:17:36.138 0.0
2025-11-29-16:17:36.596 0.0
2025-11-29-16:17:37.087 0.0
2025-11-29-16:17:37.601 0.0
2025-11-29-16:17:38.152 0.0
2025-11-29-16:17:38.675 0.0
2025-11-29-16:17:39.166 0.0
2025-11-29-16:17:39.598 0.0
handlers/videopage/channelpanel_handler.py
View file @
e8ce54c3
...
@@ -877,19 +877,11 @@ class ChannelPanelHandler:
...
@@ -877,19 +877,11 @@ class ChannelPanelHandler:
if
panel
:
if
panel
:
panel
.
updateChannelStatus
(
channel_id
,
'connected'
)
panel
.
updateChannelStatus
(
channel_id
,
'connected'
)
panel
.
setConnected
(
True
)
panel
.
setConnected
(
True
)
pass
else
:
pass
# 兼容单通道场景
if
hasattr
(
self
,
'channelPanel'
):
self
.
channelPanel
.
updateChannelStatus
(
channel_id
,
'connected'
)
self
.
channelPanel
.
setConnected
(
True
)
self
.
statusBar
()
.
showMessage
(
self
.
statusBar
()
.
showMessage
(
self
.
tr
(
" 通道已连接: {} - 视频流已启动"
)
.
format
(
channel_id
)
self
.
tr
(
" 通道已连接: {} - 视频流已启动"
)
.
format
(
channel_id
)
)
)
except
Exception
as
e
:
except
Exception
as
e
:
pass
import
traceback
import
traceback
traceback
.
print_exc
()
traceback
.
print_exc
()
...
@@ -941,12 +933,6 @@ class ChannelPanelHandler:
...
@@ -941,12 +933,6 @@ class ChannelPanelHandler:
# 🔥 保留映射(不删除),以便任务同步时能找到面板
# 🔥 保留映射(不删除),以便任务同步时能找到面板
# del self._channel_panels_map[channel_id] # 注释掉,保留映射
# del self._channel_panels_map[channel_id] # 注释掉,保留映射
# 兼容单通道场景
if
hasattr
(
self
,
'channelPanel'
):
self
.
channelPanel
.
updateChannelStatus
(
channel_id
,
'disconnected'
)
self
.
channelPanel
.
setConnected
(
False
)
self
.
channelPanel
.
clearDisplay
()
self
.
statusBar
()
.
showMessage
(
self
.
tr
(
"⏹ 通道已断开: {}"
)
.
format
(
channel_id
))
self
.
statusBar
()
.
showMessage
(
self
.
tr
(
"⏹ 通道已断开: {}"
)
.
format
(
channel_id
))
def
onChannelManage
(
self
):
def
onChannelManage
(
self
):
...
...
handlers/videopage/curvepanel_handler.py
View file @
e8ce54c3
...
@@ -280,15 +280,18 @@ class CurvePanelHandler:
...
@@ -280,15 +280,18 @@ class CurvePanelHandler:
def
addChannelData
(
self
,
channel_id
,
channel_name
=
None
,
window_name
=
None
,
color
=
None
):
def
addChannelData
(
self
,
channel_id
,
channel_name
=
None
,
window_name
=
None
,
color
=
None
):
"""
"""
添加通道数据
管理
(业务逻辑)
添加通道数据(业务逻辑)
Args:
Args:
channel_id: 通道
唯一
ID
channel_id: 通道ID
channel_name: 通道名称
(可选)
channel_name: 通道名称
window_name:
检测窗口名称(可选)
window_name:
窗口名称
color: 曲线颜色
(可选)
color: 曲线颜色
"""
"""
print
(
f
"➕ [添加通道] channel_id={channel_id}, channel_name={channel_name}, window_name={window_name}"
)
if
channel_id
in
self
.
channel_data
:
if
channel_id
in
self
.
channel_data
:
print
(
f
" - 通道已存在,跳过添加"
)
return
return
# 默认名称
# 默认名称
...
@@ -311,7 +314,11 @@ class CurvePanelHandler:
...
@@ -311,7 +314,11 @@ class CurvePanelHandler:
# 通知UI创建通道
# 通知UI创建通道
if
self
.
curve_panel
:
if
self
.
curve_panel
:
print
(
f
" - 通知UI创建通道..."
)
self
.
curve_panel
.
addChannel
(
channel_id
,
channel_name
,
window_name
,
color
)
self
.
curve_panel
.
addChannel
(
channel_id
,
channel_name
,
window_name
,
color
)
print
(
f
" - UI通道创建完成"
)
else
:
print
(
f
" - ⚠️ curve_panel不存在!"
)
def
updateCurveData
(
self
,
channel_id
,
data_points
):
def
updateCurveData
(
self
,
channel_id
,
data_points
):
"""
"""
...
@@ -322,17 +329,21 @@ class CurvePanelHandler:
...
@@ -322,17 +329,21 @@ class CurvePanelHandler:
data_points: 数据点列表 [{'timestamp': float, 'height_mm': float}, ...]
data_points: 数据点列表 [{'timestamp': float, 'height_mm': float}, ...]
height_mm精度为0.1mm(保留1位小数)
height_mm精度为0.1mm(保留1位小数)
"""
"""
print
(
f
"📊 [更新曲线] channel_id={channel_id}, 数据点数量={len(data_points)}"
)
if
not
data_points
:
if
not
data_points
:
# print(f"⚠️ [曲线数据更新] 数据点为空,channel_id={channel_id}
")
print
(
f
" - ⚠️ 数据点为空,跳过更新
"
)
return
return
if
channel_id
not
in
self
.
channel_data
:
if
channel_id
not
in
self
.
channel_data
:
print
(
f
" - 通道不存在,先添加通道"
)
self
.
addChannelData
(
channel_id
)
self
.
addChannelData
(
channel_id
)
channel
=
self
.
channel_data
[
channel_id
]
channel
=
self
.
channel_data
[
channel_id
]
# 🔥 调试:记录更新前的数据点数
# 🔥 调试:记录更新前的数据点数
before_count
=
len
(
channel
[
'time'
])
before_count
=
len
(
channel
[
'time'
])
print
(
f
" - 更新前数据点数: {before_count}"
)
# 批量添加数据
# 批量添加数据
added_count
=
0
added_count
=
0
...
@@ -350,6 +361,8 @@ class CurvePanelHandler:
...
@@ -350,6 +361,8 @@ class CurvePanelHandler:
# 🔥 调试:记录添加后的数据点数
# 🔥 调试:记录添加后的数据点数
after_add_count
=
len
(
channel
[
'time'
])
after_add_count
=
len
(
channel
[
'time'
])
print
(
f
" - 实际添加数据点数: {added_count}"
)
print
(
f
" - 更新后数据点数: {after_add_count}"
)
# 🔥 限制数据点数量
# 🔥 限制数据点数量
# - 'realtime' 模式:限制为3000个点(滚动窗口)
# - 'realtime' 模式:限制为3000个点(滚动窗口)
...
@@ -361,6 +374,7 @@ class CurvePanelHandler:
...
@@ -361,6 +374,7 @@ class CurvePanelHandler:
before_limit
=
len
(
channel
[
'time'
])
before_limit
=
len
(
channel
[
'time'
])
channel
[
'time'
]
=
channel
[
'time'
][
-
self
.
max_points
:]
channel
[
'time'
]
=
channel
[
'time'
][
-
self
.
max_points
:]
channel
[
'value'
]
=
channel
[
'value'
][
-
self
.
max_points
:]
channel
[
'value'
]
=
channel
[
'value'
][
-
self
.
max_points
:]
print
(
f
" - 限制数据点: {before_limit} -> {len(channel['time'])}"
)
# 🔥 处理时间间隔断点:超过2分钟的数据点之间插入NaN断开连接
# 🔥 处理时间间隔断点:超过2分钟的数据点之间插入NaN断开连接
processed_time
,
processed_value
=
self
.
_processTimeGaps
(
processed_time
,
processed_value
=
self
.
_processTimeGaps
(
...
@@ -368,14 +382,17 @@ class CurvePanelHandler:
...
@@ -368,14 +382,17 @@ class CurvePanelHandler:
channel
[
'value'
],
channel
[
'value'
],
max_gap_seconds
=
120
# 2分钟 = 120秒
max_gap_seconds
=
120
# 2分钟 = 120秒
)
)
print
(
f
" - 处理后数据点数: {len(processed_time)}"
)
# 更新UI显示(只更新一次)
# 更新UI显示(只更新一次)
if
self
.
curve_panel
:
if
self
.
curve_panel
:
print
(
f
" - 开始更新UI显示..."
)
self
.
curve_panel
.
updateCurveDisplay
(
self
.
curve_panel
.
updateCurveDisplay
(
channel_id
,
channel_id
,
processed_time
,
processed_time
,
processed_value
processed_value
)
)
print
(
f
" - UI显示更新完成"
)
# 更新X轴范围
# 更新X轴范围
if
channel
[
'time'
]:
if
channel
[
'time'
]:
...
@@ -386,6 +403,8 @@ class CurvePanelHandler:
...
@@ -386,6 +403,8 @@ class CurvePanelHandler:
if
channel
[
'value'
]:
if
channel
[
'value'
]:
max_value
=
max
(
channel
[
'value'
])
max_value
=
max
(
channel
[
'value'
])
self
.
curve_panel
.
setYRangeAuto
(
max_value
)
self
.
curve_panel
.
setYRangeAuto
(
max_value
)
else
:
print
(
f
" - ⚠️ curve_panel不存在,无法更新UI!"
)
def
_processTimeGaps
(
self
,
time_data
,
value_data
,
max_gap_seconds
=
120
):
def
_processTimeGaps
(
self
,
time_data
,
value_data
,
max_gap_seconds
=
120
):
...
@@ -694,23 +713,23 @@ class CurvePanelHandler:
...
@@ -694,23 +713,23 @@ class CurvePanelHandler:
try
:
try
:
import
sys
import
sys
#
动态获取项目根目录
#
🔥 动态获取数据目录(与storage_thread保持一致)
if
getattr
(
sys
,
'frozen'
,
False
):
if
getattr
(
sys
,
'frozen'
,
False
):
# 打包后
的exe
# 打包后
:使用 sys._MEIPASS 指向 _internal 目录
project_root
=
os
.
path
.
dirname
(
sys
.
executable
)
data_root
=
sys
.
_MEIPASS
else
:
else
:
# 开发环境:基于配置模块获取
# 开发环境:基于配置模块获取
try
:
try
:
from
database.config
import
get_project_root
from
database.config
import
get_project_root
project
_root
=
get_project_root
()
data
_root
=
get_project_root
()
except
ImportError
:
except
ImportError
:
# 后备方案:当前工作目录
# 后备方案:当前工作目录
project
_root
=
os
.
getcwd
()
data
_root
=
os
.
getcwd
()
# 构建完整路径
# 构建完整路径
mission_folder_path
=
os
.
path
.
join
(
project
_root
,
'database'
,
'mission_result'
,
mission_name
)
mission_folder_path
=
os
.
path
.
join
(
data
_root
,
'database'
,
'mission_result'
,
mission_name
)
print
(
f
"🔍 [路径构建] 任务名称: {mission_name}"
)
print
(
f
"🔍 [路径构建] 任务名称: {mission_name}"
)
print
(
f
"🔍 [路径构建]
项目根目录: {project
_root}"
)
print
(
f
"🔍 [路径构建]
数据根目录: {data
_root}"
)
print
(
f
"🔍 [路径构建] 完整路径: {mission_folder_path}"
)
print
(
f
"🔍 [路径构建] 完整路径: {mission_folder_path}"
)
print
(
f
"🔍 [路径构建] 路径是否存在: {os.path.exists(mission_folder_path)}"
)
print
(
f
"🔍 [路径构建] 路径是否存在: {os.path.exists(mission_folder_path)}"
)
...
@@ -769,22 +788,22 @@ class CurvePanelHandler:
...
@@ -769,22 +788,22 @@ class CurvePanelHandler:
import
sys
import
sys
try
:
try
:
#
动态获取项目根目录
#
🔥 动态获取数据目录(与storage_thread保持一致)
if
getattr
(
sys
,
'frozen'
,
False
):
if
getattr
(
sys
,
'frozen'
,
False
):
# 打包后
的exe
# 打包后
:使用 sys._MEIPASS 指向 _internal 目录
project_root
=
os
.
path
.
dirname
(
sys
.
executable
)
data_root
=
sys
.
_MEIPASS
else
:
else
:
# 开发环境:基于配置模块获取
# 开发环境:基于配置模块获取
try
:
try
:
from
database.config
import
get_project_root
from
database.config
import
get_project_root
project
_root
=
get_project_root
()
data
_root
=
get_project_root
()
except
ImportError
:
except
ImportError
:
# 后备方案:当前工作目录
# 后备方案:当前工作目录
project
_root
=
os
.
getcwd
()
data
_root
=
os
.
getcwd
()
# 构建 mission_result 目录路径
# 构建 mission_result 目录路径
mission_result_dir
=
os
.
path
.
join
(
project
_root
,
'database'
,
'mission_result'
)
mission_result_dir
=
os
.
path
.
join
(
data
_root
,
'database'
,
'mission_result'
)
print
(
f
"🔍 [任务列表]
项目根目录: {project
_root}"
)
print
(
f
"🔍 [任务列表]
数据根目录: {data
_root}"
)
print
(
f
"🔍 [任务列表] 任务目录: {mission_result_dir}"
)
print
(
f
"🔍 [任务列表] 任务目录: {mission_result_dir}"
)
print
(
f
"🔍 [任务列表] 目录是否存在: {os.path.exists(mission_result_dir)}"
)
print
(
f
"🔍 [任务列表] 目录是否存在: {os.path.exists(mission_result_dir)}"
)
...
@@ -842,6 +861,7 @@ class CurvePanelHandler:
...
@@ -842,6 +861,7 @@ class CurvePanelHandler:
self
.
setCurveLoadMode
(
'history'
)
self
.
setCurveLoadMode
(
'history'
)
# 查找所有CSV文件
# 查找所有CSV文件
print
(
f
"
\n
🔍 [曲线加载] ==================== 开始加载 ===================="
)
print
(
f
"🔍 [曲线加载] 扫描目录: {data_directory}"
)
print
(
f
"🔍 [曲线加载] 扫描目录: {data_directory}"
)
print
(
f
"🔍 [曲线加载] 目录是否存在: {os.path.exists(data_directory)}"
)
print
(
f
"🔍 [曲线加载] 目录是否存在: {os.path.exists(data_directory)}"
)
...
@@ -849,7 +869,11 @@ class CurvePanelHandler:
...
@@ -849,7 +869,11 @@ class CurvePanelHandler:
print
(
f
"❌ [曲线加载] 目录不存在: {data_directory}"
)
print
(
f
"❌ [曲线加载] 目录不存在: {data_directory}"
)
return
False
return
False
csv_files
=
[
f
for
f
in
os
.
listdir
(
data_directory
)
if
f
.
endswith
(
'.csv'
)]
# 列出目录中的所有文件
all_files
=
os
.
listdir
(
data_directory
)
print
(
f
"🔍 [曲线加载] 目录中所有文件: {all_files}"
)
csv_files
=
[
f
for
f
in
all_files
if
f
.
endswith
(
'.csv'
)]
print
(
f
"🔍 [曲线加载] 找到 {len(csv_files)} 个CSV文件: {csv_files}"
)
print
(
f
"🔍 [曲线加载] 找到 {len(csv_files)} 个CSV文件: {csv_files}"
)
if
not
csv_files
:
if
not
csv_files
:
...
@@ -889,11 +913,13 @@ class CurvePanelHandler:
...
@@ -889,11 +913,13 @@ class CurvePanelHandler:
print
(
f
"✅ [进度条] 已显示进度对话框"
)
print
(
f
"✅ [进度条] 已显示进度对话框"
)
# 创建并启动后台加载线程
# 创建并启动后台加载线程
print
(
f
"🧵 [曲线加载] 创建后台加载线程..."
)
self
.
_load_thread
=
CurveDataLoadThread
(
self
.
_load_thread
=
CurveDataLoadThread
(
data_directory
=
data_directory
,
data_directory
=
data_directory
,
csv_files
=
csv_files
,
csv_files
=
csv_files
,
handler
=
self
handler
=
self
)
)
print
(
f
"🧵 [曲线加载] 后台线程已创建"
)
# 连接信号(使用Qt.QueuedConnection确保跨线程安全)
# 连接信号(使用Qt.QueuedConnection确保跨线程安全)
self
.
_load_thread
.
progress_updated
.
connect
(
self
.
_load_thread
.
progress_updated
.
connect
(
...
@@ -911,7 +937,10 @@ class CurvePanelHandler:
...
@@ -911,7 +937,10 @@ class CurvePanelHandler:
)
)
# 启动线程
# 启动线程
print
(
f
"🚀 [曲线加载] 启动后台线程..."
)
self
.
_load_thread
.
start
()
self
.
_load_thread
.
start
()
print
(
f
"✅ [曲线数据加载] 后台加载线程已启动"
)
print
(
f
"🔍 [曲线加载] ==================== 加载流程启动完成 ====================
\n
"
)
return
True
return
True
...
@@ -928,17 +957,28 @@ class CurvePanelHandler:
...
@@ -928,17 +957,28 @@ class CurvePanelHandler:
def
_onFileLoaded
(
self
,
channel_id
,
channel_name
,
window_name
,
color
,
data_points
):
def
_onFileLoaded
(
self
,
channel_id
,
channel_name
,
window_name
,
color
,
data_points
):
"""处理单个文件加载完成"""
"""处理单个文件加载完成"""
print
(
f
"📥 [文件加载] 收到文件数据:"
)
print
(
f
" - channel_id: {channel_id}"
)
print
(
f
" - channel_name: {channel_name}"
)
print
(
f
" - window_name: {window_name}"
)
print
(
f
" - 数据点数量: {len(data_points)}"
)
# 添加通道(如果不存在)
# 添加通道(如果不存在)
if
channel_id
not
in
self
.
channel_data
:
if
channel_id
not
in
self
.
channel_data
:
print
(
f
" - 添加新通道: {channel_id}"
)
self
.
addChannelData
(
self
.
addChannelData
(
channel_id
=
channel_id
,
channel_id
=
channel_id
,
channel_name
=
channel_name
,
channel_name
=
channel_name
,
window_name
=
window_name
,
window_name
=
window_name
,
color
=
color
color
=
color
)
)
else
:
print
(
f
" - 通道已存在: {channel_id}"
)
# 批量更新曲线数据
# 批量更新曲线数据
print
(
f
" - 开始更新曲线数据..."
)
self
.
updateCurveData
(
channel_id
,
data_points
)
self
.
updateCurveData
(
channel_id
,
data_points
)
print
(
f
" - 曲线数据更新完成"
)
def
_onLoadFinished
(
self
,
progress_dialog
,
success
,
count
):
def
_onLoadFinished
(
self
,
progress_dialog
,
success
,
count
):
"""处理加载完成"""
"""处理加载完成"""
...
...
handlers/videopage/missionpanel_handler.py
View file @
e8ce54c3
...
@@ -174,7 +174,6 @@ class MissionPanelHandler:
...
@@ -174,7 +174,6 @@ class MissionPanelHandler:
self
.
mission_panel
.
btn_debug
.
setEnabled
(
False
)
self
.
mission_panel
.
btn_debug
.
setEnabled
(
False
)
except
Exception
as
e
:
except
Exception
as
e
:
pass
import
traceback
import
traceback
traceback
.
print_exc
()
traceback
.
print_exc
()
# 出错时默认隐藏调试按钮,确保安全性
# 出错时默认隐藏调试按钮,确保安全性
...
@@ -467,8 +466,6 @@ class MissionPanelHandler:
...
@@ -467,8 +466,6 @@ class MissionPanelHandler:
# 🔥 第一步:同步到 channel_config.yaml(独立业务,无论通道是否打开都执行)
# 🔥 第一步:同步到 channel_config.yaml(独立业务,无论通道是否打开都执行)
sync_success
=
self
.
_syncTaskToConfigFile
(
channel_id
,
task_id
,
task_name
,
save_liquid_data_path
)
sync_success
=
self
.
_syncTaskToConfigFile
(
channel_id
,
task_id
,
task_name
,
save_liquid_data_path
)
pass
# 🔥 第二步:更新通道面板UI(可选操作,仅在通道已打开时执行)
# 🔥 第二步:更新通道面板UI(可选操作,仅在通道已打开时执行)
# 检查是否有通道面板映射(从ChannelPanelHandler获取)
# 检查是否有通道面板映射(从ChannelPanelHandler获取)
if
not
hasattr
(
self
,
'_channel_panels_map'
):
if
not
hasattr
(
self
,
'_channel_panels_map'
):
...
@@ -1377,10 +1374,9 @@ class MissionPanelHandler:
...
@@ -1377,10 +1374,9 @@ class MissionPanelHandler:
channel_id: 通道ID(如 'channel1')
channel_id: 通道ID(如 'channel1')
task_folder_name: 任务文件夹名称(如 '1_1')
task_folder_name: 任务文件夹名称(如 '1_1')
"""
"""
try
:
# 从 channel_id 提取通道编号
# 从 channel_id 提取通道编号
if
not
channel_id
.
startswith
(
'channel'
):
if
not
channel_id
.
startswith
(
'channel'
):
print
(
f
"❌ [_updateChannelMissionLabel] 无效的通道ID: {channel_id}"
)
return
return
channel_num
=
int
(
channel_id
.
replace
(
'channel'
,
''
))
channel_num
=
int
(
channel_id
.
replace
(
'channel'
,
''
))
...
@@ -1404,19 +1400,6 @@ class MissionPanelHandler:
...
@@ -1404,19 +1400,6 @@ class MissionPanelHandler:
if
panel
and
hasattr
(
panel
,
'_positionTaskLabel'
):
if
panel
and
hasattr
(
panel
,
'_positionTaskLabel'
):
panel
.
_positionTaskLabel
()
panel
.
_positionTaskLabel
()
print
(
f
"✅ [多任务] 已更新 {channel_id} 的任务标签: {task_folder_name}"
)
# 删除状态更新逻辑,双击不改变任务状态
else
:
print
(
f
"❌ [_updateChannelMissionLabel] 未找到变量: {mission_var_name}"
)
# 注意:不在这里调用 _setTaskRowChannelColor,而是在 _handleTaskSelected 中更新完所有通道后再调用
except
Exception
as
e
:
print
(
f
"❌ [_updateChannelMissionLabel] 更新通道任务标签失败 ({channel_id}): {e}"
)
import
traceback
traceback
.
print_exc
()
def
_isTaskInUse
(
self
,
task_folder_name
):
def
_isTaskInUse
(
self
,
task_folder_name
):
"""
"""
检查指定任务是否被任何通道使用
检查指定任务是否被任何通道使用
...
@@ -1427,7 +1410,6 @@ class MissionPanelHandler:
...
@@ -1427,7 +1410,6 @@ class MissionPanelHandler:
Returns:
Returns:
bool: 如果任务被使用返回True,否则返回False
bool: 如果任务被使用返回True,否则返回False
"""
"""
try
:
# 检查所有通道(channel1-channel4)
# 检查所有通道(channel1-channel4)
for
channel_num
in
range
(
1
,
5
):
for
channel_num
in
range
(
1
,
5
):
channel_id
=
f
'channel{channel_num}'
channel_id
=
f
'channel{channel_num}'
...
@@ -1450,23 +1432,14 @@ class MissionPanelHandler:
...
@@ -1450,23 +1432,14 @@ class MissionPanelHandler:
return
False
return
False
except
Exception
as
e
:
print
(
f
"❌ [状态检查] 检查任务使用状态失败: {e}"
)
return
False
def
_refreshAllTaskStatus
(
self
):
def
_refreshAllTaskStatus
(
self
):
"""
"""
刷新任务面板中所有任务的状态显示
刷新任务面板中所有任务的状态显示
委托给 MissionTextStatus 类处理
委托给 MissionTextStatus 类处理
"""
"""
try
:
if
self
.
mission_text_status
:
if
self
.
mission_text_status
:
self
.
mission_text_status
.
refreshAllTaskStatus
(
self
)
self
.
mission_text_status
.
refreshAllTaskStatus
(
self
)
except
Exception
as
e
:
print
(
f
"❌ [状态刷新] 刷新任务状态失败: {e}"
)
import
traceback
traceback
.
print_exc
()
def
_updateTaskStatus
(
self
,
task_folder_name
,
new_status
):
def
_updateTaskStatus
(
self
,
task_folder_name
,
new_status
):
"""
"""
...
@@ -1476,7 +1449,6 @@ class MissionPanelHandler:
...
@@ -1476,7 +1449,6 @@ class MissionPanelHandler:
task_folder_name: 任务文件夹名称(如 "21321_312312")
task_folder_name: 任务文件夹名称(如 "21321_312312")
new_status: 新状态(如 "已启动")
new_status: 新状态(如 "已启动")
"""
"""
try
:
if
not
hasattr
(
self
,
'mission_panel'
):
if
not
hasattr
(
self
,
'mission_panel'
):
return
return
...
@@ -1497,19 +1469,11 @@ class MissionPanelHandler:
...
@@ -1497,19 +1469,11 @@ class MissionPanelHandler:
if
status_item
:
if
status_item
:
old_status
=
status_item
.
text
()
old_status
=
status_item
.
text
()
status_item
.
setText
(
new_status
)
status_item
.
setText
(
new_status
)
print
(
f
"✅ [_updateTaskStatus] 任务 {task_folder_name} 状态已更新: {old_status} → {new_status}"
)
# 同时更新配置文件中的状态
# 同时更新配置文件中的状态
self
.
_updateTaskConfigStatus
(
task_id_item
.
text
(),
new_status
)
self
.
_updateTaskConfigStatus
(
task_id_item
.
text
(),
new_status
)
return
return
print
(
f
"⚠️ [_updateTaskStatus] 未找到任务: {task_folder_name}"
)
except
Exception
as
e
:
print
(
f
"❌ [_updateTaskStatus] 更新任务状态失败: {e}"
)
import
traceback
traceback
.
print_exc
()
# 🔥 已删除 _updateRowColor 和 _updateRowColorForQTableWidgetItem 方法
# 🔥 已删除 _updateRowColor 和 _updateRowColorForQTableWidgetItem 方法
# 所有文本颜色管理现在由 MissionTextStatus 类统一处理
# 所有文本颜色管理现在由 MissionTextStatus 类统一处理
...
@@ -1519,17 +1483,8 @@ class MissionPanelHandler:
...
@@ -1519,17 +1483,8 @@ class MissionPanelHandler:
委托给 MissionTextStatus 类处理所有文本颜色更新
委托给 MissionTextStatus 类处理所有文本颜色更新
"""
"""
print
(
f
"🎯 [_updateChannelColumnColor] 方法被调用"
)
try
:
if
self
.
mission_text_status
:
if
self
.
mission_text_status
:
print
(
f
" ✅ mission_text_status 存在,开始更新"
)
self
.
mission_text_status
.
updateAllChannelColumnColors
(
self
)
self
.
mission_text_status
.
updateAllChannelColumnColors
(
self
)
else
:
print
(
f
" ❌ mission_text_status 不存在!"
)
except
Exception
as
e
:
print
(
f
"❌ [状态列更新] 更新状态列失败: {e}"
)
import
traceback
traceback
.
print_exc
()
def
_updateTaskConfigStatus
(
self
,
task_id
,
new_status
):
def
_updateTaskConfigStatus
(
self
,
task_id
,
new_status
):
"""
"""
...
@@ -1539,7 +1494,6 @@ class MissionPanelHandler:
...
@@ -1539,7 +1494,6 @@ class MissionPanelHandler:
task_id: 任务编号
task_id: 任务编号
new_status: 新状态
new_status: 新状态
"""
"""
try
:
from
database.config
import
get_project_root
from
database.config
import
get_project_root
import
yaml
import
yaml
import
os
import
os
...
@@ -1562,23 +1516,14 @@ class MissionPanelHandler:
...
@@ -1562,23 +1516,14 @@ class MissionPanelHandler:
with
open
(
config_path
,
'w'
,
encoding
=
'utf-8'
)
as
f
:
with
open
(
config_path
,
'w'
,
encoding
=
'utf-8'
)
as
f
:
yaml
.
safe_dump
(
config_data
,
f
,
allow_unicode
=
True
,
default_flow_style
=
False
)
yaml
.
safe_dump
(
config_data
,
f
,
allow_unicode
=
True
,
default_flow_style
=
False
)
print
(
f
"✅ [_updateTaskConfigStatus] 已更新配置文件 {filename} 状态为: {new_status}"
)
return
return
print
(
f
"⚠️ [_updateTaskConfigStatus] 未找到任务 {task_id} 的配置文件"
)
except
Exception
as
e
:
print
(
f
"❌ [_updateTaskConfigStatus] 更新任务配置状态失败: {e}"
)
import
traceback
traceback
.
print_exc
()
def
_refreshCurveMissionList
(
self
):
def
_refreshCurveMissionList
(
self
):
"""
"""
刷新曲线面板的任务列表
刷新曲线面板的任务列表
从 mission_result 目录重新扫描任务文件夹并更新下拉框
从 mission_result 目录重新扫描任务文件夹并更新下拉框
"""
"""
try
:
# 如果有 curvePanelHandler,调用其 loadMissionFolders 方法
# 如果有 curvePanelHandler,调用其 loadMissionFolders 方法
if
hasattr
(
self
,
'curvePanelHandler'
)
and
self
.
curvePanelHandler
:
if
hasattr
(
self
,
'curvePanelHandler'
)
and
self
.
curvePanelHandler
:
self
.
curvePanelHandler
.
loadMissionFolders
()
self
.
curvePanelHandler
.
loadMissionFolders
()
...
@@ -1604,10 +1549,6 @@ class MissionPanelHandler:
...
@@ -1604,10 +1549,6 @@ class MissionPanelHandler:
# 更新下拉框
# 更新下拉框
self
.
curvePanel
.
updateMissionFolderList
(
mission_folders
)
self
.
curvePanel
.
updateMissionFolderList
(
mission_folders
)
except
Exception
as
e
:
print
(
f
"⚠️ [刷新曲线任务列表] 失败: {e}"
)
import
traceback
traceback
.
print_exc
()
class
MissionTextStatus
:
class
MissionTextStatus
:
...
@@ -1647,13 +1588,8 @@ class MissionTextStatus:
...
@@ -1647,13 +1588,8 @@ class MissionTextStatus:
"""
"""
1. 初始化所有任务行文本为灰色
1. 初始化所有任务行文本为灰色
"""
"""
try
:
for
row
in
range
(
self
.
table
.
rowCount
()):
for
row
in
range
(
self
.
table
.
rowCount
()):
self
.
_setRowColor
(
row
,
self
.
COLOR_GRAY
,
exclude_columns
=
[])
self
.
_setRowColor
(
row
,
self
.
COLOR_GRAY
,
exclude_columns
=
[])
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 初始化失败: {e}"
)
import
traceback
traceback
.
print_exc
()
def
setRowBlackOnSelect
(
self
,
row_index
):
def
setRowBlackOnSelect
(
self
,
row_index
):
"""
"""
...
@@ -1664,14 +1600,10 @@ class MissionTextStatus:
...
@@ -1664,14 +1600,10 @@ class MissionTextStatus:
Args:
Args:
row_index: 选中的行索引
row_index: 选中的行索引
"""
"""
try
:
# 🔥 不再恢复之前选中行的颜色,所有"已启动"的任务点击后都保持黑色
# 🔥 不再恢复之前选中行的颜色,所有"已启动"的任务点击后都保持黑色
# 将新选中的行置为黑色
# 将新选中的行置为黑色
self
.
_setRowColor
(
row_index
,
self
.
COLOR_BLACK
,
exclude_columns
=
[
2
])
# 排除状态列
self
.
_setRowColor
(
row_index
,
self
.
COLOR_BLACK
,
exclude_columns
=
[
2
])
# 排除状态列
self
.
selected_row
=
row_index
self
.
selected_row
=
row_index
except
Exception
as
e
:
import
traceback
traceback
.
print_exc
()
def
setStatusColumnGreenOnDetection
(
self
,
task_folder_name
):
def
setStatusColumnGreenOnDetection
(
self
,
task_folder_name
):
"""
"""
...
@@ -1680,7 +1612,7 @@ class MissionTextStatus:
...
@@ -1680,7 +1612,7 @@ class MissionTextStatus:
Args:
Args:
task_folder_name: 任务文件夹名称(如 "1_1")
task_folder_name: 任务文件夹名称(如 "1_1")
"""
"""
try
:
# 查找对应的任务行
# 查找对应的任务行
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
if
row_index
>=
0
:
if
row_index
>=
0
:
...
@@ -1688,12 +1620,7 @@ class MissionTextStatus:
...
@@ -1688,12 +1620,7 @@ class MissionTextStatus:
if
status_item
:
if
status_item
:
status_item
.
setText
(
"检测中"
)
status_item
.
setText
(
"检测中"
)
status_item
.
setForeground
(
self
.
COLOR_GREEN
)
status_item
.
setForeground
(
self
.
COLOR_GREEN
)
else
:
print
(
f
"⚠️ [文本状态] 未找到任务 {task_folder_name}"
)
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 设置检测状态颜色失败: {e}"
)
import
traceback
traceback
.
print_exc
()
def
resetStatusColumnOnStopDetection
(
self
,
task_folder_name
):
def
resetStatusColumnOnStopDetection
(
self
,
task_folder_name
):
"""
"""
...
@@ -1702,7 +1629,6 @@ class MissionTextStatus:
...
@@ -1702,7 +1629,6 @@ class MissionTextStatus:
Args:
Args:
task_folder_name: 任务文件夹名称(如 "1_1")
task_folder_name: 任务文件夹名称(如 "1_1")
"""
"""
try
:
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
if
row_index
>=
0
:
if
row_index
>=
0
:
status_item
=
self
.
table
.
item
(
row_index
,
2
)
status_item
=
self
.
table
.
item
(
row_index
,
2
)
...
@@ -1713,9 +1639,6 @@ class MissionTextStatus:
...
@@ -1713,9 +1639,6 @@ class MissionTextStatus:
status_item
.
setForeground
(
self
.
COLOR_BLACK
)
status_item
.
setForeground
(
self
.
COLOR_BLACK
)
else
:
else
:
status_item
.
setForeground
(
self
.
COLOR_GRAY
)
status_item
.
setForeground
(
self
.
COLOR_GRAY
)
except
Exception
as
e
:
import
traceback
traceback
.
print_exc
()
def
setStatusColumnBlackOnStarted
(
self
,
task_folder_name
):
def
setStatusColumnBlackOnStarted
(
self
,
task_folder_name
):
"""
"""
...
@@ -1726,18 +1649,12 @@ class MissionTextStatus:
...
@@ -1726,18 +1649,12 @@ class MissionTextStatus:
Args:
Args:
task_folder_name: 任务文件夹名称(如 "1_1")
task_folder_name: 任务文件夹名称(如 "1_1")
"""
"""
try
:
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
if
row_index
>=
0
:
if
row_index
>=
0
:
status_item
=
self
.
table
.
item
(
row_index
,
2
)
status_item
=
self
.
table
.
item
(
row_index
,
2
)
if
status_item
:
if
status_item
:
status_item
.
setText
(
"已启动"
)
status_item
.
setText
(
"已启动"
)
status_item
.
setForeground
(
self
.
COLOR_BLACK
)
status_item
.
setForeground
(
self
.
COLOR_BLACK
)
print
(
f
"✅ [文本状态] 任务 {task_folder_name} 状态列已切换为黑色(已启动)"
)
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 设置状态列为已启动失败: {e}"
)
import
traceback
traceback
.
print_exc
()
def
setChannelColumnGreenOnDetection
(
self
,
task_folder_name
,
channel_num
):
def
setChannelColumnGreenOnDetection
(
self
,
task_folder_name
,
channel_num
):
"""
"""
...
@@ -1747,7 +1664,6 @@ class MissionTextStatus:
...
@@ -1747,7 +1664,6 @@ class MissionTextStatus:
task_folder_name: 任务文件夹名称(如 "1_1")
task_folder_name: 任务文件夹名称(如 "1_1")
channel_num: 通道编号(1-4)
channel_num: 通道编号(1-4)
"""
"""
try
:
# 查找对应的任务行
# 查找对应的任务行
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
if
row_index
>=
0
:
if
row_index
>=
0
:
...
@@ -1757,13 +1673,6 @@ class MissionTextStatus:
...
@@ -1757,13 +1673,6 @@ class MissionTextStatus:
channel_item
=
self
.
table
.
item
(
row_index
,
col_index
)
channel_item
=
self
.
table
.
item
(
row_index
,
col_index
)
if
channel_item
:
if
channel_item
:
channel_item
.
setForeground
(
self
.
COLOR_GREEN
)
channel_item
.
setForeground
(
self
.
COLOR_GREEN
)
print
(
f
"✅ [文本状态] 任务 {task_folder_name} 通道{channel_num}列已置为绿色(检测中)"
)
else
:
print
(
f
"⚠️ [文本状态] 未找到任务 {task_folder_name}"
)
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 设置通道列检测状态颜色失败: {e}"
)
import
traceback
traceback
.
print_exc
()
def
resetChannelColumnOnStopDetection
(
self
,
task_folder_name
,
channel_num
):
def
resetChannelColumnOnStopDetection
(
self
,
task_folder_name
,
channel_num
):
"""
"""
...
@@ -1773,7 +1682,6 @@ class MissionTextStatus:
...
@@ -1773,7 +1682,6 @@ class MissionTextStatus:
task_folder_name: 任务文件夹名称(如 "1_1")
task_folder_name: 任务文件夹名称(如 "1_1")
channel_num: 通道编号(1-4)
channel_num: 通道编号(1-4)
"""
"""
try
:
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
row_index
=
self
.
_findTaskRow
(
task_folder_name
)
if
row_index
>=
0
:
if
row_index
>=
0
:
col_index
=
3
+
(
channel_num
-
1
)
col_index
=
3
+
(
channel_num
-
1
)
...
@@ -1784,11 +1692,6 @@ class MissionTextStatus:
...
@@ -1784,11 +1692,6 @@ class MissionTextStatus:
channel_item
.
setForeground
(
self
.
COLOR_BLACK
)
channel_item
.
setForeground
(
self
.
COLOR_BLACK
)
else
:
else
:
channel_item
.
setForeground
(
self
.
COLOR_GRAY
)
channel_item
.
setForeground
(
self
.
COLOR_GRAY
)
print
(
f
"✅ [文本状态] 任务 {task_folder_name} 通道{channel_num}列已恢复"
)
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 恢复通道列颜色失败: {e}"
)
import
traceback
traceback
.
print_exc
()
def
updateAllChannelColumnColors
(
self
,
main_window
):
def
updateAllChannelColumnColors
(
self
,
main_window
):
"""
"""
...
@@ -1802,8 +1705,6 @@ class MissionTextStatus:
...
@@ -1802,8 +1705,6 @@ class MissionTextStatus:
Args:
Args:
main_window: 主窗口实例,用于访问通道任务标签和检测状态
main_window: 主窗口实例,用于访问通道任务标签和检测状态
"""
"""
try
:
print
(
f
"🔍 [文本状态] 开始更新通道列颜色"
)
# 🔥 第一步:收集所有通道当前正在执行的任务
# 🔥 第一步:收集所有通道当前正在执行的任务
active_tasks
=
set
()
# 存储正在执行的任务名称
active_tasks
=
set
()
# 存储正在执行的任务名称
channel_task_map
=
{}
# 通道 -> 任务映射
channel_task_map
=
{}
# 通道 -> 任务映射
...
@@ -1819,7 +1720,6 @@ class MissionTextStatus:
...
@@ -1819,7 +1720,6 @@ class MissionTextStatus:
if
current_task
and
current_task
!=
"未分配任务"
:
if
current_task
and
current_task
!=
"未分配任务"
:
active_tasks
.
add
(
current_task
)
active_tasks
.
add
(
current_task
)
channel_task_map
[
channel_id
]
=
current_task
channel_task_map
[
channel_id
]
=
current_task
print
(
f
" 📌 {channel_id}: 任务={current_task}"
)
# 🔥 第二步:遍历所有任务行,更新通道列颜色
# 🔥 第二步:遍历所有任务行,更新通道列颜色
for
row
in
range
(
self
.
table
.
rowCount
()):
for
row
in
range
(
self
.
table
.
rowCount
()):
...
@@ -1852,7 +1752,6 @@ class MissionTextStatus:
...
@@ -1852,7 +1752,6 @@ class MissionTextStatus:
detect_var_name
=
f
'{channel_id}detect'
detect_var_name
=
f
'{channel_id}detect'
if
hasattr
(
main_window
,
detect_var_name
):
if
hasattr
(
main_window
,
detect_var_name
):
is_detecting
=
getattr
(
main_window
,
detect_var_name
)
is_detecting
=
getattr
(
main_window
,
detect_var_name
)
print
(
f
" 🔸 任务{task_folder_name} 通道{channel_num}: 检测状态={is_detecting}"
)
if
is_detecting
:
if
is_detecting
:
# 🔥 设置对应通道列为绿色
# 🔥 设置对应通道列为绿色
self
.
setChannelColumnGreenOnDetection
(
task_folder_name
,
channel_num
)
self
.
setChannelColumnGreenOnDetection
(
task_folder_name
,
channel_num
)
...
@@ -1889,20 +1788,12 @@ class MissionTextStatus:
...
@@ -1889,20 +1788,12 @@ class MissionTextStatus:
if
assigned_channels_count
>
0
and
detecting_channels_count
==
assigned_channels_count
:
if
assigned_channels_count
>
0
and
detecting_channels_count
==
assigned_channels_count
:
# 所有分配的通道都在检测中 -> 绿色"检测中"
# 所有分配的通道都在检测中 -> 绿色"检测中"
self
.
setStatusColumnGreenOnDetection
(
task_folder_name
)
self
.
setStatusColumnGreenOnDetection
(
task_folder_name
)
print
(
f
" ✅ 任务{task_folder_name}: {detecting_channels_count}/{assigned_channels_count}通道检测中 -> 绿色"
)
elif
detecting_channels_count
==
0
:
elif
detecting_channels_count
==
0
:
# 所有通道都未检测,但任务已分配 -> 黑色"已启动"
# 所有通道都未检测,但任务已分配 -> 黑色"已启动"
self
.
setStatusColumnBlackOnStarted
(
task_folder_name
)
self
.
setStatusColumnBlackOnStarted
(
task_folder_name
)
print
(
f
" ✅ 任务{task_folder_name}: 0/{assigned_channels_count}通道检测中 -> 黑色已启动"
)
else
:
else
:
# 部分通道在检测 -> 黑色"已启动"(不是所有通道都在检测)
# 部分通道在检测 -> 黑色"已启动"(不是所有通道都在检测)
self
.
setStatusColumnBlackOnStarted
(
task_folder_name
)
self
.
setStatusColumnBlackOnStarted
(
task_folder_name
)
print
(
f
" ⚠️ 任务{task_folder_name}: {detecting_channels_count}/{assigned_channels_count}通道检测中 -> 黑色已启动"
)
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 更新通道列和状态列失败: {e}"
)
import
traceback
traceback
.
print_exc
()
def
initializeNewTaskRowGray
(
self
,
row_index
):
def
initializeNewTaskRowGray
(
self
,
row_index
):
"""
"""
...
@@ -1913,9 +1804,7 @@ class MissionTextStatus:
...
@@ -1913,9 +1804,7 @@ class MissionTextStatus:
"""
"""
try
:
try
:
self
.
_setRowColor
(
row_index
,
self
.
COLOR_GRAY
,
exclude_columns
=
[])
self
.
_setRowColor
(
row_index
,
self
.
COLOR_GRAY
,
exclude_columns
=
[])
print
(
f
"✅ [文本状态] 新建任务行 {row_index} 已初始化为灰色"
)
except
Exception
as
e
:
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 初始化新任务行颜色失败: {e}"
)
import
traceback
import
traceback
traceback
.
print_exc
()
traceback
.
print_exc
()
...
@@ -1952,7 +1841,6 @@ class MissionTextStatus:
...
@@ -1952,7 +1841,6 @@ class MissionTextStatus:
current_status
=
status_item
.
text
()
current_status
=
status_item
.
text
()
if
current_status
!=
new_status
:
if
current_status
!=
new_status
:
status_item
.
setText
(
new_status
)
status_item
.
setText
(
new_status
)
print
(
f
"🔄 [状态刷新] 任务 {task_folder_name}: {current_status} → {new_status}"
)
# 🔥 更新文本颜色
# 🔥 更新文本颜色
if
new_status
==
"未启动"
:
if
new_status
==
"未启动"
:
...
@@ -1967,7 +1855,6 @@ class MissionTextStatus:
...
@@ -1967,7 +1855,6 @@ class MissionTextStatus:
pass
pass
except
Exception
as
e
:
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 刷新任务状态失败: {e}"
)
import
traceback
import
traceback
traceback
.
print_exc
()
traceback
.
print_exc
()
...
@@ -1995,7 +1882,8 @@ class MissionTextStatus:
...
@@ -1995,7 +1882,8 @@ class MissionTextStatus:
return
False
return
False
except
Exception
as
e
:
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 检查任务使用状态失败: {e}"
)
import
traceback
traceback
.
print_exc
()
return
False
return
False
def
_setRowColor
(
self
,
row_index
,
color
,
exclude_columns
=
None
):
def
_setRowColor
(
self
,
row_index
,
color
,
exclude_columns
=
None
):
...
@@ -2025,7 +1913,6 @@ class MissionTextStatus:
...
@@ -2025,7 +1913,6 @@ class MissionTextStatus:
if
item
:
if
item
:
item
.
setForeground
(
color
)
item
.
setForeground
(
color
)
except
Exception
as
e
:
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 设置行颜色失败: {e}"
)
import
traceback
import
traceback
traceback
.
print_exc
()
traceback
.
print_exc
()
...
@@ -2050,5 +1937,6 @@ class MissionTextStatus:
...
@@ -2050,5 +1937,6 @@ class MissionTextStatus:
return
row
return
row
return
-
1
return
-
1
except
Exception
as
e
:
except
Exception
as
e
:
print
(
f
"❌ [文本状态] 查找任务行失败: {e}"
)
import
traceback
traceback
.
print_exc
()
return
-
1
return
-
1
\ No newline at end of file
handlers/videopage/thread_manager/threads/storage_thread.py
View file @
e8ce54c3
...
@@ -34,7 +34,14 @@ class StorageThread:
...
@@ -34,7 +34,14 @@ class StorageThread:
Returns:
Returns:
str: 项目根目录的绝对路径
str: 项目根目录的绝对路径
"""
"""
# 当前文件是 handlers/videopage/thread_manager/threads/storage_thread.py
import
sys
# 🔥 打包后:使用 sys._MEIPASS 指向 _internal 目录
if
getattr
(
sys
,
'frozen'
,
False
):
# 打包环境:返回 _internal 目录
return
sys
.
_MEIPASS
else
:
# 开发环境:当前文件是 handlers/videopage/thread_manager/threads/storage_thread.py
# 需要向上5级到达项目根目录
# 需要向上5级到达项目根目录
current_file
=
os
.
path
.
abspath
(
__file__
)
current_file
=
os
.
path
.
abspath
(
__file__
)
project_root
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
current_file
)))))
project_root
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
current_file
)))))
...
...
handlers/view_handler.py
View file @
e8ce54c3
...
@@ -30,7 +30,7 @@ class ViewHandler:
...
@@ -30,7 +30,7 @@ class ViewHandler:
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
"""初始化视图处理器"""
"""初始化视图处理器"""
super
()
.
__init__
(
*
args
,
**
kwargs
)
super
()
.
__init__
(
*
args
,
**
kwargs
)
# 曲线分析模式状态(False=
实时检测模式, True=曲线分析模式
)
# 曲线分析模式状态(False=
默认布局, True=曲线模式布局
)
self
.
_is_curve_mode_active
=
False
self
.
_is_curve_mode_active
=
False
@property
@property
...
@@ -60,17 +60,24 @@ class ViewHandler:
...
@@ -60,17 +60,24 @@ class ViewHandler:
import
os
import
os
import
sys
import
sys
#
动态获取项目根目录
#
🔥 动态获取数据目录(与storage_thread和curvepanel_handler保持一致)
if
getattr
(
sys
,
'frozen'
,
False
):
if
getattr
(
sys
,
'frozen'
,
False
):
project_root
=
os
.
path
.
dirname
(
sys
.
executable
)
# 打包后:使用 sys._MEIPASS 指向 _internal 目录
data_root
=
sys
.
_MEIPASS
else
:
else
:
try
:
try
:
from
database.config
import
get_project_root
from
database.config
import
get_project_root
project
_root
=
get_project_root
()
data
_root
=
get_project_root
()
except
ImportError
:
except
ImportError
:
project_root
=
os
.
getcwd
()
data_root
=
os
.
getcwd
()
mission_path
=
os
.
path
.
join
(
data_root
,
'database'
,
'mission_result'
,
mission_name
)
print
(
f
"🔍 [_getCurveMissionPath] 任务名称: {mission_name}"
)
print
(
f
"🔍 [_getCurveMissionPath] 数据根目录: {data_root}"
)
print
(
f
"🔍 [_getCurveMissionPath] 完整路径: {mission_path}"
)
print
(
f
"🔍 [_getCurveMissionPath] 路径是否存在: {os.path.exists(mission_path)}"
)
mission_path
=
os
.
path
.
join
(
project_root
,
'database'
,
'mission_result'
,
mission_name
)
return
mission_path
if
os
.
path
.
exists
(
mission_path
)
else
None
return
mission_path
if
os
.
path
.
exists
(
mission_path
)
else
None
def
toggleToolBar
(
self
):
def
toggleToolBar
(
self
):
...
@@ -208,6 +215,9 @@ class ViewHandler:
...
@@ -208,6 +215,9 @@ class ViewHandler:
def
_switchToCurveLayout
(
self
):
def
_switchToCurveLayout
(
self
):
"""切换到曲线模式:根据检测线程状态选择合适的子布局"""
"""切换到曲线模式:根据检测线程状态选择合适的子布局"""
# 🔥 先设置模式为曲线模式(_video_layout_mode = 1),确保后续逻辑能正确判断
self
.
_video_layout_mode
=
1
# 🔥 检查检测线程状态,决定使用哪种子布局
# 🔥 检查检测线程状态,决定使用哪种子布局
detection_running
=
self
.
_getCurrentDetectionState
()
detection_running
=
self
.
_getCurrentDetectionState
()
...
@@ -216,20 +226,20 @@ class ViewHandler:
...
@@ -216,20 +226,20 @@ class ViewHandler:
# 🔥 根据检测线程状态选择通道容器
# 🔥 根据检测线程状态选择通道容器
if
detection_running
:
if
detection_running
:
#
实时检测模式
:使用通道面板容器(ChannelPanel)
#
同步布局
:使用通道面板容器(ChannelPanel)
target_channel_widgets
=
self
.
channel_widgets_for_curve
target_channel_widgets
=
self
.
channel_widgets_for_curve
layout_description
=
"
实时检测模式
"
layout_description
=
"
同步布局
"
else
:
else
:
# 历史回放
模式
:使用历史视频面板容器(HistoryVideoPanel)
# 历史回放
布局
:使用历史视频面板容器(HistoryVideoPanel)
target_channel_widgets
=
self
.
history_channel_widgets_for_curve
target_channel_widgets
=
self
.
history_channel_widgets_for_curve
layout_description
=
"历史回放
模式
"
layout_description
=
"历史回放
布局
"
# 🔥 根据检测线程状态选择要显示的面板类型
# 🔥 根据检测线程状态选择要显示的面板类型
if
detection_running
:
if
detection_running
:
#
实时检测模式
:使用通道面板(ChannelPanel)
#
同步布局
:使用通道面板(ChannelPanel)
panels_to_use
=
self
.
channelPanels
panels_to_use
=
self
.
channelPanels
else
:
else
:
# 历史回放
模式
:使用历史视频面板(HistoryVideoPanel)
# 历史回放
布局
:使用历史视频面板(HistoryVideoPanel)
if
hasattr
(
self
,
'historyVideoPanels'
):
if
hasattr
(
self
,
'historyVideoPanels'
):
panels_to_use
=
self
.
historyVideoPanels
panels_to_use
=
self
.
historyVideoPanels
else
:
else
:
...
@@ -271,10 +281,7 @@ class ViewHandler:
...
@@ -271,10 +281,7 @@ class ViewHandler:
wrapper
.
updateGeometry
()
wrapper
.
updateGeometry
()
panel
.
updateGeometry
()
panel
.
updateGeometry
()
# 先设置模式为曲线模式(_video_layout_mode = 1)
# 切换到曲线模式主布局(_video_layout_mode已在方法开头设置为1)
self
.
_video_layout_mode
=
1
# 切换到曲线模式主布局
self
.
videoLayoutStack
.
setCurrentIndex
(
1
)
self
.
videoLayoutStack
.
setCurrentIndex
(
1
)
# 更新状态栏信息
# 更新状态栏信息
...
@@ -293,7 +300,7 @@ class ViewHandler:
...
@@ -293,7 +300,7 @@ class ViewHandler:
# 🔥 根据检测线程状态更新通道显示
# 🔥 根据检测线程状态更新通道显示
if
detection_running
:
if
detection_running
:
#
实时检测模式
:根据当前选择的任务更新通道显示
#
同步布局
:根据当前选择的任务更新通道显示
if
hasattr
(
self
,
'curvemission'
):
if
hasattr
(
self
,
'curvemission'
):
current_mission
=
self
.
curvemission
.
currentText
()
current_mission
=
self
.
curvemission
.
currentText
()
if
current_mission
and
current_mission
!=
"请选择任务"
:
if
current_mission
and
current_mission
!=
"请选择任务"
:
...
@@ -306,7 +313,7 @@ class ViewHandler:
...
@@ -306,7 +313,7 @@ class ViewHandler:
if
hasattr
(
self
,
'_updateCurveChannelDisplay'
):
if
hasattr
(
self
,
'_updateCurveChannelDisplay'
):
self
.
_updateCurveChannelDisplay
([])
self
.
_updateCurveChannelDisplay
([])
else
:
else
:
# 🔥 历史回放
模式
:显示所有历史视频面板
# 🔥 历史回放
布局
:显示所有历史视频面板
if
hasattr
(
self
,
'_updateCurveChannelDisplay'
):
if
hasattr
(
self
,
'_updateCurveChannelDisplay'
):
all_channels
=
[
'通道1'
,
'通道2'
,
'通道3'
,
'通道4'
]
all_channels
=
[
'通道1'
,
'通道2'
,
'通道3'
,
'通道4'
]
self
.
_updateCurveChannelDisplay
(
all_channels
)
# 显示所有4个历史视频面板
self
.
_updateCurveChannelDisplay
(
all_channels
)
# 显示所有4个历史视频面板
...
@@ -322,7 +329,7 @@ class ViewHandler:
...
@@ -322,7 +329,7 @@ class ViewHandler:
QtCore
.
QTimer
.
singleShot
(
100
,
self
.
_loadCurveDataOrStartThreads
)
QtCore
.
QTimer
.
singleShot
(
100
,
self
.
_loadCurveDataOrStartThreads
)
def
_switchToDefaultLayout
(
self
):
def
_switchToDefaultLayout
(
self
):
"""切换到默认布局(
实时检测模式
)"""
"""切换到默认布局(
任务表格 + 2x2通道面板
)"""
# 🔥 停止所有曲线线程(切换回默认布局时)
# 🔥 停止所有曲线线程(切换回默认布局时)
self
.
_stopAllCurveThreads
()
self
.
_stopAllCurveThreads
()
...
@@ -389,16 +396,16 @@ class ViewHandler:
...
@@ -389,16 +396,16 @@ class ViewHandler:
return
return
if
detection_running
:
if
detection_running
:
# 切换到
实时检测布局(
索引0)
# 切换到
同步布局(曲线模式布局的
索引0)
target_index
=
0
target_index
=
0
layout_name
=
"
实时检测
布局"
layout_name
=
"
同步
布局"
mode_text
=
"
实时检测
"
mode_text
=
"
同步
"
mode_style
=
"font-weight: bold; padding: 2px 8px;"
mode_style
=
"font-weight: bold; padding: 2px 8px;"
curve_mode
=
'realtime'
curve_mode
=
'realtime'
print
(
f
"✅ [布局切换] 选择索引0 -
实时检测
布局"
)
print
(
f
"✅ [布局切换] 选择索引0 -
同步
布局"
)
else
:
else
:
# 切换到历史回放布局(索引1)
# 切换到历史回放布局(
曲线模式布局的
索引1)
target_index
=
1
target_index
=
1
layout_name
=
"历史回放布局"
layout_name
=
"历史回放布局"
mode_text
=
"历史回放"
mode_text
=
"历史回放"
...
@@ -425,18 +432,31 @@ class ViewHandler:
...
@@ -425,18 +432,31 @@ class ViewHandler:
pass
pass
# 🔥 禁用/启用通道面板的查看曲线按钮
# 🔥 禁用/启用通道面板的查看曲线按钮
# 索引0(实时检测模式)时禁用,索引1(历史回放模式)时启用
# 只有在曲线模式(_video_layout_mode==1)的子布局切换时才需要处理
# 子布局索引0(实时检测模式)时禁用,索引1(历史回放模式)时根据任务状态决定
if
hasattr
(
self
,
'_video_layout_mode'
)
and
self
.
_video_layout_mode
==
1
:
if
hasattr
(
self
,
'channelPanels'
):
if
hasattr
(
self
,
'channelPanels'
):
for
panel
in
self
.
channelPanels
:
for
panel
in
self
.
channelPanels
:
if
hasattr
(
panel
,
'btnCurve'
):
if
hasattr
(
panel
,
'btnCurve'
):
if
target_index
==
0
:
if
target_index
==
0
:
# 实时检测模式
:禁用查看曲线按钮
# 曲线模式的同步布局
:禁用查看曲线按钮
panel
.
btnCurve
.
setEnabled
(
False
)
panel
.
btnCurve
.
setEnabled
(
False
)
panel
.
btnCurve
.
setToolTip
(
"实时检测模式
下无法查看曲线"
)
panel
.
btnCurve
.
setToolTip
(
"同步布局
下无法查看曲线"
)
else
:
else
:
# 历史回放模式:启用查看曲线按钮
# 曲线模式的历史回放布局:检查通道是否有任务
has_task
=
False
if
hasattr
(
panel
,
'getTaskInfo'
):
task_info
=
panel
.
getTaskInfo
()
has_task
=
(
task_info
is
not
None
and
task_info
!=
"未分配任务"
)
if
has_task
:
# 有任务:启用查看曲线按钮
panel
.
btnCurve
.
setEnabled
(
True
)
panel
.
btnCurve
.
setEnabled
(
True
)
panel
.
btnCurve
.
setToolTip
(
"查看曲线"
)
panel
.
btnCurve
.
setToolTip
(
"查看曲线"
)
else
:
# 无任务:保持禁用
panel
.
btnCurve
.
setEnabled
(
False
)
panel
.
btnCurve
.
setToolTip
(
"请先分配任务"
)
# 执行布局切换
# 执行布局切换
current_index
=
self
.
curveLayoutStack
.
currentIndex
()
current_index
=
self
.
curveLayoutStack
.
currentIndex
()
...
...
rules/软件功能逻辑设计.md
View file @
e8ce54c3
1曲线模式
索引0布局,只显示根据curvemission筛选使用的通道面板失效了
1曲线模式
索引0布局,只显示根据curvemission筛选使用的通道面板失效了
...
@@ -67,3 +67,11 @@ class ModelLoadingProgressDialog(QDialog):
...
@@ -67,3 +67,11 @@ class ModelLoadingProgressDialog(QDialog):
-
**容器底部**
: foam掩码的最低点
-
**容器底部**
: foam掩码的最低点
-
**容器顶部**
: air掩码的最高点
-
**容器顶部**
: air掩码的最高点
-
**适用场景**
: 同时检测到泡沫和空气,未检测到液体
-
**适用场景**
: 同时检测到泡沫和空气,未检测到液体
通道面板的查看曲线按钮禁用逻辑,任务面板的查看曲线按钮一直启用
1channelmission为未分配任务时,包括曲线按钮在内所有通道面板按钮禁用。
2切换到曲线模式布局的索引0实时检测模式时,只禁用通道面板的查看曲线按钮
PAGE_VIDEO 实时检测界面名称管理
1.
PAGE_VIDEO 实时检测管理页面页面名称,self._video_layout_mode = 0 任务表格 + 2x2通道面板(PAGE_VIDEO 的索引0)称为默认布局,self._video_layout_mode = 1垂直通道面板 + 曲线面板(PAGE_VIDEO 的索引1)为曲线模式布局
2.
曲线模式布局子布局(self._video_layout_mode = 1的索引0)称为同步布局,曲线模式布局子布局(self._video_layout_mode = 1的索引1)为历史回放布局
\ No newline at end of file
widgets/videopage/channelpanel.py
View file @
e8ce54c3
...
@@ -482,11 +482,12 @@ class ChannelPanel(QtWidgets.QWidget):
...
@@ -482,11 +482,12 @@ class ChannelPanel(QtWidgets.QWidget):
self
.
_is_disabled
=
disabled
self
.
_is_disabled
=
disabled
if
disabled
:
if
disabled
:
# 禁用所有按钮
# 禁用所有按钮
(包括查看曲线按钮)
if
hasattr
(
self
,
'btnToggleConnect'
):
if
hasattr
(
self
,
'btnToggleConnect'
):
self
.
btnToggleConnect
.
setEnabled
(
False
)
self
.
btnToggleConnect
.
setEnabled
(
False
)
if
hasattr
(
self
,
'btnCurve'
):
if
hasattr
(
self
,
'btnCurve'
):
self
.
btnCurve
.
setEnabled
(
False
)
self
.
btnCurve
.
setEnabled
(
False
)
self
.
btnCurve
.
setToolTip
(
"请先分配任务"
)
if
hasattr
(
self
,
'btnAmplify'
):
if
hasattr
(
self
,
'btnAmplify'
):
self
.
btnAmplify
.
setEnabled
(
False
)
self
.
btnAmplify
.
setEnabled
(
False
)
if
hasattr
(
self
,
'btnEdit'
):
if
hasattr
(
self
,
'btnEdit'
):
...
@@ -499,11 +500,34 @@ class ChannelPanel(QtWidgets.QWidget):
...
@@ -499,11 +500,34 @@ class ChannelPanel(QtWidgets.QWidget):
}
}
"""
)
"""
)
else
:
else
:
# 启用
所有
按钮
# 启用按钮
if
hasattr
(
self
,
'btnToggleConnect'
):
if
hasattr
(
self
,
'btnToggleConnect'
):
self
.
btnToggleConnect
.
setEnabled
(
True
)
self
.
btnToggleConnect
.
setEnabled
(
True
)
# 🔥 查看曲线按钮:有任务时启用,但需要检查是否在曲线模式的实时检测子布局
# 只有在曲线模式(_video_layout_mode==1)且子布局索引0(实时检测)时才禁用
if
hasattr
(
self
,
'btnCurve'
):
if
hasattr
(
self
,
'btnCurve'
):
self
.
btnCurve
.
setEnabled
(
True
)
should_enable_curve
=
True
# 默认启用(因为已经有任务了)
try
:
# 通过parent链向上查找主窗口
main_window
=
self
.
window
()
# 检查是否在曲线模式主布局
if
hasattr
(
main_window
,
'_video_layout_mode'
)
and
main_window
.
_video_layout_mode
==
1
:
# 在曲线模式下,检查子布局索引
if
hasattr
(
main_window
,
'curveLayoutStack'
):
current_index
=
main_window
.
curveLayoutStack
.
currentIndex
()
# 子布局索引0是同步布局,禁用查看曲线按钮
if
current_index
==
0
:
should_enable_curve
=
False
except
:
pass
self
.
btnCurve
.
setEnabled
(
should_enable_curve
)
if
not
should_enable_curve
:
self
.
btnCurve
.
setToolTip
(
"同步布局下无法查看曲线"
)
else
:
self
.
btnCurve
.
setToolTip
(
"查看曲线"
)
if
hasattr
(
self
,
'btnAmplify'
):
if
hasattr
(
self
,
'btnAmplify'
):
self
.
btnAmplify
.
setEnabled
(
True
)
self
.
btnAmplify
.
setEnabled
(
True
)
if
hasattr
(
self
,
'btnEdit'
):
if
hasattr
(
self
,
'btnEdit'
):
...
...
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