From 4c5fc718c1bc318665b2dbd16a51cf3ed55c11f6 Mon Sep 17 00:00:00 2001
From: "feifei.xu" <307327147@qq.com>
Date: Fri, 10 Jul 2026 13:35:16 +0800
Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=88=9D=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main.py | 34 +-
main.ui | 52 +++
main_ui.py | 56 ++++
mil.pyi | 27 ++
mil/__init__.py | 5 +
{src => mil}/core/__init__.py | 4 +-
{src => mil}/core/base.py | 0
{src => mil}/core/exceptions.py | 0
{src => mil}/core/mil_create_data_excel.py | 0
{src => mil}/core/mil_read_case_excel.py | 0
{src => mil}/core/mil_read_data_excel.py | 0
{src => mil}/core/mil_update_excel.py | 0
mil/ui/mil_tool.py | 17 +
mil/ui/mil_tool.ui | 367 +++++++++++++++++++++
mil/ui/mil_tool_ui.py | 316 ++++++++++++++++++
src/core/logging_config.py | 61 ----
tests/__init__.py | 0
tests/conftest.py | 47 ---
tests/test_base.py | 20 --
tests/test_mil_case_excel.py | 292 ----------------
tests/test_mil_data_excel.py | 150 ---------
21 files changed, 855 insertions(+), 593 deletions(-)
create mode 100644 main.ui
create mode 100644 main_ui.py
create mode 100644 mil.pyi
create mode 100644 mil/__init__.py
rename {src => mil}/core/__init__.py (87%)
rename {src => mil}/core/base.py (100%)
rename {src => mil}/core/exceptions.py (100%)
rename {src => mil}/core/mil_create_data_excel.py (100%)
rename {src => mil}/core/mil_read_case_excel.py (100%)
rename {src => mil}/core/mil_read_data_excel.py (100%)
rename {src => mil}/core/mil_update_excel.py (100%)
create mode 100644 mil/ui/mil_tool.py
create mode 100644 mil/ui/mil_tool.ui
create mode 100644 mil/ui/mil_tool_ui.py
delete mode 100644 src/core/logging_config.py
delete mode 100644 tests/__init__.py
delete mode 100644 tests/conftest.py
delete mode 100644 tests/test_base.py
delete mode 100644 tests/test_mil_case_excel.py
delete mode 100644 tests/test_mil_data_excel.py
diff --git a/main.py b/main.py
index 2abd127..a092ced 100644
--- a/main.py
+++ b/main.py
@@ -1,25 +1,19 @@
-"""main.py - MIL SDK 测试示例"""
-from pathlib import Path
-
-from src.core import (
- setup_logging,
- read_excel_data,
- read_excel_case,
- create_excel_case,
- update_case_excel,
-)
+from main_ui import Ui_MainWindow
+from PySide6.QtWidgets import QApplication, QMainWindow
+import sys
+from qt_material import apply_stylesheet
-def main() -> None:
- """MIL SDK 示例程序主函数"""
- setup_logging()
+class MainWindow(QMainWindow,Ui_MainWindow):
+ def __init__(self):
+ super().__init__()
+ self.setupUi(self)
- excel_path = Path(__file__).parent
-
- data_dict = read_excel_data("new_data.xlsx", return_object=False)
- old_data_dict = read_excel_data("old_data.xlsx", return_object=False)
- update_case_excel("new_case.xlsx", old_data_dict, data_dict)
+ apply_stylesheet(self, style=None,theme='dark_teal.xml')
-if __name__ == "__main__":
- main()
\ No newline at end of file
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ main: MainWindow = MainWindow()
+ main.show()
+ sys.exit(app.exec())
\ No newline at end of file
diff --git a/main.ui b/main.ui
new file mode 100644
index 0000000..e514374
--- /dev/null
+++ b/main.ui
@@ -0,0 +1,52 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 800
+ 600
+
+
+
+ MainWindow
+
+
+
+ -
+
+
+ QFrame::Shape::StyledPanel
+
+
+ QFrame::Shadow::Raised
+
+
+
+
+
+
+
+
+
+
+ FrameMILTool
+ QFrame
+
+ 1
+
+
+
+
+
diff --git a/main_ui.py b/main_ui.py
new file mode 100644
index 0000000..cc26f8e
--- /dev/null
+++ b/main_ui.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'main.ui'
+##
+## Created by: Qt User Interface Compiler version 6.11.1
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+ QMetaObject, QObject, QPoint, QRect,
+ QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+ QFont, QFontDatabase, QGradient, QIcon,
+ QImage, QKeySequence, QLinearGradient, QPainter,
+ QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QMainWindow,
+ QMenuBar, QSizePolicy, QStatusBar, QWidget)
+
+from mil import FrameMILTool
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
+ MainWindow.resize(800, 600)
+ self.centralwidget = QWidget(MainWindow)
+ self.centralwidget.setObjectName(u"centralwidget")
+ self.gridLayout = QGridLayout(self.centralwidget)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.frame = FrameMILTool(self.centralwidget)
+ self.frame.setObjectName(u"frame")
+ self.frame.setFrameShape(QFrame.Shape.StyledPanel)
+ self.frame.setFrameShadow(QFrame.Shadow.Raised)
+
+ self.gridLayout.addWidget(self.frame, 0, 0, 1, 1)
+
+ MainWindow.setCentralWidget(self.centralwidget)
+ self.menubar = QMenuBar(MainWindow)
+ self.menubar.setObjectName(u"menubar")
+ self.menubar.setGeometry(QRect(0, 0, 800, 21))
+ MainWindow.setMenuBar(self.menubar)
+ self.statusbar = QStatusBar(MainWindow)
+ self.statusbar.setObjectName(u"statusbar")
+ MainWindow.setStatusBar(self.statusbar)
+
+ self.retranslateUi(MainWindow)
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
+
+ def retranslateUi(self, MainWindow):
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
+ # retranslateUi
+
diff --git a/mil.pyi b/mil.pyi
new file mode 100644
index 0000000..8254abb
--- /dev/null
+++ b/mil.pyi
@@ -0,0 +1,27 @@
+# This file was generated by Nuitka
+
+# Stubs included by default
+from openpyxl import Workbook
+from ui.mil_tool import FrameMILTool
+
+def create_mil_tool(parent: typing.Any) -> typing.Any:
+ ...
+
+__name__ = ...
+
+
+
+# Modules used internally, to allow implicit dependencies to be seen:
+import os
+import openpyxl
+import logging
+import dataclasses
+import typing
+import copy
+import openpyxl.worksheet
+import openpyxl.worksheet.worksheet
+import _frozen_importlib_external
+import PySide6
+import PySide6.QtWidgets
+import PySide6.QtCore
+import PySide6.QtGui
\ No newline at end of file
diff --git a/mil/__init__.py b/mil/__init__.py
new file mode 100644
index 0000000..6de39c9
--- /dev/null
+++ b/mil/__init__.py
@@ -0,0 +1,5 @@
+from .ui.mil_tool import FrameMILTool
+from openpyxl import Workbook
+
+def create_mil_tool(parent=None):
+ return FrameMILTool(parent)
diff --git a/src/core/__init__.py b/mil/core/__init__.py
similarity index 87%
rename from src/core/__init__.py
rename to mil/core/__init__.py
index 7d992b6..770647c 100644
--- a/src/core/__init__.py
+++ b/mil/core/__init__.py
@@ -3,9 +3,8 @@
提供 MIL 仿真数据读取功能
使用示例:
- from src.core import setup_logging, read_excel_data
+ from src.core import read_excel_data
- setup_logging()
result = read_excel_data("simulation.xlsx")
"""
import logging
@@ -23,7 +22,6 @@ from .exceptions import (
CaseDataError,
ExcelWriteError,
)
-from .logging_config import setup_logging, get_logger
__all__ = [
"DataLog",
diff --git a/src/core/base.py b/mil/core/base.py
similarity index 100%
rename from src/core/base.py
rename to mil/core/base.py
diff --git a/src/core/exceptions.py b/mil/core/exceptions.py
similarity index 100%
rename from src/core/exceptions.py
rename to mil/core/exceptions.py
diff --git a/src/core/mil_create_data_excel.py b/mil/core/mil_create_data_excel.py
similarity index 100%
rename from src/core/mil_create_data_excel.py
rename to mil/core/mil_create_data_excel.py
diff --git a/src/core/mil_read_case_excel.py b/mil/core/mil_read_case_excel.py
similarity index 100%
rename from src/core/mil_read_case_excel.py
rename to mil/core/mil_read_case_excel.py
diff --git a/src/core/mil_read_data_excel.py b/mil/core/mil_read_data_excel.py
similarity index 100%
rename from src/core/mil_read_data_excel.py
rename to mil/core/mil_read_data_excel.py
diff --git a/src/core/mil_update_excel.py b/mil/core/mil_update_excel.py
similarity index 100%
rename from src/core/mil_update_excel.py
rename to mil/core/mil_update_excel.py
diff --git a/mil/ui/mil_tool.py b/mil/ui/mil_tool.py
new file mode 100644
index 0000000..8f889c3
--- /dev/null
+++ b/mil/ui/mil_tool.py
@@ -0,0 +1,17 @@
+import logging
+
+from .mil_tool_ui import Ui_FrameMILTool
+from PySide6.QtWidgets import QFrame
+
+logger = logging.getLogger(__name__)
+
+class FrameMILTool(QFrame,Ui_FrameMILTool):
+ def __init__(self,parent=None):
+ super().__init__(parent)
+ self.setupUi(self)
+
+ def init_ui(self):
+ pass
+ # logger.info("FrameMILTool 初始化完成")
+
+
diff --git a/mil/ui/mil_tool.ui b/mil/ui/mil_tool.ui
new file mode 100644
index 0000000..8f5f655
--- /dev/null
+++ b/mil/ui/mil_tool.ui
@@ -0,0 +1,367 @@
+
+
+ FrameMILTool
+
+
+
+ 0
+ 0
+ 706
+ 308
+
+
+
+ Frame
+
+
+ -
+
+
+ QTabWidget::TabPosition::South
+
+
+ 0
+
+
+
+ 功能面板
+
+
+
-
+
+
+ QFrame::Shape::StyledPanel
+
+
+ QFrame::Shadow::Raised
+
+
+
-
+
+
-
+
+
+ 项目
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ color: rgb(255, 255, 255);
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ color: rgb(255, 255, 255);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ color: rgb(255, 255, 255);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ ...
+
+
+
+ -
+
+
+ 累计时间
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 生成
+
+
+
+ -
+
+
+ 测试用例
+
+
+
+ -
+
+
+ 数据文件
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ ...
+
+
+
+ -
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+ -
+
+
+ QFrame::Shape::StyledPanel
+
+
+ QFrame::Shadow::Raised
+
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ 名称
+
+
+
+ -
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 名称
+
+
+
+ -
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 类型
+
+
+
+ -
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 类型
+
+
+
+ -
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 值定义
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 值定义
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ 加载测试用例
+
+
+
+ -
+
+
+ 删除
+
+
+
+ -
+
+
+ 查找
+
+
+
+ -
+
+
+ 替换
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 更新
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Orientation::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ 项目列表
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mil/ui/mil_tool_ui.py b/mil/ui/mil_tool_ui.py
new file mode 100644
index 0000000..029f9dd
--- /dev/null
+++ b/mil/ui/mil_tool_ui.py
@@ -0,0 +1,316 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'mil_tool.ui'
+##
+## Created by: Qt User Interface Compiler version 6.11.1
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+ QMetaObject, QObject, QPoint, QRect,
+ QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+ QFont, QFontDatabase, QGradient, QIcon,
+ QImage, QKeySequence, QLinearGradient, QPainter,
+ QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QFrame,
+ QGridLayout, QLabel, QLineEdit, QListWidget,
+ QListWidgetItem, QPushButton, QRadioButton, QSizePolicy,
+ QSpacerItem, QTabWidget, QWidget)
+
+class Ui_FrameMILTool(object):
+ def setupUi(self, FrameMILTool):
+ if not FrameMILTool.objectName():
+ FrameMILTool.setObjectName(u"FrameMILTool")
+ FrameMILTool.resize(706, 308)
+ self.gridLayout_8 = QGridLayout(FrameMILTool)
+ self.gridLayout_8.setObjectName(u"gridLayout_8")
+ self.tabWidget = QTabWidget(FrameMILTool)
+ self.tabWidget.setObjectName(u"tabWidget")
+ self.tabWidget.setTabPosition(QTabWidget.TabPosition.South)
+ self.widget = QWidget()
+ self.widget.setObjectName(u"widget")
+ self.gridLayout_12 = QGridLayout(self.widget)
+ self.gridLayout_12.setObjectName(u"gridLayout_12")
+ self.frame_3 = QFrame(self.widget)
+ self.frame_3.setObjectName(u"frame_3")
+ self.frame_3.setFrameShape(QFrame.Shape.StyledPanel)
+ self.frame_3.setFrameShadow(QFrame.Shadow.Raised)
+ self.gridLayout_3 = QGridLayout(self.frame_3)
+ self.gridLayout_3.setObjectName(u"gridLayout_3")
+ self.gridLayout_2 = QGridLayout()
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.label = QLabel(self.frame_3)
+ self.label.setObjectName(u"label")
+
+ self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1)
+
+ self.comboBox = QComboBox(self.frame_3)
+ self.comboBox.setObjectName(u"comboBox")
+ sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.comboBox.sizePolicy().hasHeightForWidth())
+ self.comboBox.setSizePolicy(sizePolicy)
+ self.comboBox.setStyleSheet(u"color: rgb(255, 255, 255);")
+
+ self.gridLayout_2.addWidget(self.comboBox, 0, 1, 1, 1)
+
+
+ self.gridLayout_3.addLayout(self.gridLayout_2, 0, 0, 1, 1)
+
+ self.gridLayout = QGridLayout()
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.FilePath = QLineEdit(self.frame_3)
+ self.FilePath.setObjectName(u"FilePath")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.FilePath.sizePolicy().hasHeightForWidth())
+ self.FilePath.setSizePolicy(sizePolicy1)
+ self.FilePath.setStyleSheet(u"color: rgb(255, 255, 255);")
+
+ self.gridLayout.addWidget(self.FilePath, 1, 2, 1, 1)
+
+ self.DataPath = QLineEdit(self.frame_3)
+ self.DataPath.setObjectName(u"DataPath")
+ sizePolicy1.setHeightForWidth(self.DataPath.sizePolicy().hasHeightForWidth())
+ self.DataPath.setSizePolicy(sizePolicy1)
+ self.DataPath.setStyleSheet(u"color: rgb(255, 255, 255);")
+
+ self.gridLayout.addWidget(self.DataPath, 0, 2, 1, 1)
+
+ self.FileButton = QPushButton(self.frame_3)
+ self.FileButton.setObjectName(u"FileButton")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
+ sizePolicy2.setHorizontalStretch(0)
+ sizePolicy2.setVerticalStretch(0)
+ sizePolicy2.setHeightForWidth(self.FileButton.sizePolicy().hasHeightForWidth())
+ self.FileButton.setSizePolicy(sizePolicy2)
+
+ self.gridLayout.addWidget(self.FileButton, 1, 3, 1, 1)
+
+ self.checkBox = QCheckBox(self.frame_3)
+ self.checkBox.setObjectName(u"checkBox")
+
+ self.gridLayout.addWidget(self.checkBox, 0, 4, 1, 1)
+
+ self.radioButtonFile = QRadioButton(self.frame_3)
+ self.radioButtonFile.setObjectName(u"radioButtonFile")
+
+ self.gridLayout.addWidget(self.radioButtonFile, 1, 0, 1, 1)
+
+ self.pushButton = QPushButton(self.frame_3)
+ self.pushButton.setObjectName(u"pushButton")
+ sizePolicy2.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
+ self.pushButton.setSizePolicy(sizePolicy2)
+
+ self.gridLayout.addWidget(self.pushButton, 1, 4, 1, 1)
+
+ self.label_3 = QLabel(self.frame_3)
+ self.label_3.setObjectName(u"label_3")
+
+ self.gridLayout.addWidget(self.label_3, 1, 1, 1, 1)
+
+ self.label_2 = QLabel(self.frame_3)
+ self.label_2.setObjectName(u"label_2")
+
+ self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1)
+
+ self.DataButton = QPushButton(self.frame_3)
+ self.DataButton.setObjectName(u"DataButton")
+ sizePolicy2.setHeightForWidth(self.DataButton.sizePolicy().hasHeightForWidth())
+ self.DataButton.setSizePolicy(sizePolicy2)
+
+ self.gridLayout.addWidget(self.DataButton, 0, 3, 1, 1)
+
+ self.radioButtonData = QRadioButton(self.frame_3)
+ self.radioButtonData.setObjectName(u"radioButtonData")
+ self.radioButtonData.setChecked(True)
+
+ self.gridLayout.addWidget(self.radioButtonData, 0, 0, 1, 1)
+
+
+ self.gridLayout_3.addLayout(self.gridLayout, 1, 0, 1, 1)
+
+
+ self.gridLayout_12.addWidget(self.frame_3, 0, 0, 1, 1)
+
+ self.frame = QFrame(self.widget)
+ self.frame.setObjectName(u"frame")
+ self.frame.setFrameShape(QFrame.Shape.StyledPanel)
+ self.frame.setFrameShadow(QFrame.Shadow.Raised)
+ self.gridLayout_6 = QGridLayout(self.frame)
+ self.gridLayout_6.setObjectName(u"gridLayout_6")
+ self.gridLayout_5 = QGridLayout()
+ self.gridLayout_5.setObjectName(u"gridLayout_5")
+ self.label_4 = QLabel(self.frame)
+ self.label_4.setObjectName(u"label_4")
+ sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding)
+ sizePolicy3.setHorizontalStretch(0)
+ sizePolicy3.setVerticalStretch(0)
+ sizePolicy3.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth())
+ self.label_4.setSizePolicy(sizePolicy3)
+
+ self.gridLayout_5.addWidget(self.label_4, 0, 0, 1, 1)
+
+ self.lineEdit = QLineEdit(self.frame)
+ self.lineEdit.setObjectName(u"lineEdit")
+
+ self.gridLayout_5.addWidget(self.lineEdit, 0, 1, 1, 1)
+
+ self.label_7 = QLabel(self.frame)
+ self.label_7.setObjectName(u"label_7")
+ sizePolicy3.setHeightForWidth(self.label_7.sizePolicy().hasHeightForWidth())
+ self.label_7.setSizePolicy(sizePolicy3)
+
+ self.gridLayout_5.addWidget(self.label_7, 0, 2, 1, 1)
+
+ self.lineEdit_4 = QLineEdit(self.frame)
+ self.lineEdit_4.setObjectName(u"lineEdit_4")
+
+ self.gridLayout_5.addWidget(self.lineEdit_4, 0, 3, 1, 1)
+
+ self.label_5 = QLabel(self.frame)
+ self.label_5.setObjectName(u"label_5")
+ sizePolicy3.setHeightForWidth(self.label_5.sizePolicy().hasHeightForWidth())
+ self.label_5.setSizePolicy(sizePolicy3)
+
+ self.gridLayout_5.addWidget(self.label_5, 1, 0, 1, 1)
+
+ self.lineEdit_2 = QLineEdit(self.frame)
+ self.lineEdit_2.setObjectName(u"lineEdit_2")
+
+ self.gridLayout_5.addWidget(self.lineEdit_2, 1, 1, 2, 1)
+
+ self.label_8 = QLabel(self.frame)
+ self.label_8.setObjectName(u"label_8")
+ sizePolicy3.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth())
+ self.label_8.setSizePolicy(sizePolicy3)
+
+ self.gridLayout_5.addWidget(self.label_8, 1, 2, 1, 1)
+
+ self.lineEdit_5 = QLineEdit(self.frame)
+ self.lineEdit_5.setObjectName(u"lineEdit_5")
+
+ self.gridLayout_5.addWidget(self.lineEdit_5, 1, 3, 2, 1)
+
+ self.label_6 = QLabel(self.frame)
+ self.label_6.setObjectName(u"label_6")
+ sizePolicy3.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth())
+ self.label_6.setSizePolicy(sizePolicy3)
+
+ self.gridLayout_5.addWidget(self.label_6, 2, 0, 2, 1)
+
+ self.label_9 = QLabel(self.frame)
+ self.label_9.setObjectName(u"label_9")
+ sizePolicy3.setHeightForWidth(self.label_9.sizePolicy().hasHeightForWidth())
+ self.label_9.setSizePolicy(sizePolicy3)
+
+ self.gridLayout_5.addWidget(self.label_9, 2, 2, 2, 1)
+
+ self.lineEdit_3 = QLineEdit(self.frame)
+ self.lineEdit_3.setObjectName(u"lineEdit_3")
+
+ self.gridLayout_5.addWidget(self.lineEdit_3, 3, 1, 1, 1)
+
+ self.lineEdit_6 = QLineEdit(self.frame)
+ self.lineEdit_6.setObjectName(u"lineEdit_6")
+
+ self.gridLayout_5.addWidget(self.lineEdit_6, 3, 3, 1, 1)
+
+
+ self.gridLayout_6.addLayout(self.gridLayout_5, 0, 0, 1, 1)
+
+ self.gridLayout_10 = QGridLayout()
+ self.gridLayout_10.setObjectName(u"gridLayout_10")
+ self.pushButton_2 = QPushButton(self.frame)
+ self.pushButton_2.setObjectName(u"pushButton_2")
+ sizePolicy.setHeightForWidth(self.pushButton_2.sizePolicy().hasHeightForWidth())
+ self.pushButton_2.setSizePolicy(sizePolicy)
+
+ self.gridLayout_10.addWidget(self.pushButton_2, 0, 0, 1, 1)
+
+ self.pushButton_4 = QPushButton(self.frame)
+ self.pushButton_4.setObjectName(u"pushButton_4")
+
+ self.gridLayout_10.addWidget(self.pushButton_4, 0, 4, 1, 1)
+
+ self.pushButton_5 = QPushButton(self.frame)
+ self.pushButton_5.setObjectName(u"pushButton_5")
+
+ self.gridLayout_10.addWidget(self.pushButton_5, 0, 2, 1, 1)
+
+ self.pushButton_3 = QPushButton(self.frame)
+ self.pushButton_3.setObjectName(u"pushButton_3")
+
+ self.gridLayout_10.addWidget(self.pushButton_3, 0, 3, 1, 1)
+
+ self.UpdateButton = QPushButton(self.frame)
+ self.UpdateButton.setObjectName(u"UpdateButton")
+ sizePolicy2.setHeightForWidth(self.UpdateButton.sizePolicy().hasHeightForWidth())
+ self.UpdateButton.setSizePolicy(sizePolicy2)
+
+ self.gridLayout_10.addWidget(self.UpdateButton, 0, 5, 1, 1)
+
+
+ self.gridLayout_6.addLayout(self.gridLayout_10, 1, 0, 1, 1)
+
+
+ self.gridLayout_12.addWidget(self.frame, 1, 0, 1, 1)
+
+ self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
+
+ self.gridLayout_12.addItem(self.verticalSpacer, 2, 0, 1, 1)
+
+ self.tabWidget.addTab(self.widget, "")
+ self.tab_2 = QWidget()
+ self.tab_2.setObjectName(u"tab_2")
+ self.gridLayout_11 = QGridLayout(self.tab_2)
+ self.gridLayout_11.setObjectName(u"gridLayout_11")
+ self.listWidget = QListWidget(self.tab_2)
+ self.listWidget.setObjectName(u"listWidget")
+
+ self.gridLayout_11.addWidget(self.listWidget, 0, 0, 1, 1)
+
+ self.tabWidget.addTab(self.tab_2, "")
+
+ self.gridLayout_8.addWidget(self.tabWidget, 0, 0, 1, 1)
+
+
+ self.retranslateUi(FrameMILTool)
+
+ self.tabWidget.setCurrentIndex(0)
+
+
+ QMetaObject.connectSlotsByName(FrameMILTool)
+ # setupUi
+
+ def retranslateUi(self, FrameMILTool):
+ FrameMILTool.setWindowTitle(QCoreApplication.translate("FrameMILTool", u"Frame", None))
+ self.label.setText(QCoreApplication.translate("FrameMILTool", u"\u9879\u76ee", None))
+ self.FileButton.setText(QCoreApplication.translate("FrameMILTool", u"...", None))
+ self.checkBox.setText(QCoreApplication.translate("FrameMILTool", u"\u7d2f\u8ba1\u65f6\u95f4", None))
+ self.radioButtonFile.setText("")
+ self.pushButton.setText(QCoreApplication.translate("FrameMILTool", u"\u751f\u6210", None))
+ self.label_3.setText(QCoreApplication.translate("FrameMILTool", u"\u6d4b\u8bd5\u7528\u4f8b ", None))
+ self.label_2.setText(QCoreApplication.translate("FrameMILTool", u"\u6570\u636e\u6587\u4ef6 ", None))
+ self.DataButton.setText(QCoreApplication.translate("FrameMILTool", u"...", None))
+ self.radioButtonData.setText("")
+ self.label_4.setText(QCoreApplication.translate("FrameMILTool", u"\u540d\u79f0", None))
+ self.label_7.setText(QCoreApplication.translate("FrameMILTool", u"\u540d\u79f0", None))
+ self.label_5.setText(QCoreApplication.translate("FrameMILTool", u"\u7c7b\u578b", None))
+ self.label_8.setText(QCoreApplication.translate("FrameMILTool", u"\u7c7b\u578b", None))
+ self.label_6.setText(QCoreApplication.translate("FrameMILTool", u"\u503c\u5b9a\u4e49", None))
+ self.label_9.setText(QCoreApplication.translate("FrameMILTool", u"\u503c\u5b9a\u4e49", None))
+ self.pushButton_2.setText(QCoreApplication.translate("FrameMILTool", u"\u52a0\u8f7d\u6d4b\u8bd5\u7528\u4f8b", None))
+ self.pushButton_4.setText(QCoreApplication.translate("FrameMILTool", u"\u5220\u9664", None))
+ self.pushButton_5.setText(QCoreApplication.translate("FrameMILTool", u"\u67e5\u627e", None))
+ self.pushButton_3.setText(QCoreApplication.translate("FrameMILTool", u"\u66ff\u6362", None))
+ self.UpdateButton.setText(QCoreApplication.translate("FrameMILTool", u"\u66f4\u65b0", None))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.widget), QCoreApplication.translate("FrameMILTool", u"\u529f\u80fd\u9762\u677f", None))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("FrameMILTool", u"\u9879\u76ee\u5217\u8868", None))
+ # retranslateUi
+
diff --git a/src/core/logging_config.py b/src/core/logging_config.py
deleted file mode 100644
index 1edac08..0000000
--- a/src/core/logging_config.py
+++ /dev/null
@@ -1,61 +0,0 @@
-"""日志配置模块"""
-import logging
-import sys
-from pathlib import Path
-from typing import Literal
-
-
-def setup_logging(
- level: Literal["DEBUG", "INFO", "WARNING", "ERROR"] = "INFO",
- log_file: str | Path | None = "logs/mil_sdk.log",
- console_output: bool = True,
-) -> logging.Logger:
- """配置日志系统
-
- Args:
- level: 日志级别,默认 INFO
- log_file: 日志文件路径,默认 logs/mil_sdk.log。设为 None 则不写入文件
- console_output: 是否输出到控制台,默认 True
-
- Returns:
- 根日志记录器
- """
- logger = logging.getLogger()
- logger.setLevel(level)
-
- if logger.hasHandlers():
- logger.handlers.clear()
-
- formatter = logging.Formatter(
- "%(asctime)s [%(levelname)s] %(message)s",
- datefmt="%Y-%m-%d %H:%M:%S"
- )
-
- if log_file is not None:
- log_path = Path(log_file)
- log_path.parent.mkdir(parents=True, exist_ok=True)
-
- file_handler = logging.FileHandler(log_path, encoding="utf-8")
- file_handler.setLevel(logging.DEBUG)
- file_handler.setFormatter(formatter)
- logger.addHandler(file_handler)
-
- if console_output:
- console_handler = logging.StreamHandler(sys.stdout)
- console_handler.setLevel(level)
- console_handler.setFormatter(formatter)
- logger.addHandler(console_handler)
-
- return logger
-
-
-def get_logger(name: str) -> logging.Logger:
- """获取指定名称的日志记录器
-
- Args:
- name: 日志记录器名称,通常使用 __name__
-
- Returns:
- 日志记录器实例
- """
- return logging.getLogger(name)
\ No newline at end of file
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/conftest.py b/tests/conftest.py
deleted file mode 100644
index b47d61b..0000000
--- a/tests/conftest.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import pytest
-from pathlib import Path
-from openpyxl import Workbook
-
-
-@pytest.fixture
-def sample_excel_path() -> Path:
- """返回根目录下的 sample.xlsx 路径"""
- path = Path(__file__).parent.parent / "sample.xlsx"
- if not path.exists():
- pytest.skip(f"测试文件 {path} 不存在")
- return path
-
-
-@pytest.fixture
-def invalid_excel_path(tmp_path: Path) -> Path:
- """创建缺少 Scenario1 表的无效 Excel 文件"""
- wb = Workbook()
- wb.save(tmp_path / "invalid.xlsx")
- return tmp_path / "invalid.xlsx"
-
-
-@pytest.fixture
-def sample_data_dict() -> dict:
- """返回示例数据字典"""
- return {
- "Scenario1": {
- "headers": ["Column1", "Column2", "Column3"],
- "rows": [
- ["Value1", "Value2", "Value3"],
- ["Value4", "Value5", "Value6"]
- ]
- }
- }
-
-
-@pytest.fixture
-def sample_sheets_dict() -> dict:
- """返回示例工作表字典"""
- return {
- "Scenario1": {
- "A1": "Header1",
- "B1": "Header2",
- "A2": "Data1",
- "B2": "Data2"
- }
- }
\ No newline at end of file
diff --git a/tests/test_base.py b/tests/test_base.py
deleted file mode 100644
index f7153c9..0000000
--- a/tests/test_base.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import pytest
-from src.core.base import DataLog
-
-
-def test_datalog_defaults():
- log = DataLog()
- assert log.time == 0.0
- assert log.value == ""
-
-
-def test_datalog_with_values():
- log = DataLog(time=1.5, value="test")
- assert log.time == 1.5
- assert log.value == "test"
-
-
-def test_datalog_equality():
- log1 = DataLog(time=1.0, value="a")
- log2 = DataLog(time=1.0, value="a")
- assert log1 == log2
\ No newline at end of file
diff --git a/tests/test_mil_case_excel.py b/tests/test_mil_case_excel.py
deleted file mode 100644
index 1ca9c75..0000000
--- a/tests/test_mil_case_excel.py
+++ /dev/null
@@ -1,292 +0,0 @@
-import pytest
-from pathlib import Path
-from openpyxl import Workbook
-
-from src.core.mil_read_case_excel import (
- read_excel_case,
- _get_template_version,
- _analysis_action,
-)
-from src.core.mil_create_data_excel import (
- create_excel_case,
- _init_data_log,
- _analysis_case,
- _analysis_step,
-)
-from src.core.exceptions import ExcelReadError, ExcelFormatError, CaseDataError
-from src.core.base import DataLog
-
-
-@pytest.fixture
-def sample_data_dict():
- """返回示例数据字典"""
- return {
- "signal1": {
- "type": "Type1",
- "column": 2,
- "datalog": [DataLog(0.0, "initial"), DataLog(1.0, "value1")]
- },
- "signal2": {
- "type": "Type2",
- "column": 3,
- "datalog": [DataLog(0.0, "init2"), DataLog(1.0, "value2")]
- }
- }
-
-
-@pytest.fixture
-def sample_sheets_dict():
- """返回示例工作表字典"""
- return {
- "TestSheet": {
- "TestCase1": {
- "enable": False,
- "step": {
- "step0": {
- "name": "Step1",
- "time": 1.0,
- "action": {"signal1": "new_value1"}
- },
- "step1": {
- "name": "Step2",
- "time": 2.0,
- "action": {"signal2": "new_value2"}
- }
- }
- },
- "TestCase2": {
- "enable": True,
- "step": {}
- }
- }
- }
-
-
-def test_get_template_version():
- """验证获取模板版本号"""
- wb = Workbook()
- sheet = wb.active
- sheet.cell(2, 1, "v1.0.0")
- sheet.cell(3, 1, None)
-
- version = _get_template_version(sheet)
- assert version == "v1.0.0"
-
-
-def test_get_template_version_empty():
- """验证空工作表的版本号"""
- wb = Workbook()
- sheet = wb.active
-
- version = _get_template_version(sheet)
- assert version is None
-
-
-def test_analysis_action_valid(sample_data_dict):
- """验证解析有效操作字符串"""
- wb = Workbook()
- sheet = wb.create_sheet("TestSheet")
- sheet.cell(1, 1, "Test")
-
- action = _analysis_action(sheet, 1, 3, "signal1=newvalue", sample_data_dict, "test.xlsx")
- assert "signal1" in action
- assert action["signal1"] == "newvalue"
-
-
-def test_analysis_action_multiple(sample_data_dict):
- """验证解析多个操作"""
- wb = Workbook()
- sheet = wb.create_sheet("TestSheet")
- sheet.cell(1, 1, "Test")
-
- action = _analysis_action(sheet, 1, 3, "signal1=v1; signal2=v2", sample_data_dict, "test.xlsx")
- assert "signal1" in action
- assert "signal2" in action
- assert action["signal1"] == "v1"
- assert action["signal2"] == "v2"
-
-
-def test_analysis_action_invalid_signal(sample_data_dict):
- """验证解析无效信号时抛出异常"""
- wb = Workbook()
- sheet = wb.create_sheet("TestSheet")
- sheet.cell(1, 1, "Test")
-
- with pytest.raises(CaseDataError, match="信号 .* 不存在"):
- _analysis_action(sheet, 1, 3, "invalid_signal=value", sample_data_dict, "test.xlsx")
-
-
-def test_init_data_log(sample_data_dict):
- """验证初始化数据日志"""
- data_copy = {k: v.copy() for k, v in sample_data_dict.items()}
- for name in data_copy:
- data_copy[name]["datalog"] = data_copy[name]["datalog"].copy()
-
- _init_data_log(data_copy)
-
- for name in data_copy:
- assert len(data_copy[name]["datalog"]) == 1
- assert data_copy[name]["datalog"][0].time == 0.0
-
-
-def test_analysis_step_with_action(sample_data_dict):
- """验证分析带操作的步骤"""
- step_dict = {
- "step0": {
- "name": "TestStep",
- "time": 1.5,
- "action": {"signal1": "newvalue"}
- }
- }
-
- data_copy = {k: v.copy() for k, v in sample_data_dict.items()}
- for name in data_copy:
- data_copy[name]["datalog"] = data_copy[name]["datalog"].copy()
-
- _analysis_step(step_dict, data_copy)
-
- assert len(data_copy["signal1"]["datalog"]) == 3
- assert data_copy["signal1"]["datalog"][-1].time == 1.5
- assert data_copy["signal1"]["datalog"][-1].value == "newvalue"
-
-
-def test_analysis_step_without_action(sample_data_dict):
- """验证分析不带操作的步骤"""
- step_dict = {
- "step0": {
- "name": "TestStep",
- "time": 1.0
- }
- }
-
- data_copy = {k: v.copy() for k, v in sample_data_dict.items()}
- for name in data_copy:
- data_copy[name]["datalog"] = data_copy[name]["datalog"].copy()
-
- initial_length = len(data_copy["signal1"]["datalog"])
- _analysis_step(step_dict, data_copy)
-
- assert len(data_copy["signal1"]["datalog"]) == initial_length + 1
-
-
-def test_analysis_case(sample_data_dict, sample_sheets_dict):
- """验证用例分析"""
- result = _analysis_case(sample_data_dict, sample_sheets_dict)
-
- assert "TestCase1" in result
- assert "TestCase2" not in result
-
-
-def test_analysis_case_skips_enabled_cases(sample_data_dict):
- """验证跳过早启用的用例"""
- sheets_dict = {
- "TestSheet": {
- "EnabledCase": {
- "enable": True,
- "step": {}
- }
- }
- }
-
- result = _analysis_case(sample_data_dict, sheets_dict)
- assert "EnabledCase" not in result
-
-
-def test_read_excel_case_file_not_found():
- """验证文件不存在时抛出异常"""
- with pytest.raises(ExcelReadError, match="不存在"):
- read_excel_case("nonexistent.xlsx", {}, False)
-
-
-def test_read_excel_case_missing_atech_sheet(tmp_path: Path):
- """验证缺少 Atech-Hefei 表时抛出异常"""
- wb = Workbook()
- wb.create_sheet("OtherSheet")
- invalid_path = tmp_path / "invalid.xlsx"
- wb.save(invalid_path)
-
- with pytest.raises(ExcelFormatError, match="缺少 Atech-Hefei 表"):
- read_excel_case(invalid_path, {}, False)
-
-
-def test_read_excel_case_missing_version(tmp_path: Path, sample_data_dict):
- """验证缺少版本号时抛出异常"""
- wb = Workbook()
- wb.create_sheet("Atech-Hefei")
- wb.create_sheet("TestSheet")
- invalid_path = tmp_path / "no_version.xlsx"
- wb.save(invalid_path)
-
- with pytest.raises(ExcelFormatError, match="缺少模板版本号"):
- read_excel_case(invalid_path, sample_data_dict, False)
-
-
-def test_read_excel_case_success(tmp_path: Path, sample_data_dict):
- """验证成功读取用例模板"""
- wb = Workbook()
- wb.remove(wb.active)
-
- version_sheet = wb.create_sheet("Atech-Hefei")
- version_sheet.cell(2, 1, "v1.0.0")
-
- test_sheet = wb.create_sheet("TestSheet")
- test_sheet.cell(2, 1, "TestCase1")
- test_sheet.cell(2, 2, "未完成")
- test_sheet.cell(2, 3, None)
- test_sheet.cell(2, 4, "Step1")
- test_sheet.cell(2, 5, 1.0)
- test_sheet.cell(2, 6, None)
-
- test_sheet.cell(3, 1, "TestCase1")
- test_sheet.cell(3, 2, "未完成")
- test_sheet.cell(3, 3, None)
- test_sheet.cell(3, 4, "Step2")
- test_sheet.cell(3, 5, 2.0)
- test_sheet.cell(3, 6, None)
-
- valid_path = tmp_path / "valid.xlsx"
- wb.save(valid_path)
-
- result = read_excel_case(valid_path, sample_data_dict, False)
-
- assert "TestSheet" in result
- assert "TestCase1" in result["TestSheet"]
-
-
-def test_read_excel_case_missing_title(tmp_path: Path, sample_data_dict):
- """验证缺少标题时抛出异常"""
- wb = Workbook()
-
- version_sheet = wb.create_sheet("Atech-Hefei")
- version_sheet.cell(2, 1, "v1.0.0")
-
- test_sheet = wb.create_sheet("TestSheet")
- test_sheet.cell(2, 1, None)
-
- invalid_path = tmp_path / "missing_title.xlsx"
- wb.save(invalid_path)
-
- with pytest.raises(CaseDataError, match="必须有标题名"):
- read_excel_case(invalid_path, sample_data_dict, False)
-
-
-def test_read_excel_case_invalid_time(tmp_path: Path, sample_data_dict):
- """验证时间格式错误时抛出异常"""
- wb = Workbook()
- wb.remove(wb.active)
-
- version_sheet = wb.create_sheet("Atech-Hefei")
- version_sheet.cell(2, 1, "v1.0.0")
-
- test_sheet = wb.create_sheet("TestSheet")
- test_sheet.cell(2, 1, "TestCase1")
- test_sheet.cell(2, 2, "未完成")
- test_sheet.cell(2, 4, "Step1")
- test_sheet.cell(2, 5, "invalid_time")
- test_sheet.cell(2, 6, None)
-
- invalid_path = tmp_path / "invalid_time.xlsx"
- wb.save(invalid_path)
-
- with pytest.raises(CaseDataError, match="时间必须是数字"):
- read_excel_case(invalid_path, sample_data_dict, False)
diff --git a/tests/test_mil_data_excel.py b/tests/test_mil_data_excel.py
deleted file mode 100644
index c2051a7..0000000
--- a/tests/test_mil_data_excel.py
+++ /dev/null
@@ -1,150 +0,0 @@
-import pytest
-from pathlib import Path
-from openpyxl import Workbook
-
-from src.core.mil_read_data_excel import read_excel_data, ExcelReaderConfig
-from src.core.exceptions import ExcelReadError, ExcelFormatError
-
-
-def test_read_excel_data_returns_required_keys(sample_excel_path: Path):
- """验证返回结果包含必需键"""
- result = read_excel_data(sample_excel_path)
- assert "wb" in result
- assert "sheet" in result
- assert "source_row" in result
-
-
-def test_read_excel_data_contains_signals(sample_excel_path: Path):
- """验证能解析出信号数据"""
- result = read_excel_data(sample_excel_path)
- signal_keys = [k for k in result.keys() if k not in ("wb", "sheet", "source_row")]
- assert len(signal_keys) > 0, "应至少包含一个信号"
- for name in signal_keys:
- assert "type" in result[name]
- assert "column" in result[name]
- assert "datalog" in result[name]
-
-
-def test_read_excel_file_not_found():
- """文件不存在时抛出 ExcelReadError"""
- with pytest.raises(ExcelReadError, match="不存在"):
- read_excel_data("nonexistent.xlsx")
-
-
-def test_read_excel_missing_sheet(tmp_path: Path):
- """缺少 Scenario1 表时抛出 ExcelFormatError"""
- wb = Workbook()
- wb.create_sheet("WrongSheet")
- invalid_path = tmp_path / "invalid.xlsx"
- wb.save(invalid_path)
- with pytest.raises(ExcelFormatError, match="缺少"):
- read_excel_data(invalid_path)
-
-
-def test_read_excel_missing_source_header(tmp_path: Path):
- """缺少 Source: Input 标记时抛出 ExcelFormatError"""
- wb = Workbook()
- sheet = wb.active
- sheet.title = ExcelReaderConfig().sheet_name
- sheet.cell(1, 1, "time")
- sheet.cell(1, 2, "signal1")
- invalid_path = tmp_path / "missing_header.xlsx"
- wb.save(invalid_path)
- with pytest.raises(ExcelFormatError, match="缺少"):
- read_excel_data(invalid_path)
-
-
-def test_datalog_is_list(sample_excel_path: Path):
- """验证 datalog 是 DataLog 对象列表"""
- result = read_excel_data(sample_excel_path)
- signal_keys = [k for k in result.keys() if k not in ("wb", "sheet", "source_row")]
- assert len(signal_keys) > 0
- first_signal = result[signal_keys[0]]
- assert len(first_signal["datalog"]) > 0
- assert hasattr(first_signal["datalog"][0], "time")
- assert hasattr(first_signal["datalog"][0], "value")
-
-
-
-
-
-def test_read_excel_data_return_object(sample_excel_path: Path):
- """验证 return_object=True 时返回 ExcelDataResult 对象"""
- from src.core.base import ExcelDataResult, SignalData
-
- result = read_excel_data(sample_excel_path, return_object=True)
- assert isinstance(result, ExcelDataResult)
- assert result.sheet_name == "Scenario1"
- assert result.source_row > 0
- assert len(result.signals) > 0
-
-
-def test_read_excel_data_signal_data_access(sample_excel_path: Path):
- """验证 ExcelDataResult 的信号访问方法"""
- from src.core.base import SignalData
-
- result = read_excel_data(sample_excel_path, return_object=True)
- signal_names = result.get_signal_names()
- assert len(signal_names) > 0
-
- first_signal_name = signal_names[0]
- signal = result.get_signal(first_signal_name)
- assert isinstance(signal, SignalData)
- assert signal.datalog is not None
-
-
-def test_excel_reader_config_defaults():
- """验证 ExcelReaderConfig 默认值"""
- config = ExcelReaderConfig()
- assert config.sheet_name == "Scenario1"
- assert config.source_header == "Source: Input"
- assert config.time_column == 1
- assert config.header_row == 1
- assert config.type_row == 3
- assert config.data_start_row_offset == 1
-
-
-def test_excel_reader_config_custom():
- """验证 ExcelReaderConfig 自定义值"""
- config = ExcelReaderConfig(
- sheet_name="CustomSheet",
- source_header="CustomHeader",
- time_column=2,
- header_row=2,
- type_row=4,
- data_start_row_offset=2
- )
- assert config.sheet_name == "CustomSheet"
- assert config.source_header == "CustomHeader"
- assert config.time_column == 2
- assert config.header_row == 2
- assert config.type_row == 4
- assert config.data_start_row_offset == 2
-
-
-def test_read_excel_with_custom_config(tmp_path: Path):
- """验证使用自定义配置读取 Excel"""
- wb = Workbook()
- sheet = wb.active
- sheet.title = "CustomSheet"
-
- sheet.cell(1, 1, "time")
- sheet.cell(1, 2, "signal1")
- sheet.cell(2, 1, "CustomHeader")
- sheet.cell(2, 2, "CustomHeader")
- sheet.cell(3, 1, "Type1")
- sheet.cell(4, 1, 0.0)
- sheet.cell(4, 2, "value1")
- sheet.cell(5, 1, 1.0)
- sheet.cell(5, 2, "value2")
-
- custom_path = tmp_path / "custom.xlsx"
- wb.save(custom_path)
-
- config = ExcelReaderConfig(
- sheet_name="CustomSheet",
- source_header="CustomHeader"
- )
- result = read_excel_data(custom_path, return_object=True, config=config)
- assert result.sheet_name == "CustomSheet"
- assert "signal1" in result.signals
\ No newline at end of file