submit 0421
parent
97dee8326b
commit
596f1b9673
|
|
@ -4,7 +4,9 @@
|
|||
"Bash(python3 -c ' *)",
|
||||
"Bash(sqlite3 data.db \"PRAGMA table_info\\(task_instruction\\);\")",
|
||||
"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 *)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
23
common.py
23
common.py
|
|
@ -431,6 +431,7 @@ class Common(QObject):
|
|||
def onScanfFinish(self, msg):
|
||||
self.scanfResult = msg
|
||||
|
||||
@pyqtSlot(str,str,str,str, result=bool)
|
||||
@pyqtSlot(str, str, str, str, result=bool)
|
||||
def initAppScript(self, appId, instancName, scriptFile, plusFile="plus"):
|
||||
try:
|
||||
|
|
@ -447,6 +448,10 @@ class Common(QObject):
|
|||
print(e)
|
||||
return False
|
||||
|
||||
@pyqtSlot(str, result=QVariant)
|
||||
def getScript(self, name):
|
||||
return self.qscript.get(name, None)
|
||||
|
||||
@pyqtSlot(str,str,str,str,str, result=bool)
|
||||
def registAppQml(self, appId, instancName, className, scriptFile, plusFile="plus"):
|
||||
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_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):
|
||||
import stat
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class SessionSerial(SessionAbstract):
|
|||
self.thread = QThread()
|
||||
self.worker.moveToThread(self.thread)
|
||||
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.connectClosed.connect(self.onConnectClosed)
|
||||
self.worker.connectFailed.connect(self.onConnectFailed)
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class SessionTbus(SessionAbstract):
|
|||
self.thread = QThread()
|
||||
self.worker.moveToThread(self.thread)
|
||||
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.connectClosed.connect(self.onConnectClosed)
|
||||
self.worker.connectFailed.connect(self.onConnectFailed)
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class SessionTbusNs(SessionAbstract):
|
|||
self.thread = QThread()
|
||||
self.worker.moveToThread(self.thread)
|
||||
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.connectClosed.connect(self.onConnectClosed)
|
||||
self.worker.connectFailed.connect(self.onConnectFailed)
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class MainWindow(QMainWindow):
|
|||
self.ui = Ui_MainWindow()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.tbDefault.setVisible(False)
|
||||
self.isDebugQML = False #DEBUG
|
||||
self.isDebugQML = True #DEBUG
|
||||
self.setWindowTitle("TG-TestingPlatform "+app_version.data["version"])
|
||||
self.ui.lbtitle.setText("TG-TestingPlatform "+app_version.data["version"])
|
||||
self.ui.logWidget.setVisible(True)
|
||||
|
|
@ -234,7 +234,6 @@ class MainWindow(QMainWindow):
|
|||
self.ui.quickTaskbar.setSource(QUrl(common.firstPath()+"/TaskBar.qml"))
|
||||
self.ui.quickStackView.setSource(QUrl(common.firstPath()+"/main.qml"))
|
||||
self.ui.quickSetting.setSource(QUrl(common.firstPath()+"/SettingView.qml"))
|
||||
|
||||
if self.isDebugQML:
|
||||
self.setDebugQML()
|
||||
|
||||
|
|
@ -249,7 +248,7 @@ class MainWindow(QMainWindow):
|
|||
self.ui.quickDebug.rootContext().setContextProperty("taskManager", taskManager)
|
||||
self.ui.quickDebug.rootContext().setContextProperty("interfaceManager", interfaceManager)
|
||||
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):
|
||||
# 清除QML引擎缓存
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ Rectangle
|
|||
property var g_sn: "8441"
|
||||
property var appPath: "/"+plusFile+"/"+appId+"/"
|
||||
property var firstPath: ""
|
||||
property var calibrate: null
|
||||
property var startDate: new Date()
|
||||
property var startTime: startDate.getTime()
|
||||
property var endTime: startDate.getTime()
|
||||
|
|
@ -54,6 +55,7 @@ Rectangle
|
|||
firstPath = common.firstPath()
|
||||
g_user = common.getCurrentUser()
|
||||
common.initAppScript(appId, "calibrate", "calibrate.py", plusFile)
|
||||
calibrate = common.getScript("calibrate")
|
||||
setConfigInfo()
|
||||
calibrate.startShima(firstPath + appPath)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import QtQuick.Dialogs
|
|||
// import QtQuick.Controls.
|
||||
import "./app.js" as App
|
||||
import "./common"
|
||||
import Qt.labs.folderlistmodel
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
radius: 9
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import QtQuick.Dialogs
|
|||
// import QtQuick.Controls.
|
||||
import "./app.js" as App
|
||||
import "./common"
|
||||
import Qt.labs.folderlistmodel
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
|
@ -55,6 +54,24 @@ Rectangle {
|
|||
GradientStop { position: 1.0; color: "#b7d6fb" }
|
||||
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{
|
||||
id: logModel
|
||||
}
|
||||
|
|
@ -138,24 +155,16 @@ Rectangle {
|
|||
boundsBehavior: Flickable.StopAtBounds
|
||||
ScrollBar.vertical: ScrollBar{}
|
||||
anchors.margins: 5
|
||||
model: FolderListModel {
|
||||
id: folderModel
|
||||
rootFolder: logDirectory
|
||||
showDirsFirst: true
|
||||
showFiles: true
|
||||
folder: logDirectory // 显式设置初始路径
|
||||
}
|
||||
model: fileListModel
|
||||
delegate: ItemDelegate {
|
||||
text: model.fileName
|
||||
icon.source: "resource/file.svg"
|
||||
background: Rectangle {
|
||||
color: fileSystemView.currentIndex == index ? "#D9D9D9" : "white"
|
||||
// 代理项的其他内容...
|
||||
}
|
||||
onClicked: {
|
||||
console.info("Clicked on: " + model.fileName)
|
||||
currentLogfilePath = model.filePath
|
||||
currentLogResult = log_processor.read_file(currentLogfilePath)
|
||||
currentLogResult = common.readLogFile(currentLogfilePath)
|
||||
updateLogDisplay()
|
||||
fileSystemView.currentIndex = index
|
||||
}
|
||||
|
|
|
|||
|
|
@ -565,8 +565,8 @@ class TaskForm(QWidget):
|
|||
row_id_index = self.taskGroupModel.index(row, 0, QModelIndex())
|
||||
group_id = self.taskGroupModel.data(row_id_index, Qt.ItemDataRole.DisplayRole)
|
||||
self.current_groupId = group_id
|
||||
self.loadTask()
|
||||
self.clearChildrenModel()
|
||||
QTimer.singleShot(0, self.loadTask)
|
||||
|
||||
#任务列表选中
|
||||
def handleTaskSelection(self, index):
|
||||
|
|
@ -955,6 +955,9 @@ class TaskForm(QWidget):
|
|||
if str(taskId) == str(obj.get('task_instruction_id')):
|
||||
self.taskModelBlockSignals = True
|
||||
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):
|
||||
"""任务停止时清理缓存和进度显示"""
|
||||
taskId = str(taskId)
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ class TaskActuator(QThread):
|
|||
loop = int(self.taskInfo.get("loop", 1))
|
||||
delay = float(int(self.taskInfo.get("delay",0))/1000)
|
||||
taskIndex = 0
|
||||
total = instructionListLength * loop
|
||||
total = instructionListLength * loop if loop > 0 else instructionListLength
|
||||
self.updateProgress.emit(self.id, 0, total)
|
||||
self.updateDetails.emit(self.id, 0, total)
|
||||
self.updateDetails.emit(self.parentId, 0, total)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,30 @@ from taskInstructionModel.taskInstructionManager import taskInstructionManager
|
|||
from taskModel.taskManager import taskManager
|
||||
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):
|
||||
logMsg = pyqtSignal(dict)
|
||||
taskStart = pyqtSignal(str)
|
||||
|
|
@ -100,7 +124,6 @@ class TaskActuatorManager(QObject):
|
|||
a for tid, a in list(self.taskActuatorDict.items())
|
||||
if a.isRunning() and not (excludeTaskId and str(tid) == str(excludeTaskId))
|
||||
]
|
||||
# 先全部设置停止标志
|
||||
for a in actuators:
|
||||
a.running_lock.lock()
|
||||
a.running = False
|
||||
|
|
@ -111,24 +134,19 @@ class TaskActuatorManager(QObject):
|
|||
a.subTaskActuator.running_lock.lock()
|
||||
a.subTaskActuator.running = False
|
||||
a.subTaskActuator.running_lock.unlock()
|
||||
# 再统一等待/强杀
|
||||
for a in actuators:
|
||||
a.quit()
|
||||
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)
|
||||
kt = _KillThread(a)
|
||||
kt.done.connect(self._onKillDone)
|
||||
self._killThreads = getattr(self, '_killThreads', [])
|
||||
self._killThreads.append(kt)
|
||||
kt.start()
|
||||
return len(actuators)
|
||||
|
||||
def _onKillDone(self, a):
|
||||
a.updateDetails.emit(a.id, -1, -1)
|
||||
a.taskStop.emit(a.id)
|
||||
log.info(f"任务 {a.id} 已停止")
|
||||
return len(actuators)
|
||||
self._killThreads = [t for t in getattr(self, '_killThreads', []) if t.isRunning()]
|
||||
|
||||
def requestStopAll(self, requesterTaskId=None):
|
||||
"""请求停止所有任务(由主程序处理)"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue