submit 0421

main
COT001\DEV 2026-04-21 13:28:01 +08:00
parent 97dee8326b
commit 596f1b9673
12 changed files with 94 additions and 40 deletions

View File

@ -4,7 +4,9 @@
"Bash(python3 -c ' *)", "Bash(python3 -c ' *)",
"Bash(sqlite3 data.db \"PRAGMA table_info\\(task_instruction\\);\")", "Bash(sqlite3 data.db \"PRAGMA table_info\\(task_instruction\\);\")",
"Bash(venv/Scripts/python.exe -c ' *)", "Bash(venv/Scripts/python.exe -c ' *)",
"Bash(venv/Scripts/python.exe -c \"import py_compile; py_compile.compile\\('taskForm.py', doraise=True\\)\")" "Bash(venv/Scripts/python.exe -c \"import py_compile; py_compile.compile\\('taskForm.py', doraise=True\\)\")",
"Bash(venv/Scripts/pip list *)",
"Bash(venv/Scripts/pip install *)"
] ]
} }
} }

View File

@ -432,6 +432,7 @@ class Common(QObject):
self.scanfResult = msg self.scanfResult = msg
@pyqtSlot(str,str,str,str, result=bool) @pyqtSlot(str,str,str,str, result=bool)
@pyqtSlot(str, str, str, str, result=bool)
def initAppScript(self, appId, instancName, scriptFile, plusFile="plus"): def initAppScript(self, appId, instancName, scriptFile, plusFile="plus"):
try: try:
if dog.isDogAlive() == 1 or suDog.isDogAlive() == 1: if dog.isDogAlive() == 1 or suDog.isDogAlive() == 1:
@ -447,6 +448,10 @@ class Common(QObject):
print(e) print(e)
return False return False
@pyqtSlot(str, result=QVariant)
def getScript(self, name):
return self.qscript.get(name, None)
@pyqtSlot(str,str,str,str,str, result=bool) @pyqtSlot(str,str,str,str,str, result=bool)
def registAppQml(self, appId, instancName, className, scriptFile, plusFile="plus"): def registAppQml(self, appId, instancName, className, scriptFile, plusFile="plus"):
try: try:
@ -915,6 +920,24 @@ class Common(QObject):
# export_table_structure_and_data('data.db', 'task_group') # export_table_structure_and_data('data.db', 'task_group')
# export_table_structure_and_data('data.db', 'task_instruction') # export_table_structure_and_data('data.db', 'task_instruction')
# 导入表结构和数据 # 导入表结构和数据
@pyqtSlot(str, result=str)
def readLogFile(self, file_path):
try:
with open(file_path, 'r', encoding='utf-8') as f:
return f.read()
except Exception as e:
return f"Error reading file {file_path}: {e}"
@pyqtSlot(str, result=list)
def getTxtFiles(self, directory):
try:
path = directory.replace("file:///", "")
if not os.path.exists(path):
return []
return [os.path.join(path, f) for f in sorted(os.listdir(path)) if os.path.isfile(os.path.join(path, f))]
except Exception:
return []
def migrate_sql_to_database(self, db_path, table_name): def migrate_sql_to_database(self, db_path, table_name):
import stat import stat
try: try:

View File

@ -94,7 +94,7 @@ class SessionSerial(SessionAbstract):
self.thread = QThread() self.thread = QThread()
self.worker.moveToThread(self.thread) self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.start) self.thread.started.connect(self.worker.start)
self.worker.newDataArrive.connect(self.onNewDataArrive) self.worker.newDataArrive.connect(self.onNewDataArrive, type=Qt.ConnectionType.DirectConnection)
self.worker.connectSuccess.connect(self.onConnectSuccess) self.worker.connectSuccess.connect(self.onConnectSuccess)
self.worker.connectClosed.connect(self.onConnectClosed) self.worker.connectClosed.connect(self.onConnectClosed)
self.worker.connectFailed.connect(self.onConnectFailed) self.worker.connectFailed.connect(self.onConnectFailed)

View File

@ -81,7 +81,7 @@ class SessionTbus(SessionAbstract):
self.thread = QThread() self.thread = QThread()
self.worker.moveToThread(self.thread) self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.start) self.thread.started.connect(self.worker.start)
self.worker.newDataArrive.connect(self.onNewDataArrive) self.worker.newDataArrive.connect(self.onNewDataArrive, type=Qt.ConnectionType.DirectConnection)
self.worker.connectSuccess.connect(self.onConnectSuccess) self.worker.connectSuccess.connect(self.onConnectSuccess)
self.worker.connectClosed.connect(self.onConnectClosed) self.worker.connectClosed.connect(self.onConnectClosed)
self.worker.connectFailed.connect(self.onConnectFailed) self.worker.connectFailed.connect(self.onConnectFailed)

View File

@ -82,7 +82,7 @@ class SessionTbusNs(SessionAbstract):
self.thread = QThread() self.thread = QThread()
self.worker.moveToThread(self.thread) self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.start) self.thread.started.connect(self.worker.start)
self.worker.newDataArrive.connect(self.onNewDataArrive) self.worker.newDataArrive.connect(self.onNewDataArrive, type=Qt.ConnectionType.DirectConnection)
self.worker.connectSuccess.connect(self.onConnectSuccess) self.worker.connectSuccess.connect(self.onConnectSuccess)
self.worker.connectClosed.connect(self.onConnectClosed) self.worker.connectClosed.connect(self.onConnectClosed)
self.worker.connectFailed.connect(self.onConnectFailed) self.worker.connectFailed.connect(self.onConnectFailed)

View File

@ -104,7 +104,7 @@ class MainWindow(QMainWindow):
self.ui = Ui_MainWindow() self.ui = Ui_MainWindow()
self.ui.setupUi(self) self.ui.setupUi(self)
self.ui.tbDefault.setVisible(False) self.ui.tbDefault.setVisible(False)
self.isDebugQML = False #DEBUG self.isDebugQML = True #DEBUG
self.setWindowTitle("TG-TestingPlatform "+app_version.data["version"]) self.setWindowTitle("TG-TestingPlatform "+app_version.data["version"])
self.ui.lbtitle.setText("TG-TestingPlatform "+app_version.data["version"]) self.ui.lbtitle.setText("TG-TestingPlatform "+app_version.data["version"])
self.ui.logWidget.setVisible(True) self.ui.logWidget.setVisible(True)
@ -234,7 +234,6 @@ class MainWindow(QMainWindow):
self.ui.quickTaskbar.setSource(QUrl(common.firstPath()+"/TaskBar.qml")) self.ui.quickTaskbar.setSource(QUrl(common.firstPath()+"/TaskBar.qml"))
self.ui.quickStackView.setSource(QUrl(common.firstPath()+"/main.qml")) self.ui.quickStackView.setSource(QUrl(common.firstPath()+"/main.qml"))
self.ui.quickSetting.setSource(QUrl(common.firstPath()+"/SettingView.qml")) self.ui.quickSetting.setSource(QUrl(common.firstPath()+"/SettingView.qml"))
if self.isDebugQML: if self.isDebugQML:
self.setDebugQML() self.setDebugQML()
@ -249,7 +248,7 @@ class MainWindow(QMainWindow):
self.ui.quickDebug.rootContext().setContextProperty("taskManager", taskManager) self.ui.quickDebug.rootContext().setContextProperty("taskManager", taskManager)
self.ui.quickDebug.rootContext().setContextProperty("interfaceManager", interfaceManager) self.ui.quickDebug.rootContext().setContextProperty("interfaceManager", interfaceManager)
self.ui.quickDebug.rootContext().setContextProperty("common", common) self.ui.quickDebug.rootContext().setContextProperty("common", common)
self.ui.quickDebug.setSource(QUrl(common.firstPath()+"/debug/gviewer/main.qml")) self.ui.quickDebug.setSource(QUrl(common.firstPath()+"/debug/calibrate/main.qml"))
def clearContextProperties(self): def clearContextProperties(self):
# 清除QML引擎缓存 # 清除QML引擎缓存

View File

@ -15,6 +15,7 @@ Rectangle
property var g_sn: "8441" property var g_sn: "8441"
property var appPath: "/"+plusFile+"/"+appId+"/" property var appPath: "/"+plusFile+"/"+appId+"/"
property var firstPath: "" property var firstPath: ""
property var calibrate: null
property var startDate: new Date() property var startDate: new Date()
property var startTime: startDate.getTime() property var startTime: startDate.getTime()
property var endTime: startDate.getTime() property var endTime: startDate.getTime()
@ -54,6 +55,7 @@ Rectangle
firstPath = common.firstPath() firstPath = common.firstPath()
g_user = common.getCurrentUser() g_user = common.getCurrentUser()
common.initAppScript(appId, "calibrate", "calibrate.py", plusFile) common.initAppScript(appId, "calibrate", "calibrate.py", plusFile)
calibrate = common.getScript("calibrate")
setConfigInfo() setConfigInfo()
calibrate.startShima(firstPath + appPath) calibrate.startShima(firstPath + appPath)
} }

View File

@ -5,8 +5,6 @@ import QtQuick.Dialogs
// import QtQuick.Controls. // import QtQuick.Controls.
import "./app.js" as App import "./app.js" as App
import "./common" import "./common"
import Qt.labs.folderlistmodel
Rectangle { Rectangle {
id: root id: root
radius: 9 radius: 9

View File

@ -5,7 +5,6 @@ import QtQuick.Dialogs
// import QtQuick.Controls. // import QtQuick.Controls.
import "./app.js" as App import "./app.js" as App
import "./common" import "./common"
import Qt.labs.folderlistmodel
Rectangle { Rectangle {
id: root id: root
@ -55,6 +54,24 @@ Rectangle {
GradientStop { position: 1.0; color: "#b7d6fb" } GradientStop { position: 1.0; color: "#b7d6fb" }
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
} }
ListModel { id: fileListModel }
function refreshFileList() {
fileListModel.clear()
if (logDirectory) {
var files = common.getTxtFiles(logDirectory)
for (var i = 0; i < files.length; i++) {
var fp = files[i].toString()
fileListModel.append({
"fileName": fp.substring(fp.lastIndexOf('/') + 1).replace(/\\/g, '/').split('/').pop(),
"filePath": fp
})
}
}
}
onLogDirectoryChanged: { refreshFileList() }
ListModel{ ListModel{
id: logModel id: logModel
} }
@ -138,24 +155,16 @@ Rectangle {
boundsBehavior: Flickable.StopAtBounds boundsBehavior: Flickable.StopAtBounds
ScrollBar.vertical: ScrollBar{} ScrollBar.vertical: ScrollBar{}
anchors.margins: 5 anchors.margins: 5
model: FolderListModel { model: fileListModel
id: folderModel
rootFolder: logDirectory
showDirsFirst: true
showFiles: true
folder: logDirectory //
}
delegate: ItemDelegate { delegate: ItemDelegate {
text: model.fileName text: model.fileName
icon.source: "resource/file.svg" icon.source: "resource/file.svg"
background: Rectangle { background: Rectangle {
color: fileSystemView.currentIndex == index ? "#D9D9D9" : "white" color: fileSystemView.currentIndex == index ? "#D9D9D9" : "white"
// ...
} }
onClicked: { onClicked: {
console.info("Clicked on: " + model.fileName)
currentLogfilePath = model.filePath currentLogfilePath = model.filePath
currentLogResult = log_processor.read_file(currentLogfilePath) currentLogResult = common.readLogFile(currentLogfilePath)
updateLogDisplay() updateLogDisplay()
fileSystemView.currentIndex = index fileSystemView.currentIndex = index
} }

View File

@ -565,8 +565,8 @@ class TaskForm(QWidget):
row_id_index = self.taskGroupModel.index(row, 0, QModelIndex()) row_id_index = self.taskGroupModel.index(row, 0, QModelIndex())
group_id = self.taskGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole) group_id = self.taskGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole)
self.current_groupId = group_id self.current_groupId = group_id
self.loadTask()
self.clearChildrenModel() self.clearChildrenModel()
QTimer.singleShot(0, self.loadTask)
#任务列表选中 #任务列表选中
def handleTaskSelection(self, index): def handleTaskSelection(self, index):
@ -955,6 +955,9 @@ class TaskForm(QWidget):
if str(taskId) == str(obj.get('task_instruction_id')): if str(taskId) == str(obj.get('task_instruction_id')):
self.taskModelBlockSignals = True self.taskModelBlockSignals = True
item.setData({'value': value, 'maximum': maxValue, 'task_instruction_id': obj.get('task_instruction_id'), 'name': obj.get('name')}, Qt.ItemDataRole.UserRole) item.setData({'value': value, 'maximum': maxValue, 'task_instruction_id': obj.get('task_instruction_id'), 'name': obj.get('name')}, Qt.ItemDataRole.UserRole)
self.taskModelBlockSignals = False
self.ui.tableViewTask.viewport().update()
return
def _onTaskStop(self, taskId): def _onTaskStop(self, taskId):
"""任务停止时清理缓存和进度显示""" """任务停止时清理缓存和进度显示"""
taskId = str(taskId) taskId = str(taskId)

View File

@ -87,7 +87,7 @@ class TaskActuator(QThread):
loop = int(self.taskInfo.get("loop", 1)) loop = int(self.taskInfo.get("loop", 1))
delay = float(int(self.taskInfo.get("delay",0))/1000) delay = float(int(self.taskInfo.get("delay",0))/1000)
taskIndex = 0 taskIndex = 0
total = instructionListLength * loop total = instructionListLength * loop if loop > 0 else instructionListLength
self.updateProgress.emit(self.id, 0, total) self.updateProgress.emit(self.id, 0, total)
self.updateDetails.emit(self.id, 0, total) self.updateDetails.emit(self.id, 0, total)
self.updateDetails.emit(self.parentId, 0, total) self.updateDetails.emit(self.parentId, 0, total)

View File

@ -11,6 +11,30 @@ from taskInstructionModel.taskInstructionManager import taskInstructionManager
from taskModel.taskManager import taskManager from taskModel.taskManager import taskManager
from common import common from common import common
class _KillThread(QThread):
done = pyqtSignal(object) # 传 actuator 回主线程处理
def __init__(self, actuator):
super().__init__()
self.actuator = actuator
self.finished.connect(self.deleteLater)
def run(self):
a = self.actuator
if not a.wait(500):
for item in a.instructionList:
try:
iface = item.get("interface")
if iface:
from interfaceSession.interfaceManager import interfaceManager
interfaceManager.getSession(iface).unlock()
except Exception:
pass
a.terminate()
a.wait(200)
self.done.emit(a)
class TaskActuatorManager(QObject): class TaskActuatorManager(QObject):
logMsg = pyqtSignal(dict) logMsg = pyqtSignal(dict)
taskStart = pyqtSignal(str) taskStart = pyqtSignal(str)
@ -100,7 +124,6 @@ class TaskActuatorManager(QObject):
a for tid, a in list(self.taskActuatorDict.items()) a for tid, a in list(self.taskActuatorDict.items())
if a.isRunning() and not (excludeTaskId and str(tid) == str(excludeTaskId)) if a.isRunning() and not (excludeTaskId and str(tid) == str(excludeTaskId))
] ]
# 先全部设置停止标志
for a in actuators: for a in actuators:
a.running_lock.lock() a.running_lock.lock()
a.running = False a.running = False
@ -111,25 +134,20 @@ class TaskActuatorManager(QObject):
a.subTaskActuator.running_lock.lock() a.subTaskActuator.running_lock.lock()
a.subTaskActuator.running = False a.subTaskActuator.running = False
a.subTaskActuator.running_lock.unlock() a.subTaskActuator.running_lock.unlock()
# 再统一等待/强杀
for a in actuators:
a.quit() a.quit()
if not a.wait(500): kt = _KillThread(a)
for item in a.instructionList: kt.done.connect(self._onKillDone)
try: self._killThreads = getattr(self, '_killThreads', [])
iface = item.get("interface") self._killThreads.append(kt)
if iface: kt.start()
from interfaceSession.interfaceManager import interfaceManager
interfaceManager.getSession(iface).unlock()
except Exception:
pass
a.terminate()
a.wait(200)
a.updateDetails.emit(a.id, -1, -1)
a.taskStop.emit(a.id)
log.info(f"任务 {a.id} 已停止")
return len(actuators) return len(actuators)
def _onKillDone(self, a):
a.updateDetails.emit(a.id, -1, -1)
a.taskStop.emit(a.id)
log.info(f"任务 {a.id} 已停止")
self._killThreads = [t for t in getattr(self, '_killThreads', []) if t.isRunning()]
def requestStopAll(self, requesterTaskId=None): def requestStopAll(self, requesterTaskId=None):
"""请求停止所有任务(由主程序处理)""" """请求停止所有任务(由主程序处理)"""
print(f"[DEBUG] requestStopAll 被调用,请求者: {requesterTaskId}") print(f"[DEBUG] requestStopAll 被调用,请求者: {requesterTaskId}")