mirror of
https://github.com/KenanZhu/AutoLibrary.git
synced 2026-06-17 23:13:03 +08:00
feat(gui): 编辑窗口支持调试运行与动态模拟目标数据输入
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,8 @@ __all__ = [
|
|||||||
"buildMockTargetData",
|
"buildMockTargetData",
|
||||||
"META_VARS",
|
"META_VARS",
|
||||||
"ALL_VARIABLES",
|
"ALL_VARIABLES",
|
||||||
|
"_TARGET_VAR_DEFS",
|
||||||
|
"_MOCK_TYPE_VALUES",
|
||||||
"ASTokenizer",
|
"ASTokenizer",
|
||||||
"Stmt",
|
"Stmt",
|
||||||
"Script",
|
"Script",
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ This software is provided "as is", without any warranty of any kind.
|
|||||||
You may use, modify, and distribute this file under the terms of the MIT License.
|
You may use, modify, and distribute this file under the terms of the MIT License.
|
||||||
See the LICENSE file for details.
|
See the LICENSE file for details.
|
||||||
"""
|
"""
|
||||||
from PySide6.QtCore import Qt, Slot
|
from copy import deepcopy
|
||||||
|
|
||||||
|
from PySide6.QtCore import QDate, Qt, QTime, QTimer, Slot
|
||||||
from PySide6.QtGui import (
|
from PySide6.QtGui import (
|
||||||
QColor,
|
QColor,
|
||||||
QFont,
|
QFont,
|
||||||
@@ -16,21 +18,40 @@ from PySide6.QtGui import (
|
|||||||
)
|
)
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QApplication,
|
QApplication,
|
||||||
|
QComboBox,
|
||||||
|
QDateEdit,
|
||||||
QDialog,
|
QDialog,
|
||||||
QDialogButtonBox,
|
QDialogButtonBox,
|
||||||
|
QDoubleSpinBox,
|
||||||
|
QFormLayout,
|
||||||
|
QFrame,
|
||||||
QGridLayout,
|
QGridLayout,
|
||||||
|
QGroupBox,
|
||||||
QHBoxLayout,
|
QHBoxLayout,
|
||||||
|
QHeaderView,
|
||||||
QLabel,
|
QLabel,
|
||||||
|
QLineEdit,
|
||||||
|
QMessageBox,
|
||||||
QPlainTextEdit,
|
QPlainTextEdit,
|
||||||
QPushButton,
|
QPushButton,
|
||||||
|
QSpinBox,
|
||||||
|
QSplitter,
|
||||||
QStyle,
|
QStyle,
|
||||||
QTabWidget,
|
QTabWidget,
|
||||||
|
QTableWidget,
|
||||||
|
QTableWidgetItem,
|
||||||
|
QTimeEdit,
|
||||||
QVBoxLayout,
|
QVBoxLayout,
|
||||||
QWidget,
|
QWidget,
|
||||||
)
|
)
|
||||||
|
|
||||||
from autoscript import ALL_VARIABLES
|
from autoscript import (
|
||||||
|
ALL_VARIABLES,
|
||||||
|
_MOCK_TYPE_VALUES,
|
||||||
|
_TARGET_VAR_DEFS,
|
||||||
|
execute,
|
||||||
|
registerDefaultTargetVars,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ALScriptHighlighter(QSyntaxHighlighter):
|
class ALScriptHighlighter(QSyntaxHighlighter):
|
||||||
@@ -99,16 +120,47 @@ class ALScriptHighlighter(QSyntaxHighlighter):
|
|||||||
self.setFormat(start, length, fmt)
|
self.setFormat(start, length, fmt)
|
||||||
|
|
||||||
|
|
||||||
|
class _DebugResultDialog(QDialog):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
changes: list,
|
||||||
|
parent = None
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setWindowTitle("调试运行结果 - AutoLibrary")
|
||||||
|
self.setMinimumSize(600, 200)
|
||||||
|
layout = QVBoxLayout(self)
|
||||||
|
table = QTableWidget(len(changes), 3)
|
||||||
|
table.setHorizontalHeaderLabels(["目标变量", "原始数据", "运行后数据"])
|
||||||
|
table.horizontalHeader().setStretchLastSection(True)
|
||||||
|
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
|
table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
|
||||||
|
for row, (display_name, name, var_type, before_val, after_val) in enumerate(changes):
|
||||||
|
label = f"{display_name}: {name}({var_type})"
|
||||||
|
table.setItem(row, 0, QTableWidgetItem(label))
|
||||||
|
table.setItem(row, 1, QTableWidgetItem(str(before_val)))
|
||||||
|
table.setItem(row, 2, QTableWidgetItem(str(after_val)))
|
||||||
|
layout.addWidget(table)
|
||||||
|
btnBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok)
|
||||||
|
btnBox.button(QDialogButtonBox.StandardButton.Ok).setText("确定")
|
||||||
|
btnBox.accepted.connect(self.accept)
|
||||||
|
layout.addWidget(btnBox)
|
||||||
|
|
||||||
|
|
||||||
class ALAutoScriptEditDialog(QDialog):
|
class ALAutoScriptEditDialog(QDialog):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
parent = None,
|
parent = None,
|
||||||
script: str = ""
|
script: str = "",
|
||||||
|
mockData: dict = None
|
||||||
):
|
):
|
||||||
|
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._fontSize = 19
|
self._fontSize = 19
|
||||||
|
self._mockWidgets = {}
|
||||||
|
|
||||||
self.setupUi()
|
self.setupUi()
|
||||||
self.connectSignals()
|
self.connectSignals()
|
||||||
@@ -116,6 +168,8 @@ class ALAutoScriptEditDialog(QDialog):
|
|||||||
self._highlighter = ALScriptHighlighter(
|
self._highlighter = ALScriptHighlighter(
|
||||||
self.textEdit.document()
|
self.textEdit.document()
|
||||||
)
|
)
|
||||||
|
if mockData:
|
||||||
|
self.setMockData(mockData)
|
||||||
|
|
||||||
|
|
||||||
def setupUi(
|
def setupUi(
|
||||||
@@ -123,10 +177,10 @@ class ALAutoScriptEditDialog(QDialog):
|
|||||||
):
|
):
|
||||||
|
|
||||||
self.setWindowTitle("AutoScript 编辑 - AutoLibrary")
|
self.setWindowTitle("AutoScript 编辑 - AutoLibrary")
|
||||||
self.setMinimumSize(640, 600)
|
self.setMinimumSize(660, 600)
|
||||||
layout = QVBoxLayout(self)
|
layout = QVBoxLayout(self)
|
||||||
layout.setSpacing(4)
|
layout.setSpacing(3)
|
||||||
layout.setContentsMargins(4, 4, 4, 4)
|
layout.setContentsMargins(3, 3, 3, 3)
|
||||||
toolbarLayout = QHBoxLayout()
|
toolbarLayout = QHBoxLayout()
|
||||||
self.zoomInBtn = QPushButton("+")
|
self.zoomInBtn = QPushButton("+")
|
||||||
self.zoomInBtn.setFixedSize(25, 25)
|
self.zoomInBtn.setFixedSize(25, 25)
|
||||||
@@ -141,6 +195,19 @@ class ALAutoScriptEditDialog(QDialog):
|
|||||||
self.zoomResetBtn.setToolTip("重置缩放")
|
self.zoomResetBtn.setToolTip("重置缩放")
|
||||||
self.zoomLabel = QLabel(f"{self._fontSize}px")
|
self.zoomLabel = QLabel(f"{self._fontSize}px")
|
||||||
self.zoomLabel.setFixedHeight(25)
|
self.zoomLabel.setFixedHeight(25)
|
||||||
|
self.orchBtn = QPushButton("编排")
|
||||||
|
self.orchBtn.setFixedHeight(25)
|
||||||
|
self.orchBtn.setToolTip("可视化生成 AutoScript 代码并插入到光标位置")
|
||||||
|
toolbarLayout.addWidget(self.orchBtn)
|
||||||
|
self.debugBtn = QPushButton("▶ 调试运行")
|
||||||
|
self.debugBtn.setFixedHeight(25)
|
||||||
|
self.debugBtn.setToolTip("使用右侧模拟数据执行脚本,查看目标变量变化")
|
||||||
|
toolbarLayout.addWidget(self.debugBtn)
|
||||||
|
sep = QFrame()
|
||||||
|
sep.setFrameShape(QFrame.Shape.VLine)
|
||||||
|
sep.setFrameShadow(QFrame.Shadow.Sunken)
|
||||||
|
sep.setFixedWidth(1)
|
||||||
|
toolbarLayout.addWidget(sep)
|
||||||
toolbarLayout.addWidget(self.zoomInBtn)
|
toolbarLayout.addWidget(self.zoomInBtn)
|
||||||
toolbarLayout.addWidget(self.zoomOutBtn)
|
toolbarLayout.addWidget(self.zoomOutBtn)
|
||||||
toolbarLayout.addWidget(self.zoomResetBtn)
|
toolbarLayout.addWidget(self.zoomResetBtn)
|
||||||
@@ -181,46 +248,38 @@ class ALAutoScriptEditDialog(QDialog):
|
|||||||
parent_layout
|
parent_layout
|
||||||
):
|
):
|
||||||
|
|
||||||
|
splitter = QSplitter(Qt.Orientation.Horizontal)
|
||||||
tab_widget = QTabWidget()
|
tabWidget = QTabWidget()
|
||||||
tab_widget.setMaximumHeight(200)
|
tabWidget.setMaximumHeight(150)
|
||||||
basic_widget = QWidget()
|
basicWidget = QWidget()
|
||||||
basic_layout = QGridLayout(basic_widget)
|
basicLayout = QGridLayout(basicWidget)
|
||||||
basic_layout.setSpacing(4)
|
basicLayout.setSpacing(4)
|
||||||
basic_layout.setContentsMargins(4, 4, 4, 4)
|
basicLayout.setContentsMargins(4, 4, 4, 4)
|
||||||
basic_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
basicLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
||||||
control_buttons = [
|
controlButtons = [
|
||||||
("IF", "IF()\n \nEND IF"),
|
("IF", "IF()\n \nEND IF"),
|
||||||
("ELSE IF", "ELSE IF()\n "),
|
("ELSE IF", "ELSE IF()\n "),
|
||||||
("ELSE", "ELSE"),
|
("ELSE", "ELSE"),
|
||||||
("END IF", "END IF"),
|
("END IF", "END IF"),
|
||||||
("PASS", "PASS"),
|
("PASS", "PASS"),
|
||||||
]
|
]
|
||||||
self._addButtonsToGrid(basic_layout, control_buttons, 0, 0, 5)
|
self._addButtonsToGrid(basicLayout, controlButtons, 0, 0, 5)
|
||||||
|
assignButtons = [
|
||||||
assign_buttons = [
|
|
||||||
("SET", "SET = "),
|
("SET", "SET = "),
|
||||||
]
|
]
|
||||||
self._addButtonsToGrid(basic_layout, assign_buttons, 0, 5, 1)
|
self._addButtonsToGrid(basicLayout, assignButtons, 0, 5, 1)
|
||||||
|
tabWidget.addTab(basicWidget, "基本语法")
|
||||||
func_buttons = [
|
operatorWidget = QWidget()
|
||||||
("DATE()", "DATE()"),
|
operatorLayout = QGridLayout(operatorWidget)
|
||||||
("TIME()", "TIME()"),
|
operatorLayout.setSpacing(4)
|
||||||
]
|
operatorLayout.setContentsMargins(4, 4, 4, 4)
|
||||||
self._addButtonsToGrid(basic_layout, func_buttons, 1, 0, 2)
|
operatorLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
||||||
|
arithmeticButtons = [
|
||||||
tab_widget.addTab(basic_widget, "基本语法")
|
|
||||||
operator_widget = QWidget()
|
|
||||||
operator_layout = QGridLayout(operator_widget)
|
|
||||||
operator_layout.setSpacing(4)
|
|
||||||
operator_layout.setContentsMargins(4, 4, 4, 4)
|
|
||||||
operator_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
|
||||||
arithmetic_buttons = [
|
|
||||||
(".ADD.", ".ADD."),
|
(".ADD.", ".ADD."),
|
||||||
(".SUB.", ".SUB."),
|
(".SUB.", ".SUB."),
|
||||||
]
|
]
|
||||||
self._addButtonsToGrid(operator_layout, arithmetic_buttons, 0, 0, 2)
|
self._addButtonsToGrid(operatorLayout, arithmeticButtons, 0, 0, 2)
|
||||||
compare_buttons = [
|
compareButtons = [
|
||||||
(".EQ.", ".EQ."),
|
(".EQ.", ".EQ."),
|
||||||
(".NEQ.", ".NEQ."),
|
(".NEQ.", ".NEQ."),
|
||||||
(".BGT.", ".BGT."),
|
(".BGT.", ".BGT."),
|
||||||
@@ -228,42 +287,54 @@ class ALAutoScriptEditDialog(QDialog):
|
|||||||
(".BGE.", ".BGE."),
|
(".BGE.", ".BGE."),
|
||||||
(".BLE.", ".BLE."),
|
(".BLE.", ".BLE."),
|
||||||
]
|
]
|
||||||
self._addButtonsToGrid(operator_layout, compare_buttons, 1, 0, 6)
|
self._addButtonsToGrid(operatorLayout, compareButtons, 1, 0, 6)
|
||||||
logic_buttons = [
|
logic_buttons = [
|
||||||
(".AND.", ".AND."),
|
(".AND.", ".AND."),
|
||||||
(".OR.", ".OR."),
|
(".OR.", ".OR."),
|
||||||
]
|
]
|
||||||
self._addButtonsToGrid(operator_layout, logic_buttons, 2, 0, 2)
|
self._addButtonsToGrid(operatorLayout, logic_buttons, 2, 0, 2)
|
||||||
tab_widget.addTab(operator_widget, "运算符")
|
tabWidget.addTab(operatorWidget, "运算符")
|
||||||
literal_widget = QWidget()
|
literalWidget = QWidget()
|
||||||
literal_layout = QGridLayout(literal_widget)
|
literalLayout = QGridLayout(literalWidget)
|
||||||
literal_layout.setSpacing(4)
|
literalLayout.setSpacing(4)
|
||||||
literal_layout.setContentsMargins(4, 4, 4, 4)
|
literalLayout.setContentsMargins(4, 4, 4, 4)
|
||||||
literal_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
literalLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
||||||
bool_buttons = [
|
bool_buttons = [
|
||||||
(".TRUE.", ".TRUE."),
|
(".TRUE.", ".TRUE."),
|
||||||
(".FALSE.", ".FALSE."),
|
(".FALSE.", ".FALSE."),
|
||||||
]
|
]
|
||||||
self._addButtonsToGrid(literal_layout, bool_buttons, 0, 0, 2)
|
self._addButtonsToGrid(literalLayout, bool_buttons, 0, 0, 2)
|
||||||
hint_buttons = [
|
dateTimeButtons = [
|
||||||
("字符串", "'文本'"),
|
("DATE()", "DATE(2025-01-01)"),
|
||||||
("数字", "123"),
|
("TIME()", "TIME(00:00)"),
|
||||||
("注释", "// 注释"),
|
|
||||||
]
|
]
|
||||||
self._addButtonsToGrid(literal_layout, hint_buttons, 1, 0, 3)
|
self._addButtonsToGrid(literalLayout, dateTimeButtons, 1, 0, 2)
|
||||||
tab_widget.addTab(literal_widget, "字面量")
|
hintButtons = [
|
||||||
var_widget = QWidget()
|
("字符串", "'请输入文本'"),
|
||||||
var_layout = QGridLayout(var_widget)
|
("数字", "123"),
|
||||||
var_layout.setSpacing(4)
|
("注释", "// 请输入注释"),
|
||||||
var_layout.setContentsMargins(4, 4, 4, 4)
|
]
|
||||||
var_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
self._addButtonsToGrid(literalLayout, hintButtons, 2, 0, 3)
|
||||||
var_buttons = [
|
tabWidget.addTab(literalWidget, "字面量")
|
||||||
|
varWidget = QWidget()
|
||||||
|
varLayout = QGridLayout(varWidget)
|
||||||
|
varLayout.setSpacing(4)
|
||||||
|
varLayout.setContentsMargins(4, 4, 4, 4)
|
||||||
|
varLayout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
|
||||||
|
varButtons = [
|
||||||
(display_name, name) for display_name, (name, _) in ALL_VARIABLES.items()
|
(display_name, name) for display_name, (name, _) in ALL_VARIABLES.items()
|
||||||
]
|
]
|
||||||
|
|
||||||
self._addButtonsToGrid(var_layout, var_buttons, 0, 0, 5)
|
self._addButtonsToGrid(varLayout, varButtons, 0, 0, 5)
|
||||||
tab_widget.addTab(var_widget, "变量")
|
tabWidget.addTab(varWidget, "变量")
|
||||||
parent_layout.addWidget(tab_widget)
|
mockPanel = self._createMockPanel()
|
||||||
|
mockPanel.setMinimumWidth(260)
|
||||||
|
splitter.addWidget(tabWidget)
|
||||||
|
splitter.addWidget(mockPanel)
|
||||||
|
splitter.setStretchFactor(0, 1)
|
||||||
|
splitter.setStretchFactor(1, 0)
|
||||||
|
splitter.setSizes([660, 400])
|
||||||
|
parent_layout.addWidget(splitter)
|
||||||
|
|
||||||
|
|
||||||
def _addButtonsToGrid(
|
def _addButtonsToGrid(
|
||||||
@@ -283,7 +354,7 @@ class ALAutoScriptEditDialog(QDialog):
|
|||||||
btn.setProperty("template", template)
|
btn.setProperty("template", template)
|
||||||
btn.clicked.connect(self._insertTemplate)
|
btn.clicked.connect(self._insertTemplate)
|
||||||
btn.setFixedWidth(100)
|
btn.setFixedWidth(100)
|
||||||
btn.setFixedHeight(30)
|
btn.setFixedHeight(25)
|
||||||
btn.setToolTip(f"插入: {template}")
|
btn.setToolTip(f"插入: {template}")
|
||||||
grid_layout.addWidget(btn, row, col)
|
grid_layout.addWidget(btn, row, col)
|
||||||
|
|
||||||
@@ -307,12 +378,186 @@ class ALAutoScriptEditDialog(QDialog):
|
|||||||
cursor.insertText(template)
|
cursor.insertText(template)
|
||||||
|
|
||||||
|
|
||||||
|
def _createMockPanel(
|
||||||
|
self
|
||||||
|
) -> QGroupBox:
|
||||||
|
|
||||||
|
group = QGroupBox("模拟目标数据")
|
||||||
|
form = QFormLayout(group)
|
||||||
|
form.setSpacing(4)
|
||||||
|
form.setContentsMargins(5, 10, 5, 5)
|
||||||
|
self._mockWidgets = {}
|
||||||
|
for name, var_type, key_path, display_name in _TARGET_VAR_DEFS:
|
||||||
|
default = _MOCK_TYPE_VALUES.get(var_type, "")
|
||||||
|
widget = self._makeMockInput(var_type, default)
|
||||||
|
label = QLabel(f"{display_name}: {name}({var_type})")
|
||||||
|
form.addRow(label, widget)
|
||||||
|
self._mockWidgets[name] = (widget, var_type, key_path)
|
||||||
|
return group
|
||||||
|
|
||||||
|
|
||||||
|
def _makeMockInput(
|
||||||
|
self,
|
||||||
|
var_type: str,
|
||||||
|
default
|
||||||
|
) -> QWidget:
|
||||||
|
|
||||||
|
if var_type == "String":
|
||||||
|
w = QLineEdit()
|
||||||
|
w.setText(str(default))
|
||||||
|
return w
|
||||||
|
if var_type == "Boolean":
|
||||||
|
w = QComboBox()
|
||||||
|
w.addItems(["是", "否"])
|
||||||
|
w.setCurrentIndex(0 if default else 1)
|
||||||
|
return w
|
||||||
|
if var_type == "Date":
|
||||||
|
w = QDateEdit()
|
||||||
|
w.setCalendarPopup(True)
|
||||||
|
w.setDisplayFormat("yyyy-MM-dd")
|
||||||
|
w.setDate(QDate.fromString(str(default), "yyyy-MM-dd"))
|
||||||
|
return w
|
||||||
|
if var_type == "Time":
|
||||||
|
w = QTimeEdit()
|
||||||
|
w.setDisplayFormat("HH:mm")
|
||||||
|
w.setTime(QTime.fromString(str(default), "HH:mm"))
|
||||||
|
return w
|
||||||
|
if var_type == "Int":
|
||||||
|
w = QSpinBox()
|
||||||
|
w.setMinimum(-999999)
|
||||||
|
w.setMaximum(999999)
|
||||||
|
w.setValue(int(default) if default else 0)
|
||||||
|
return w
|
||||||
|
if var_type == "Float":
|
||||||
|
w = QDoubleSpinBox()
|
||||||
|
w.setMinimum(-999999.0)
|
||||||
|
w.setMaximum(999999.0)
|
||||||
|
w.setDecimals(2)
|
||||||
|
w.setValue(float(default) if default else 0.0)
|
||||||
|
return w
|
||||||
|
w = QLineEdit()
|
||||||
|
w.setText(str(default))
|
||||||
|
return w
|
||||||
|
|
||||||
|
|
||||||
|
def getMockData(
|
||||||
|
self
|
||||||
|
) -> dict:
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
for name, var_type, key_path, display_name in _TARGET_VAR_DEFS:
|
||||||
|
widget, _, _ = self._mockWidgets[name]
|
||||||
|
value = self._getMockValue(widget, var_type)
|
||||||
|
d = data
|
||||||
|
for key in key_path[:-1]:
|
||||||
|
d = d.setdefault(key, {})
|
||||||
|
d[key_path[-1]] = value
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def setMockData(
|
||||||
|
self,
|
||||||
|
data: dict
|
||||||
|
):
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
for name, var_type, key_path, display_name in _TARGET_VAR_DEFS:
|
||||||
|
d = data
|
||||||
|
try:
|
||||||
|
for key in key_path:
|
||||||
|
d = d[key]
|
||||||
|
except (KeyError, TypeError):
|
||||||
|
continue
|
||||||
|
widget, _, _ = self._mockWidgets[name]
|
||||||
|
self._setMockValue(widget, var_type, d)
|
||||||
|
|
||||||
|
|
||||||
|
def _getMockValue(
|
||||||
|
self,
|
||||||
|
widget: QWidget,
|
||||||
|
var_type: str
|
||||||
|
):
|
||||||
|
|
||||||
|
if var_type == "Boolean":
|
||||||
|
return widget.currentIndex() == 0
|
||||||
|
if var_type == "Date":
|
||||||
|
return widget.date().toString("yyyy-MM-dd")
|
||||||
|
if var_type == "Time":
|
||||||
|
return widget.time().toString("HH:mm")
|
||||||
|
if var_type == "Int":
|
||||||
|
return widget.value()
|
||||||
|
if var_type == "Float":
|
||||||
|
return widget.value()
|
||||||
|
return widget.text()
|
||||||
|
|
||||||
|
|
||||||
|
def _setMockValue(
|
||||||
|
self,
|
||||||
|
widget: QWidget,
|
||||||
|
var_type: str,
|
||||||
|
value
|
||||||
|
):
|
||||||
|
|
||||||
|
if var_type == "Boolean":
|
||||||
|
widget.setCurrentIndex(0 if value else 1)
|
||||||
|
elif var_type == "Date":
|
||||||
|
widget.setDate(QDate.fromString(str(value), "yyyy-MM-dd"))
|
||||||
|
elif var_type == "Time":
|
||||||
|
widget.setTime(QTime.fromString(str(value), "HH:mm"))
|
||||||
|
elif var_type == "Int":
|
||||||
|
widget.setValue(int(value))
|
||||||
|
elif var_type == "Float":
|
||||||
|
widget.setValue(float(value))
|
||||||
|
else:
|
||||||
|
widget.setText(str(value))
|
||||||
|
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def onDebugRun(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
script = self.textEdit.toPlainText().strip()
|
||||||
|
if not script:
|
||||||
|
QMessageBox.warning(self, "提示", "脚本内容为空。")
|
||||||
|
return
|
||||||
|
target_data = self.getMockData()
|
||||||
|
before = deepcopy(target_data)
|
||||||
|
try:
|
||||||
|
registerDefaultTargetVars()
|
||||||
|
execute(script, target_data)
|
||||||
|
except ValueError as e:
|
||||||
|
QMessageBox.warning(self, "运行错误", str(e))
|
||||||
|
return
|
||||||
|
changes = []
|
||||||
|
for name, var_type, key_path, display_name in _TARGET_VAR_DEFS:
|
||||||
|
before_val = before
|
||||||
|
after_val = target_data
|
||||||
|
try:
|
||||||
|
for key in key_path:
|
||||||
|
before_val = before_val[key]
|
||||||
|
after_val = after_val[key]
|
||||||
|
except (KeyError, TypeError):
|
||||||
|
continue
|
||||||
|
if before_val != after_val:
|
||||||
|
changes.append((display_name, name, var_type, before_val, after_val))
|
||||||
|
if not changes:
|
||||||
|
QMessageBox.information(self, "调试运行", "目标变量未发生变化。")
|
||||||
|
return
|
||||||
|
dlg = _DebugResultDialog(changes, self)
|
||||||
|
dlg.exec()
|
||||||
|
dlg.deleteLater()
|
||||||
|
|
||||||
|
|
||||||
def connectSignals(
|
def connectSignals(
|
||||||
self
|
self
|
||||||
):
|
):
|
||||||
|
|
||||||
self.btnBox.accepted.connect(self.accept)
|
self.btnBox.accepted.connect(self.accept)
|
||||||
self.btnBox.rejected.connect(self.reject)
|
self.btnBox.rejected.connect(self.reject)
|
||||||
|
self.orchBtn.clicked.connect(self.onOpenOrchDialog)
|
||||||
|
self.debugBtn.clicked.connect(self.onDebugRun)
|
||||||
self.zoomInBtn.clicked.connect(self.onZoomIn)
|
self.zoomInBtn.clicked.connect(self.onZoomIn)
|
||||||
self.zoomOutBtn.clicked.connect(self.onZoomOut)
|
self.zoomOutBtn.clicked.connect(self.onZoomOut)
|
||||||
self.zoomResetBtn.clicked.connect(self.onZoomReset)
|
self.zoomResetBtn.clicked.connect(self.onZoomReset)
|
||||||
@@ -375,8 +620,21 @@ class ALAutoScriptEditDialog(QDialog):
|
|||||||
original = self.copyBtn.text()
|
original = self.copyBtn.text()
|
||||||
self.copyBtn.setText("已复制")
|
self.copyBtn.setText("已复制")
|
||||||
self.copyBtn.setEnabled(False)
|
self.copyBtn.setEnabled(False)
|
||||||
from PySide6.QtCore import QTimer
|
|
||||||
QTimer.singleShot(2000, lambda: (
|
QTimer.singleShot(2000, lambda: (
|
||||||
self.copyBtn.setText(original),
|
self.copyBtn.setText(original),
|
||||||
self.copyBtn.setEnabled(True)
|
self.copyBtn.setEnabled(True)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def onOpenOrchDialog(
|
||||||
|
self
|
||||||
|
):
|
||||||
|
|
||||||
|
from gui.ALAutoScriptOrchDialog import ALAutoScriptOrchDialog
|
||||||
|
dlg = ALAutoScriptOrchDialog(self)
|
||||||
|
if dlg.exec() == QDialog.DialogCode.Accepted:
|
||||||
|
script = dlg.getScript()
|
||||||
|
if script:
|
||||||
|
cursor = self.textEdit.textCursor()
|
||||||
|
cursor.insertText(script)
|
||||||
|
dlg.deleteLater()
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ from PySide6.QtGui import QDesktopServices
|
|||||||
from PySide6.QtWidgets import QLabel, QDialog, QWidget, QSpinBox, QHBoxLayout, QVBoxLayout, QGridLayout, QDateTimeEdit, QGroupBox, QPushButton
|
from PySide6.QtWidgets import QLabel, QDialog, QWidget, QSpinBox, QHBoxLayout, QVBoxLayout, QGridLayout, QDateTimeEdit, QGroupBox, QPushButton
|
||||||
|
|
||||||
from gui.resources.ui.Ui_ALTimerTaskAddDialog import Ui_ALTimerTaskAddDialog
|
from gui.resources.ui.Ui_ALTimerTaskAddDialog import Ui_ALTimerTaskAddDialog
|
||||||
from gui.ALAutoScriptOrchDialog import ALAutoScriptOrchDialog
|
|
||||||
from utils.TimerUtils import TimerUtils
|
from utils.TimerUtils import TimerUtils
|
||||||
|
|
||||||
|
|
||||||
@@ -102,10 +101,6 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
|||||||
self.AutoScriptLayout.setContentsMargins(3, 3, 3, 3)
|
self.AutoScriptLayout.setContentsMargins(3, 3, 3, 3)
|
||||||
self.AutoScriptLayout.setSpacing(3)
|
self.AutoScriptLayout.setSpacing(3)
|
||||||
autoScriptBtnLayout = QHBoxLayout()
|
autoScriptBtnLayout = QHBoxLayout()
|
||||||
self.AutoScriptSetButton = QPushButton("设置指令")
|
|
||||||
self.AutoScriptSetButton.setMinimumHeight(25)
|
|
||||||
self.AutoScriptSetButton.setFixedWidth(130)
|
|
||||||
autoScriptBtnLayout.addWidget(self.AutoScriptSetButton)
|
|
||||||
self.AutoScriptPreviewButton = QPushButton("编辑")
|
self.AutoScriptPreviewButton = QPushButton("编辑")
|
||||||
self.AutoScriptPreviewButton.setMinimumHeight(25)
|
self.AutoScriptPreviewButton.setMinimumHeight(25)
|
||||||
self.AutoScriptPreviewButton.setFixedWidth(60)
|
self.AutoScriptPreviewButton.setFixedWidth(60)
|
||||||
@@ -136,6 +131,7 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
|||||||
)
|
)
|
||||||
self.AutoScriptGroupBox.setVisible(False)
|
self.AutoScriptGroupBox.setVisible(False)
|
||||||
self.__auto_script = ""
|
self.__auto_script = ""
|
||||||
|
self.__mock_target_data = None
|
||||||
|
|
||||||
|
|
||||||
def loadTask(
|
def loadTask(
|
||||||
@@ -173,6 +169,9 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
|||||||
self.__auto_script = auto_script
|
self.__auto_script = auto_script
|
||||||
self.AutoScriptStatusLabel.setText("已设置")
|
self.AutoScriptStatusLabel.setText("已设置")
|
||||||
self.AutoScriptStatusLabel.setStyleSheet("color: #4CAF50;")
|
self.AutoScriptStatusLabel.setStyleSheet("color: #4CAF50;")
|
||||||
|
mock_data = task.get("mock_target_data")
|
||||||
|
if mock_data:
|
||||||
|
self.__mock_target_data = mock_data
|
||||||
self.ConfirmButton.setText("保存")
|
self.ConfirmButton.setText("保存")
|
||||||
|
|
||||||
|
|
||||||
@@ -184,7 +183,6 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
|||||||
self.ConfirmButton.clicked.connect(self.accept)
|
self.ConfirmButton.clicked.connect(self.accept)
|
||||||
self.TimerTypeComboBox.currentIndexChanged.connect(self.onTimerTypeComboBoxIndexChanged)
|
self.TimerTypeComboBox.currentIndexChanged.connect(self.onTimerTypeComboBoxIndexChanged)
|
||||||
self.RepeatCheckBox.toggled.connect(self.onRepeatCheckBoxToggled)
|
self.RepeatCheckBox.toggled.connect(self.onRepeatCheckBoxToggled)
|
||||||
self.AutoScriptSetButton.clicked.connect(self.onSetAutoScript)
|
|
||||||
self.AutoScriptPreviewButton.clicked.connect(self.onPreviewAutoScript)
|
self.AutoScriptPreviewButton.clicked.connect(self.onPreviewAutoScript)
|
||||||
self.AutoScriptHelpButton.clicked.connect(self.onAutoScriptHelp)
|
self.AutoScriptHelpButton.clicked.connect(self.onAutoScriptHelp)
|
||||||
|
|
||||||
@@ -220,6 +218,7 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
|||||||
task_data["status"] = ALTimerTaskStatus.PENDING
|
task_data["status"] = ALTimerTaskStatus.PENDING
|
||||||
task_data["executed"] = False
|
task_data["executed"] = False
|
||||||
task_data["repeat_auto_script"] = self.__auto_script
|
task_data["repeat_auto_script"] = self.__auto_script
|
||||||
|
task_data["mock_target_data"] = self.__mock_target_data
|
||||||
else:
|
else:
|
||||||
task_data = {
|
task_data = {
|
||||||
"name": name,
|
"name": name,
|
||||||
@@ -232,6 +231,7 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
|||||||
"executed": False,
|
"executed": False,
|
||||||
"repeat": self.RepeatCheckBox.isChecked(),
|
"repeat": self.RepeatCheckBox.isChecked(),
|
||||||
"repeat_auto_script": self.__auto_script,
|
"repeat_auto_script": self.__auto_script,
|
||||||
|
"mock_target_data": self.__mock_target_data,
|
||||||
}
|
}
|
||||||
|
|
||||||
repeat = self.RepeatCheckBox.isChecked()
|
repeat = self.RepeatCheckBox.isChecked()
|
||||||
@@ -292,27 +292,14 @@ class ALTimerTaskAddDialog(QDialog, Ui_ALTimerTaskAddDialog):
|
|||||||
self.SunCheckBox.setEnabled(checked)
|
self.SunCheckBox.setEnabled(checked)
|
||||||
self.AutoScriptGroupBox.setVisible(checked)
|
self.AutoScriptGroupBox.setVisible(checked)
|
||||||
|
|
||||||
@Slot()
|
|
||||||
def onSetAutoScript(self):
|
|
||||||
dlg = ALAutoScriptOrchDialog(self, existingScript=self.__auto_script)
|
|
||||||
if dlg.exec() == QDialog.DialogCode.Accepted:
|
|
||||||
script = dlg.getScript()
|
|
||||||
self.__auto_script = script
|
|
||||||
if script:
|
|
||||||
self.AutoScriptStatusLabel.setText("已设置")
|
|
||||||
self.AutoScriptStatusLabel.setStyleSheet("color: #4CAF50;")
|
|
||||||
else:
|
|
||||||
self.AutoScriptStatusLabel.setText("未设置")
|
|
||||||
self.AutoScriptStatusLabel.setStyleSheet("color: #969696;")
|
|
||||||
dlg.deleteLater()
|
|
||||||
|
|
||||||
@Slot()
|
@Slot()
|
||||||
def onPreviewAutoScript(self):
|
def onPreviewAutoScript(self):
|
||||||
from gui.ALAutoScriptEditDialog import ALAutoScriptEditDialog
|
from gui.ALAutoScriptEditDialog import ALAutoScriptEditDialog
|
||||||
dlg = ALAutoScriptEditDialog(self, self.__auto_script)
|
dlg = ALAutoScriptEditDialog(self, self.__auto_script, self.__mock_target_data)
|
||||||
if dlg.exec() == QDialog.DialogCode.Accepted:
|
if dlg.exec() == QDialog.DialogCode.Accepted:
|
||||||
script = dlg.getScript()
|
script = dlg.getScript()
|
||||||
self.__auto_script = script
|
self.__auto_script = script
|
||||||
|
self.__mock_target_data = dlg.getMockData()
|
||||||
if script:
|
if script:
|
||||||
self.AutoScriptStatusLabel.setText("已设置")
|
self.AutoScriptStatusLabel.setText("已设置")
|
||||||
self.AutoScriptStatusLabel.setStyleSheet("color: #4CAF50;")
|
self.AutoScriptStatusLabel.setStyleSheet("color: #4CAF50;")
|
||||||
|
|||||||
Reference in New Issue
Block a user