Bläddra i källkod

创建仓库,第一次提交

guoqiang 2 år sedan
incheckning
c924f0b9ac
76 ändrade filer med 13834 tillägg och 0 borttagningar
  1. 72 0
      BreatheProcess.qml
  2. 263 0
      BreatheResult.qml
  3. 279 0
      BreatheTable.qml
  4. 52 0
      CurveDisplay.qml
  5. 83 0
      DLog.cpp
  6. 18 0
      DLog.h
  7. 72 0
      DynamicGroupBox.qml
  8. 43 0
      InputLine.qml
  9. 27 0
      LCDNumber.qml
  10. 81 0
      Log.qml
  11. 151 0
      Message_box.cpp
  12. 53 0
      Message_box.h
  13. 54 0
      Modbus.cpp
  14. 14 0
      Modbus.h
  15. 64 0
      Msgbox.cpp
  16. 44 0
      Msgbox.h
  17. 47 0
      Page1.qml
  18. 50 0
      Page2.qml
  19. 81 0
      PageDefault.qml
  20. 15 0
      PageFirst.qml
  21. 429 0
      PageMain.qml
  22. 785 0
      PageSetting.qml
  23. 477 0
      PageStandard.qml
  24. 502 0
      PageTest.qml
  25. 47 0
      RecordTable.qml
  26. 604 0
      RecoveryValve.qml
  27. 22 0
      ReportButton.qml
  28. 71 0
      ReportPicture.qml
  29. 40 0
      ResultDisplayText.qml
  30. 115 0
      ResultTable.qml
  31. 416 0
      Standard.cpp
  32. 67 0
      Standard.h
  33. 20 0
      StartStopButton.qml
  34. 95 0
      StateTable.qml
  35. 2079 0
      TestService.cpp
  36. 214 0
      TestService.h
  37. 50 0
      UserButton.qml
  38. 90 0
      UserComboBox.qml
  39. 37 0
      UserRadioButton.qml
  40. 61 0
      UserSwitch.qml
  41. 166 0
      UserTableView.qml
  42. 88 0
      UserTristate.qml
  43. 54 0
      ValveTest.pro
  44. 265 0
      ValveTest.pro.user
  45. 750 0
      breatheTest.js
  46. BIN
      font/DS-DIGI.TTF
  47. 1076 0
      generateword.cpp
  48. 28 0
      generateword.h
  49. BIN
      img/blue_button.png
  50. BIN
      img/close.png
  51. BIN
      img/crystal_button.png
  52. BIN
      img/main_zjtj_bj.jpg
  53. BIN
      img/pink_button.png
  54. BIN
      img/reports-icon.png
  55. BIN
      img/shutdown_blue.png
  56. BIN
      img/shutdown_red.png
  57. BIN
      img/start1.png
  58. BIN
      img/stop1.png
  59. BIN
      img/tj_icon.png
  60. BIN
      img/zjtj_logo.png
  61. 52 0
      main.cpp
  62. 158 0
      main.qml
  63. 113 0
      pid.cpp
  64. 25 0
      pid.h
  65. 45 0
      qml.qrc
  66. 1271 0
      qword.cpp
  67. 165 0
      qword.h
  68. 799 0
      report.cpp
  69. 98 0
      report.h
  70. 347 0
      serialport.cpp
  71. 54 0
      serialport.h
  72. 130 0
      serialui.cpp
  73. 48 0
      serialui.h
  74. 234 0
      tank.cpp
  75. 84 0
      tank.h
  76. BIN
      valve.ico

+ 72 - 0
BreatheProcess.qml

@@ -0,0 +1,72 @@
+import QtQuick 2.11
+import QtQuick.Controls 2.14
+
+Item {
+    id:root
+
+    property int hideWith
+    Loader{
+        id:loader
+        anchors.fill: parent
+    }
+
+    function show(text){
+
+        loader.sourceComponent  = undefined
+        loader.sourceComponent  = component
+        loader.item.show()
+        loader.item.text = text
+    }
+
+    function exit(){
+        loader.sourceComponent = undefined
+    }
+
+    Component{
+        id:component
+        Item {
+            id:item
+            property alias text:fgtext.text
+
+            function show(){
+                animationShow.running = true
+            }
+
+
+            //加载任务动画效果
+            NumberAnimation {
+                id: animationShow
+                target: item
+                property: "x"
+                from: root.hideWith
+                to: 0
+                duration: 500
+            }
+
+            Rectangle{
+                id:bg
+                anchors.fill: parent
+                color: "black"
+                opacity: 0.5
+                radius: 4
+            }
+
+            Item {
+                id:fg
+                z:bg.z+1
+                anchors.fill: parent
+                Text {
+                    id: fgtext
+                    anchors.centerIn: parent
+                    color: "white"
+                    font.bold: true
+                    font.pixelSize: 18
+                }
+            }
+        }
+    }
+
+
+
+
+}

+ 263 - 0
BreatheResult.qml

@@ -0,0 +1,263 @@
+import QtQuick 2.11
+import QtQuick.Controls 2.14
+Item {
+    id:root
+    anchors.fill: parent
+
+    property string  positiveOpenPressure1
+    property string  positiveOpenPressure2
+    property string  positiveOpenPressure3
+    property string  positiveSealPressure1
+    property string  positiveSealPressure2
+    property string  positiveSealPressure3
+
+    property string  negativeOpenPressure1
+    property string  negativeOpenPressure2
+    property string  negativeOpenPressure3
+    property string  negativeSealPressure1
+    property string  negativeSealPressure2
+    property string  negativeSealPressure3
+
+    property string  capsizeSealPressure1
+    property string  capsizeSealPressure2
+    property string  capsizeSealPressure3
+
+    property alias  swipeview:view
+
+
+    SwipeView {
+        id: view
+        currentIndex: pageIndicator.currentIndex
+        anchors.fill: parent
+        clip: true
+
+        Rectangle {
+            Item {
+                id:positiveReuslt
+                anchors.fill: parent
+                anchors.margins: 10
+                property int resultHeight: 25
+                Column{
+                    anchors.centerIn: parent
+                    ResultDisplayText{
+                        width: positiveReuslt.width
+                        height: positiveReuslt.resultHeight
+                        color: "white"
+                        paraName: "正压开启压力"
+                        paraResult:""
+                        paraUnit:""
+                    }
+                    ResultDisplayText{
+                        width: positiveReuslt.width
+                        height: positiveReuslt.resultHeight
+                        color: "#D2D5D9"
+                        paraName: "第一次:"
+                        paraResult:positiveOpenPressure1
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: positiveReuslt.width
+                        height: positiveReuslt.resultHeight
+                        color: "#DFE2E6"
+                        paraName: "第二次:"
+                        paraResult:positiveOpenPressure2
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: positiveReuslt.width
+                        height: positiveReuslt.resultHeight
+                        color: "#D2D5D9"
+                        paraName: "第三次:"
+                        paraResult:positiveOpenPressure3
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: positiveReuslt.width
+                        height: positiveReuslt.resultHeight
+                        color: "white"
+                        paraName: ""
+                        paraResult:""
+                        paraUnit:""
+                    }
+                    ResultDisplayText{
+                        width: positiveReuslt.width
+                        height: positiveReuslt.resultHeight
+                        color: "white"
+                        paraName: "正压密封压力"
+                        paraResult:""
+                        paraUnit:""
+                    }
+                    ResultDisplayText{
+                        width: positiveReuslt.width
+                        height: positiveReuslt.resultHeight
+                        color: "#DFE2E6"
+                        paraName: "第一次:"
+                        paraResult:positiveSealPressure1
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: positiveReuslt.width
+                        height: positiveReuslt.resultHeight
+                        color: "#D2D5D9"
+                        paraName: "第二次:"
+                        paraResult:positiveSealPressure2
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: positiveReuslt.width
+                        height: positiveReuslt.resultHeight
+                        color: "#DFE2E6"
+                        paraName: "第三次:"
+                        paraResult:positiveSealPressure3
+                        paraUnit:"kPa"
+                    }
+
+                }
+            }
+
+        }
+        Rectangle {
+            Item {
+                id:negativeReuslt
+                anchors.fill: parent
+                anchors.margins: 10
+                property int resultHeight: 25
+                Column{
+                    anchors.centerIn: parent
+                    ResultDisplayText{
+                        width: negativeReuslt.width
+                        height: negativeReuslt.resultHeight
+                        color: "white"
+                        paraName: "负压开启压力"
+                        paraResult:""
+                        paraUnit:""
+                    }
+                    ResultDisplayText{
+                        width: negativeReuslt.width
+                        height: negativeReuslt.resultHeight
+                        color: "#D2D5D9"
+                        paraName: "第一次:"
+                        paraResult:negativeOpenPressure1
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: negativeReuslt.width
+                        height: negativeReuslt.resultHeight
+                        color: "#DFE2E6"
+                        paraName: "第二次:"
+                        paraResult:negativeOpenPressure2
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: negativeReuslt.width
+                        height: negativeReuslt.resultHeight
+                        color: "#D2D5D9"
+                        paraName: "第三次:"
+                        paraResult:negativeOpenPressure3
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: negativeReuslt.width
+                        height: negativeReuslt.resultHeight
+                        color: "white"
+                        paraName: ""
+                        paraResult:""
+                        paraUnit:""
+                    }
+                    ResultDisplayText{
+                        width: negativeReuslt.width
+                        height: negativeReuslt.resultHeight
+                        color: "white"
+                        paraName: "负压密封压力"
+                        paraResult:""
+                        paraUnit:""
+                    }
+                    ResultDisplayText{
+                        width: negativeReuslt.width
+                        height: negativeReuslt.resultHeight
+                        color: "#DFE2E6"
+                        paraName: "第一次:"
+                        paraResult:negativeSealPressure1
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: negativeReuslt.width
+                        height: negativeReuslt.resultHeight
+                        color: "#D2D5D9"
+                        paraName: "第二次:"
+                        paraResult:negativeSealPressure2
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: negativeReuslt.width
+                        height: negativeReuslt.resultHeight
+                        color: "#DFE2E6"
+                        paraName: "第三次:"
+                        paraResult:negativeSealPressure3
+                        paraUnit:"kPa"
+                    }
+
+                }
+            }
+
+        }
+        Rectangle {
+            Item {
+                id:capsizeReuslt
+                anchors.fill: parent
+                anchors.margins: 10
+                property int resultHeight: 25
+                Column{
+                    anchors.centerIn: parent
+                    ResultDisplayText{
+                        width: capsizeReuslt.width
+                        height: capsizeReuslt.resultHeight
+                        color: "white"
+                        paraName: "倾覆密封压力"
+                        paraResult:""
+                        paraUnit:""
+                    }
+                    ResultDisplayText{
+                        width: capsizeReuslt.width
+                        height: capsizeReuslt.resultHeight
+                        color: "#D2D5D9"
+                        paraName: "90°:"
+                        paraResult:capsizeSealPressure1
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: capsizeReuslt.width
+                        height: capsizeReuslt.resultHeight
+                        color: "#DFE2E6"
+                        paraName: "180°:"
+                        paraResult:capsizeSealPressure2
+                        paraUnit:"kPa"
+                    }
+                    ResultDisplayText{
+                        width: capsizeReuslt.width
+                        height: capsizeReuslt.resultHeight
+                        color: "#D2D5D9"
+                        paraName: "270°:"
+                        paraResult:capsizeSealPressure3
+                        paraUnit:"kPa"
+                    }
+                }
+            }
+        }
+
+    }
+
+    PageIndicator {
+        id: pageIndicator
+        interactive: true
+        count: view.count
+        currentIndex: view.currentIndex
+
+        anchors.bottom: parent.bottom
+        anchors.horizontalCenter: parent.horizontalCenter
+    }
+}
+
+
+
+

+ 279 - 0
BreatheTable.qml

@@ -0,0 +1,279 @@
+import QtQuick 2.11
+import QtQuick.Controls 1.4
+import QtQuick.Controls 2.14
+import "modbus.js" as ModbusJs
+
+Item {
+    id:root
+
+    property alias  swipeview:view
+    property alias  positiveTabview:tabview1
+    property alias  negativeTabview:tabview2
+    property alias  capsizeTabview: tabview3
+
+    SwipeView {
+        id: view
+        property int tableWidth:980
+        currentIndex: pageIndicator.currentIndex
+        anchors.fill: parent
+        clip: true
+
+        function dataRandomSet1(modelData,max){
+            for(var i=0;i<max; i++){
+                var number= Math.round(Math.random()*30)
+                var obj={}
+                obj.pressure=number
+                modelData.append(obj)
+            }
+        }
+
+        function dataRandomSet2(modelData,max){
+            for(var i=0;i<max; i++){
+                var number= Math.round(Math.random()*(-10))
+                var obj={}
+                obj.pressure=number
+                modelData.append(obj)
+            }
+        }
+
+        function dataRandomSet3(modelData,max){
+            for(var i=0;i<max; i++){
+                var number= Math.round(Math.random()*50)
+                var obj={}
+                obj.pressure=number
+                modelData.append(obj)
+            }
+        }
+
+        TabView {
+            id:tabview1
+
+            GraphButton{
+                id:graphButton
+                x:910
+                y:-18
+                z:tabview1.z+1
+                width: 48
+                height: 24
+                onUserClicked: {
+                    var tab = tabview1.getTab(tabview1.currentIndex)
+                    var axisxMax = tab.item.modelData.count
+                    generateCurve.show(0,axisxMax,0,50,tab.item.modelData,tab.title,"横轴时间(秒) 纵轴压力(kPa)")
+                }
+            }
+
+
+            Tab {
+                id:tab
+                active: true
+                title: "正压第一次开启"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet1(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "正压第二次开启"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet1(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "正压第三次开启"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet1(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "正压第一次密封"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet1(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "正压第二次密封"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet1(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "正压第三次密封"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet1(modelData,20)
+//                    }
+                }
+            }
+
+        }
+        TabView {
+            id:tabview2
+            GraphButton{
+                x:910
+                y:-18
+                z:tabview1.z+1
+                width: 48
+                height: 24
+                onUserClicked: {
+                    var tab = tabview2.getTab(tabview2.currentIndex)
+                    var axisxMax = tab.item.modelData.count
+                    generateCurve.show(0,axisxMax,-10,5,tab.item.modelData,tab.title,"横轴时间(秒) 纵轴压力(kPa)")
+                }
+            }
+            Tab {
+                active: true
+                title: "负压第一次开启"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet2(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "负压第二次开启"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet2(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "负压第三次开启"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet2(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "负压第一次密封"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet2(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "负压第二次密封"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet2(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "负压第三次密封"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet2(modelData,20)
+//                    }
+                }
+            }
+
+        }
+
+        TabView {
+            id:tabview3
+            GraphButton{
+                x:910
+                y:-18
+                z:tabview1.z+1
+                width: 48
+                height: 24
+                onUserClicked: {
+                    var tab = tabview3.getTab(tabview3.currentIndex)
+                    var axisxMax = tab.item.modelData.count
+                    generateCurve.show(0,axisxMax,0,50,tab.item.modelData,tab.title,"横轴时间(秒) 纵轴压力(kPa)")
+                }
+            }
+            Tab {
+                active: true
+                title: "倾覆90度记录"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet3(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "倾覆180度记录"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet3(modelData,20)
+//                    }
+                }
+            }
+            Tab {
+                active: true
+                title: "倾覆270度记录"
+                anchors.fill: parent
+                anchors.bottomMargin: 5
+                RecordTable{
+//                    Component.onCompleted: {
+//                        view.dataRandomSet3(modelData,20)
+//                    }
+                }
+            }
+        }
+
+    }
+
+
+    PageIndicator {
+        id: pageIndicator
+        interactive: true
+        count: view.count
+        currentIndex: view.currentIndex
+        anchors.bottom: parent.bottom
+        anchors.horizontalCenter: parent.horizontalCenter
+    }
+
+}

+ 52 - 0
CurveDisplay.qml

@@ -0,0 +1,52 @@
+import QtQuick 2.15
+import QtCharts 2.15
+Item {
+
+    property int axisxMax
+    property int axisxMin
+    property int axisyMax
+    property int axisyMin
+    property alias spline:splineSeries
+    property alias name:splineSeries.name
+    property alias charView:charView
+
+    function setRange_X(min, max){
+        axisxMin=min
+        axisxMax=max
+    }
+
+    function setRange_Y(min, max){
+        axisyMin=min
+        axisyMax=max
+    }
+
+    ChartView{
+        id:charView
+        anchors.fill: parent
+        antialiasing:true
+
+        ValueAxis{
+            id:axisx
+            max:axisxMax;
+            min:axisxMin;
+            tickCount: 13
+        }
+
+        ValueAxis{
+            id:axisy
+            max:axisyMax;
+            min:axisyMin;
+            tickCount: 15
+        }
+        SplineSeries{
+            id:splineSeries
+            color: Qt.rgba(255,0,0,1)
+
+            axisX: axisx
+            axisY: axisy
+            useOpenGL: false
+        }
+
+    }
+
+}

+ 83 - 0
DLog.cpp

@@ -0,0 +1,83 @@
+#include "DLog.h"
+#include <QtDebug>
+
+#define DEBUG_FILE_NAME  "debug.txt"
+#define DEBUG_FILE_BACKUP  "debug_bak.txt"
+#define DEBUG_FILE_MAX_SIZE (1*1024*1024)  //1MB
+
+void DLog_Init()
+{
+
+    //tmp 存放生成的曲线图片
+    QDir dir("D:/tmp");
+
+    if(dir.exists()){
+        //clear tmp
+        dir.setFilter(QDir::Files);
+
+        int filecount = dir.count();
+        for(int i=0; i< filecount; i++){
+            dir.remove(dir[i]);
+        }
+
+        qDebug() << "D:/tmp is exists";
+
+    }else{
+
+        dir.mkdir("D:/tmp");
+        qDebug() << "D:/tmp is not exists, mk it";
+    }
+
+
+    QFile file(DEBUG_FILE_NAME);
+    if( file.exists() && file.size() >= DEBUG_FILE_MAX_SIZE ){
+
+        {
+            QFile file_bak(DEBUG_FILE_BACKUP);
+            if(file_bak.exists()){
+                file_bak.remove();
+            }
+        }
+
+        file.rename(DEBUG_FILE_BACKUP);
+
+    }
+
+    //qInstallMessageHandler(myMsgOutput);
+
+
+}
+
+void myMsgOutput(QtMsgType type, const QMessageLogContext &context, const QString& msg)
+{
+    static QMutex mutex;
+    mutex.lock();
+    QString time=QDateTime::currentDateTime().toString(QString("[ yyyy-MM-dd HH:mm:ss:zzz ]"));
+    QString mmsg;
+    switch(type)
+    {
+    case QtDebugMsg:
+        mmsg=QString("%1: Debug:\t%2 (file:%3, line:%4, func: %5)").arg(time).arg(msg).arg(QString(context.file)).arg(context.line).arg(QString(context.function));
+        break;
+    case QtInfoMsg:
+        mmsg=QString("%1: Info:\t%2 (file:%3, line:%4, func: %5)").arg(time).arg(msg).arg(QString(context.file)).arg(context.line).arg(QString(context.function));
+        break;
+    case QtWarningMsg:
+        mmsg=QString("%1: Warning:\t%2 (file:%3, line:%4, func: %5)").arg(time).arg(msg).arg(QString(context.file)).arg(context.line).arg(QString(context.function));
+        break;
+    case QtCriticalMsg:
+        mmsg=QString("%1: Critical:\t%2 (file:%3, line:%4, func: %5)").arg(time).arg(msg).arg(QString(context.file)).arg(context.line).arg(QString(context.function));
+        break;
+    case QtFatalMsg:
+        mmsg=QString("%1: Fatal:\t%2 (file:%3, line:%4, func: %5)").arg(time).arg(msg).arg(QString(context.file)).arg(context.line).arg(QString(context.function));
+        abort();
+    }
+
+    QFile file(DEBUG_FILE_NAME);
+    file.open(QIODevice::ReadWrite | QIODevice::Append);
+    QTextStream stream(&file);
+    stream << mmsg << "\r\n";
+    file.flush();
+    file.close();
+    mutex.unlock();
+}

+ 18 - 0
DLog.h

@@ -0,0 +1,18 @@
+#ifndef DLOG_H
+#define DLOG_H
+
+#include <qapplication.h>
+#include <QDateTime>
+#include <QFile>
+#include <QDir>
+#include <QTextStream>
+#include <QtMsgHandler>
+#include <QMessageLogContext>
+#include <QMutex>
+
+
+void DLog_Init();
+void myMsgOutput(QtMsgType type, const QMessageLogContext &context, const QString& msg);
+
+
+#endif // DLOG_H

+ 72 - 0
DynamicGroupBox.qml

@@ -0,0 +1,72 @@
+import QtQuick 2.15
+
+import QtQuick.Controls 2.14
+import QtGraphicalEffects 1.14
+
+GroupBox {
+      property var radiusVal: 6                     // 圆角值
+      property var borderWidth:  1                  // 边框宽度
+      property var borderColor: "#97C4F5"           // 边框颜色
+      property var titleColor:  "#2359B7"           // 标题颜色
+      property var titleLeftBkColor:  "#C9DDF8"     // 标题最左侧背景色
+      property var titleRightBkColor:  "#F7FAFF"    // 标题最右侧颜色
+      property var titleTopPadding:  3              // 标题的顶部内边距
+      property var contentBkColor:  "#77F0F6FF"     // 内容背景色
+      property var titleFontPixel:  24
+
+      id: control
+      title: qsTr("GroupBox")
+
+
+      background: Rectangle {
+          anchors.fill: control
+          radius: radiusVal
+          border.color: borderColor
+          clip: true
+          Item {
+                  x: borderWidth
+                  y: borderWidth
+                  width: parent.width - borderWidth * 2
+                  height: control.topPadding - control.bottomPadding - borderWidth * 2 + titleTopPadding * 2
+                  clip: true
+
+                  Rectangle {        // 设置标题的背景色
+                        anchors.fill: parent
+                        color: "#228833"
+
+                        LinearGradient {
+                            anchors.fill: parent
+                            source: parent
+                            start: Qt.point(0, 0)
+                            end: Qt.point(parent.width, 0)
+                            gradient: Gradient {
+                                GradientStop { position: 0.0; color: titleLeftBkColor }
+                                GradientStop { position: 1.0; color: titleRightBkColor }
+                            }
+                        }
+                  }
+          }
+
+          Rectangle {   // 设置内容的背景色
+                x: 1
+                y: control.topPadding - control.bottomPadding - borderWidth * 2 + titleTopPadding * 2
+                width: parent.width - borderWidth * 2
+                height: parent.height - control.topPadding + control.bottomPadding - borderWidth * 2 - titleTopPadding * 2
+                color: contentBkColor
+          }
+
+      }
+
+      label: Label {        // 设置title的属性
+           y:  titleTopPadding
+           x: control.leftPadding
+           width: control.availableWidth
+           text: control.title
+           color: titleColor
+           elide: Text.ElideRight
+           font.pixelSize: titleFontPixel
+
+      }
+
+
+}

+ 43 - 0
InputLine.qml

@@ -0,0 +1,43 @@
+import QtQuick 2.11
+import QtQuick.Controls 2.14
+
+Row{
+    property string paraName
+    property int paraLength
+    property alias validator:textField.validator
+    property alias textFocus:textField.focus
+    property alias text:textField.text
+    property alias inputMethodHints:textField.inputMethodHints
+    property alias background:bg
+    spacing: 5
+
+    signal userAccept(var text)
+
+    Text {
+        id: name
+        anchors.verticalCenter: parent.verticalCenter
+        text: paraName
+        color:  "#272727"
+        font.bold: true
+        font.pixelSize: 20
+    }
+
+    TextField {
+        id: textField
+        anchors.verticalCenter: parent.verticalCenter
+        font.pixelSize: 20
+        font.bold: false
+        onTextEdited: {
+            userAccept(text)
+        }
+
+        background: Rectangle {
+                        id:bg
+                        implicitWidth: paraLength
+                        height: 28
+                        radius: 4
+                        border.color:  "#0099cc"
+                    }
+       // placeholderText: qsTr("请输入")
+    }
+}

+ 27 - 0
LCDNumber.qml

@@ -0,0 +1,27 @@
+import QtQuick 2.11
+
+Item {
+    id:root
+    anchors.fill: parent
+    anchors.margins: 5
+    property  int fontsize:100
+    property  string fontcolor:"black"
+    property  string text:"0.000"
+
+
+    FontLoader{
+        id: fontlcd
+        source: "qrc:/font/DS-DIGI.TTF"
+    }
+
+    Text {
+        id:lcdnumber
+        anchors.centerIn: parent
+
+        color:fontcolor
+        text: root.text
+        font.family: fontlcd.name
+        font.pixelSize: root.fontsize
+    }
+
+}

+ 81 - 0
Log.qml

@@ -0,0 +1,81 @@
+import QtQuick 2.0
+
+Item {
+    id:root
+    Loader{
+        id:loader
+        anchors.fill: parent
+    }
+
+    function show(text){
+
+        if(loader.sourceComponent  === null){
+            loader.sourceComponent  = component
+        }
+        loader.item.text = text
+        //loader.item.bg.color="black"
+        console.log(text)
+    }
+
+    function show2(text){
+
+        if(loader.sourceComponent  === null){
+            loader.sourceComponent  = component
+        }
+        loader.item.text = text
+        //loader.item.bg.color="red"
+        console.log(text)
+    }
+
+    function exit(){
+        loader.sourceComponent = undefined
+    }
+
+
+    Component{
+        id:component
+        Item {
+            id:item
+            property alias text:fgtext.text
+
+            Rectangle{
+                id:bg
+                anchors.fill: parent
+                color: "black"
+                opacity: 0.5
+                radius: 4
+                MouseArea{
+                    anchors.fill: parent
+                    drag.target:item
+                    drag.axis:Drag.XAndYAxis
+                }
+            }
+
+            Item {
+                id:fg
+                z:bg.z+1
+                anchors.fill: parent
+                Text {
+                    id: fgtext
+                    anchors.centerIn: parent
+                    color: "white"
+                    font.bold: true
+                    font.pixelSize: 15
+                }
+                Image {
+                    anchors.right: parent.right
+                    anchors.top: parent.top
+                    source: "qrc:/img/close.png"
+                    MouseArea{
+                        anchors.fill: parent
+                        onClicked:{
+                            root.exit()
+                        }
+                    }
+                }
+
+            }
+        }
+    }
+
+}

+ 151 - 0
Message_box.cpp

@@ -0,0 +1,151 @@
+#include <QLabel>
+#include <QPushButton>
+#include <QMessageBox>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QEvent>
+#include <QApplication>
+#include "Message_box.h"
+
+MessageBox::MessageBox(QWidget *parent, const QString &title, const QString &text,
+                       QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
+    : CustomWindow(parent)
+{
+    setWindowIcon(QIcon(":/Images/logo"));
+    setWindowTitle(title);
+    setMinimumSize(300, 130);
+    setMinimizeVisible(false);
+    setMaximizeVisible(false);
+    setWidgetResizable(false);
+
+    m_pButtonBox = new QDialogButtonBox(this);
+    m_pButtonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons)));
+    setDefaultButton(defaultButton);
+
+    QPushButton *pYesButton = m_pButtonBox->button(QDialogButtonBox::Yes);
+    if (pYesButton != NULL)
+    {
+        pYesButton->setObjectName("blueButton");
+        pYesButton->setStyle(QApplication::style());
+    }
+
+    m_pIconLabel = new QLabel(this);
+    m_pLabel = new QLabel(this);
+
+    QPixmap pixmap(":/Images/information");
+    m_pIconLabel->setPixmap(pixmap);
+    m_pIconLabel->setFixedSize(35, 35);
+    m_pIconLabel->setScaledContents(true);
+
+    m_pLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+    m_pLabel->setObjectName("whiteLabel");
+    m_pLabel->setOpenExternalLinks(true);
+    m_pLabel->setText(text);
+
+    m_pGridLayout = new QGridLayout();
+    m_pGridLayout->addWidget(m_pIconLabel, 0, 0, 2, 1, Qt::AlignTop);
+    m_pGridLayout->addWidget(m_pLabel, 0, 1, 2, 1);
+    m_pGridLayout->addWidget(m_pButtonBox, m_pGridLayout->rowCount(), 0, 1, m_pGridLayout->columnCount());
+    m_pGridLayout->setSizeConstraint(QLayout::SetNoConstraint);
+    m_pGridLayout->setHorizontalSpacing(10);
+    m_pGridLayout->setVerticalSpacing(10);
+    m_pGridLayout->setContentsMargins(10, 10, 10, 10);
+    m_pLayout->addLayout(m_pGridLayout);
+
+    translateUI();
+
+    connect(m_pButtonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*)));
+}
+
+MessageBox::~MessageBox()
+{
+
+}
+
+void MessageBox::changeEvent(QEvent *event)
+{
+    switch (event->type())
+    {
+    case QEvent::LanguageChange:
+        translateUI();
+        break;
+    default:
+        CustomWindow::changeEvent(event);
+    }
+}
+
+void MessageBox::translateUI()
+{
+    QPushButton *pYesButton = m_pButtonBox->button(QDialogButtonBox::Yes);
+    if (pYesButton != NULL)
+        pYesButton->setText(tr("Yes"));
+
+    QPushButton *pNoButton = m_pButtonBox->button(QDialogButtonBox::No);
+    if (pNoButton != NULL)
+        pNoButton->setText(tr("No"));
+
+    QPushButton *pOkButton = m_pButtonBox->button(QDialogButtonBox::Ok);
+    if (pOkButton != NULL)
+        pOkButton->setText(tr("Ok"));
+
+    QPushButton *pCancelButton = m_pButtonBox->button(QDialogButtonBox::Cancel);
+    if (pCancelButton != NULL)
+        pCancelButton->setText(tr("Cancel"));
+}
+
+QMessageBox::StandardButton MessageBox::standardButton(QAbstractButton *button) const
+{
+    return (QMessageBox::StandardButton)m_pButtonBox->standardButton(button);
+}
+
+QAbstractButton *MessageBox::clickedButton() const
+{
+    return m_pClickedButton;
+}
+
+int MessageBox::execReturnCode(QAbstractButton *button)
+{
+    int nResult = m_pButtonBox->standardButton(button);
+    return nResult;
+}
+
+void MessageBox::onButtonClicked(QAbstractButton *button)
+{
+    m_pClickedButton = button;
+    done(execReturnCode(button));
+}
+
+void MessageBox::setDefaultButton(QPushButton *button)
+{
+    if (!m_pButtonBox->buttons().contains(button))
+        return;
+    m_pDefaultButton = button;
+    button->setDefault(true);
+    button->setFocus();
+}
+
+void MessageBox::setDefaultButton(QMessageBox::StandardButton button)
+{
+    setDefaultButton(m_pButtonBox->button(QDialogButtonBox::StandardButton(button)));
+}
+
+void MessageBox::setTitle(const QString &title)
+{
+    setWindowTitle(title);
+}
+
+void MessageBox::setText(const QString &text)
+{
+    m_pLabel->setText(text);
+}
+
+void MessageBox::setIcon(const QString &icon)
+{
+    m_pIconLabel->setPixmap(QPixmap(icon));
+}
+
+void MessageBox::addWidget(QWidget *pWidget)
+{
+    m_pLabel->hide();
+    m_pGridLayout->addWidget(pWidget, 0, 1, 2, 1);
+}

+ 53 - 0
Message_box.h

@@ -0,0 +1,53 @@
+#ifndef MESSAGE_BOX_H
+#define MESSAGE_BOX_H
+
+
+#include <QMessageBox>
+#include <QDialogButtonBox>
+#include <QGridLayout>
+#include "custom_window.h"
+
+class QLabel;
+
+class MessageBox : public CustomWindow
+{
+    Q_OBJECT
+
+public:
+    explicit MessageBox(QWidget *parent = 0, const QString &title = tr("Tip"), const QString &text = "",
+                        QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::Ok);
+    ~MessageBox();
+    QAbstractButton *clickedButton() const;
+    QMessageBox::StandardButton standardButton(QAbstractButton *button) const;
+    // 设置默认按钮
+    void setDefaultButton(QPushButton *button);
+    void setDefaultButton(QMessageBox::StandardButton button);
+    // 设置窗体标题
+    void setTitle(const QString &title);
+    // 设置提示信息
+    void setText(const QString &text);
+    // 设置窗体图标
+    void setIcon(const QString &icon);
+    // 添加控件-替换提示信息所在的QLabel
+    void addWidget(QWidget *pWidget);
+
+protected:
+    // 多语言翻译
+    void changeEvent(QEvent *event);
+
+private slots:
+    void onButtonClicked(QAbstractButton *button);
+
+private:
+    void translateUI();
+    int execReturnCode(QAbstractButton *button);
+
+private:
+    QLabel *m_pIconLabel;
+    QLabel *m_pLabel;
+    QGridLayout *m_pGridLayout;
+    QDialogButtonBox *m_pButtonBox;
+    QAbstractButton *m_pClickedButton;
+    QAbstractButton *m_pDefaultButton;
+};
+#endif // MESSAGE_BOX_H

+ 54 - 0
Modbus.cpp

@@ -0,0 +1,54 @@
+#include "Modbus.h"
+
+
+void InvertUint8(unsigned char *dBuf, unsigned char *srcBuf)
+{
+    int i;
+    unsigned char tmp[4];
+    tmp[0] = 0;
+    for(i = 0; i < 8; i++)
+    {
+        if(srcBuf[0] & (1 << i))
+            tmp[0] |= 1 << (7 - i);
+    }
+    dBuf[0] = tmp[0];
+}
+
+void InvertUint16(unsigned short *dBuf, unsigned short *srcBuf)
+{
+    int i;
+    unsigned short tmp[4];
+    tmp[0] = 0;
+    for (i = 0; i < 16; i++)
+    {
+        if(srcBuf[0] & (1 << i))
+            tmp[0] |= 1 << (15 - i);
+    }
+    dBuf[0] = tmp[0];
+}
+unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen)
+{
+    int i;
+      unsigned short temp;
+      unsigned short temp1;
+    unsigned short wCRCin = 0xFFFF;
+    unsigned short wCPoly = 0x8005;
+    unsigned char wChar = 0;
+    while(usDataLen--)
+    {
+        wChar = *(puchMsg++);
+        InvertUint8(&wChar, &wChar);
+        wCRCin ^= (wChar << 8);
+        for(i = 0; i < 8; i++)
+        {
+            if(wCRCin & 0x8000)
+                wCRCin = (wCRCin << 1)^wCPoly;
+            else
+                wCRCin = wCRCin << 1;
+        }
+    }
+    InvertUint16(&wCRCin, &wCRCin);
+        temp1=wCRCin>>8&0x00ff;
+        temp=(temp1)+(wCRCin<<8);
+    return(temp);
+}

+ 14 - 0
Modbus.h

@@ -0,0 +1,14 @@
+#ifndef MODBUS_H
+#define MODBUS_H
+
+//继电器控制板modbus 地址
+#define RELAY_ADDRESS  (0x01)
+//比例调节阀modbus 地址
+#define ADJUSTVALVE_ADDRESS  (0x03)
+
+//压力传感器modbus地址
+#define PRESSURESENSOR_ADDRESS     (0x02)
+
+unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen);
+
+#endif // MODBUS_H

+ 64 - 0
Msgbox.cpp

@@ -0,0 +1,64 @@
+#include "Msgbox.h"
+#include "QDebug"
+
+MsgBox::MsgBox(QObject * parent )
+   :QObject(parent), m_btnres(QMessageBox::NoButton) {
+   //qRegisterMetaType<QMessageBox::StandardButtons>("QMessageBox::StandardButtons");
+   //qRegisterMetaType<QMessageBox::StandardButton>("QMessageBox::StandardButton");
+   connect(this, SIGNAL(msgbox_sig(MSGBOXTYPE, QWidget *, const QString, const QString, QMessageBox::StandardButtons, QMessageBox::StandardButton)), SLOT(on_msgbox(MSGBOXTYPE, QWidget *, const QString , const QString, QMessageBox::StandardButtons , QMessageBox::StandardButton )), Qt::BlockingQueuedConnection);
+}
+
+void MsgBox::about(QWidget * parent, const QString &title, const QString &text) {
+   emit msgbox_sig(mbt_about, parent, title, text, QMessageBox::NoButton, QMessageBox::NoButton);
+}
+
+void MsgBox::aboutQt(QWidget *parent, const QString &title) {
+   emit msgbox_sig(mbt_aboutqt, parent, title, tr(""), QMessageBox::NoButton, QMessageBox::NoButton);
+}
+
+int MsgBox::critical(QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons , QMessageBox::StandardButton defaultButton ) {
+   emit msgbox_sig(mbt_critical, parent, title, text, buttons, defaultButton);
+   return m_btnres;
+}
+
+int MsgBox::information(QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons , QMessageBox::StandardButton defaultButton )
+{
+   emit msgbox_sig(mbt_information, parent, title, text, buttons, defaultButton);
+   return m_btnres;
+}
+
+int MsgBox::question(QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons , QMessageBox::StandardButton defaultButton) {
+   emit msgbox_sig(mbt_question, parent, title, text, buttons, defaultButton);
+   return m_btnres;
+}
+
+int MsgBox::warning(QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons , QMessageBox::StandardButton defaultButton) {
+   emit msgbox_sig(mbt_warning, parent, title, text, buttons, defaultButton);
+   return m_btnres;
+}
+
+
+ void MsgBox::on_msgbox(MSGBOXTYPE type, QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) {
+    switch(type) {
+    case mbt_about:
+       QMessageBox::about(parent,title,text);
+       break;
+    case mbt_aboutqt:
+       QMessageBox::aboutQt(parent, title);
+       break;
+    case mbt_critical:
+       m_btnres = QMessageBox::critical(parent, title, text, buttons, defaultButton);
+       break;
+    case mbt_information:
+       m_btnres = QMessageBox::information(parent, title, text, buttons, defaultButton);
+       break;
+    case mbt_question:
+       m_btnres = QMessageBox::question(parent, title, text, buttons, defaultButton);
+       break;
+    case mbt_warning:
+       m_btnres = QMessageBox::warning(parent, title, text, buttons, defaultButton);
+       break;
+    default:
+       Q_ASSERT_X(false,"QMessageBox in thread","invalid box type specified.");
+    }
+ }

+ 44 - 0
Msgbox.h

@@ -0,0 +1,44 @@
+#ifndef MSGBOX_H
+#define MSGBOX_H
+
+#include <QThread>
+#include <QMessageBox>
+
+class MsgBox : public QObject
+{
+   Q_OBJECT
+   typedef enum {
+      mbt_about = 0,
+      mbt_aboutqt = 1,
+      mbt_critical = 2,
+      mbt_information = 3,
+      mbt_question = 4,
+      mbt_warning = 5
+   } MSGBOXTYPE;
+//protected:
+
+ public:
+
+   MsgBox(QObject * parent = 0);
+
+   void about(QWidget * parent, const QString &title, const QString &text);
+   void aboutQt(QWidget *parent, const QString &title = QString());
+
+   int critical(QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+   int information(QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+
+   int question(QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No), QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+
+   int warning(QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+
+
+signals:
+    void msgbox_sig(MSGBOXTYPE type, QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
+
+private slots:
+    void on_msgbox(MSGBOXTYPE type, QWidget * parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
+private:
+    int m_btnres;
+};
+
+#endif // MSGBOX_H

+ 47 - 0
Page1.qml

@@ -0,0 +1,47 @@
+import QtQuick 2.11
+
+Rectangle {
+    id: page1
+    signal message(string msg)
+    width: 300
+    height: 300
+    color: "red"
+
+    MouseArea {
+        anchors.fill: parent
+        onClicked: myItem.message("clicked!");
+    }
+
+    /*
+    function show(){
+        animationShow.running = true
+    }
+
+    function exit(){
+        //BreatheTestJs.exit = true
+        animationExit.running = true
+        //startStopButton.running = false
+        //stopTimer.start()
+    }
+
+    //加载任务动画效果
+    NumberAnimation {
+        id: animationShow
+        target: page
+        property: "x"
+        from: page.x
+        to: 0
+        duration: 50
+    }
+
+    NumberAnimation {
+        id: animationExit
+        target: page
+        property: "x"
+        from: page.x
+        to: 1024
+        duration: 50
+    }
+
+    */
+}

+ 50 - 0
Page2.qml

@@ -0,0 +1,50 @@
+import QtQuick 2.11
+
+Rectangle {
+     id:page2
+    width: parent.width
+    height: parent.height
+    color: "blue"
+    Text {
+        anchors.centerIn: parent
+        text: "Page2 Test"
+    }
+    focus: true
+    Keys.onPressed: {
+        console.log("Loaded item captured: ", event.text);
+        event.accepted = true;
+    }
+
+    /*
+    function show(){
+        animationShow.running = true
+        console.log("Loaded page2 show ");
+    }
+
+    function exit(){
+        //BreatheTestJs.exit = true
+        animationExit.running = true
+        //startStopButton.running = false
+        //stopTimer.start()
+    }
+
+    //加载任务动画效果
+    NumberAnimation {
+        id: animationShow
+        target: page
+        property: "x"
+        from: page.x
+        to: 0
+        duration: 500
+    }
+    NumberAnimation {
+        id: animationExit
+        target: page
+        property: "x"
+        from: page.x
+        to: 1024
+        duration: 500
+    }
+*/
+
+}

+ 81 - 0
PageDefault.qml

@@ -0,0 +1,81 @@
+import QtQuick 2.11
+
+Item  {
+    id: root
+    property bool isFirst : false;
+    //width: 200
+    //height: 200
+    //color: "blue"
+    //anchors.fill: parent
+
+
+
+    Loader {
+        id: pageLoader
+        anchors.fill: parent
+        //source: "Page2.qml"
+        //sourceComponent: defaultPage
+        focus: true
+        onStatusChanged:  console.log(pageLoader.status == Loader.Ready)
+        onLoaded: console.log("Loaded")
+    }
+
+    MouseArea {
+        id:mousearea
+        anchors.fill: parent
+
+    }
+
+    function show(){
+        pageLoader.source = "Page2.qml"
+        //pageLoader.item.show()
+        console.log("pagedefault show")
+    }
+
+
+
+    Connections{
+        target: mousearea
+        onClicked: root.changePage()
+    }
+
+
+    function changePage()
+    {
+        if(isFirst) {
+            pageLoader.source = "Page1.qml"
+        } else {
+            pageLoader.source = "Page2.qml"
+        }
+
+        isFirst = !isFirst;
+    }
+
+
+
+    Component {
+        id: defaultPage
+        Rectangle {
+            width: 200
+            height: 50
+            color: "red"
+            Text {
+                text: "Default Page"
+                anchors.fill: parent
+            }
+        }
+    }
+
+    Keys.onPressed: {
+        console.log("Captured: ", event.text);
+         event.accepted = true;
+    }
+
+/*
+    Component.onCompleted: {
+        rect1.changePage()
+    }
+
+    */
+}
+

+ 15 - 0
PageFirst.qml

@@ -0,0 +1,15 @@
+import QtQuick 2.11
+import QtQuick.Controls 2.3
+
+Rectangle {
+    width: 400
+    height: 300
+    color: "#051f58"
+    radius: 8
+
+    Button {
+        text: "登录页面-登录按钮"
+        anchors.centerIn: parent
+        onClicked: myLoder.sourceComponent = mainpage // 切换显示主页面
+    }
+}

+ 429 - 0
PageMain.qml

@@ -0,0 +1,429 @@
+import QtQuick 2.15
+import QtQuick.Window 2.15
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+import QtQuick.Dialogs 1.3
+import QtQuick.Controls.Styles 1.4
+import QtQuick.VirtualKeyboard 2.15
+
+import TService 1.0
+
+Rectangle{
+    id:root
+    //anchors.fill:parent
+
+    Item{
+        id:rootitem
+        anchors.fill:parent
+
+        enum Page_Type {
+            Page_Type_Settings,
+            Page_Type_Testing,
+            Page_Type_ValveTest
+        }
+
+        SwipeView {
+            id: swipeView
+            //anchors.fill: parent
+            width: main_window.width
+            height: main_window.height
+
+            currentIndex: 0
+            y: !inputPanel.active ? 0 : Math.min(0, main_window.height - inputPanel.height - activeFocusItemBottom)
+            Behavior on y {
+                NumberAnimation {
+                    duration: 250
+                    easing.type: Easing.InOutQuad
+                }
+            }
+
+            PageSetting {
+                id:page_set
+            }
+
+            PageTest {
+                id:pagetest
+                //visible: false;
+            }
+
+
+            function changePages(compartment_num){
+                console.log("changePages num : "+compartment_num)
+                removePage(pagetest)
+
+                if(compartment_num>7){
+                    addPage(page_recoveryvalve1)
+                    addPage(page_recoveryvalve2)
+                    addPage(page_recoveryvalve3)
+                    addPage(page_recoveryvalve4)
+                    addPage(page_recoveryvalve5)
+                    addPage(page_recoveryvalve6)
+                    addPage(page_recoveryvalve7)
+                    addPage(page_recoveryvalve8)
+                }else if(compartment_num>6){
+                    removePage(page_recoveryvalve8)
+                    addPage(page_recoveryvalve1)
+                    addPage(page_recoveryvalve2)
+                    addPage(page_recoveryvalve3)
+                    addPage(page_recoveryvalve4)
+                    addPage(page_recoveryvalve5)
+                    addPage(page_recoveryvalve6)
+                    addPage(page_recoveryvalve7)
+                }else if(compartment_num>5){
+                    removePage(page_recoveryvalve8)
+                    removePage(page_recoveryvalve7)
+                    addPage(page_recoveryvalve1)
+                    addPage(page_recoveryvalve2)
+                    addPage(page_recoveryvalve3)
+                    addPage(page_recoveryvalve4)
+                    addPage(page_recoveryvalve5)
+                    addPage(page_recoveryvalve6)
+                }else if(compartment_num>4){
+                    removePage(page_recoveryvalve8)
+                    removePage(page_recoveryvalve7)
+                    removePage(page_recoveryvalve6)
+                    addPage(page_recoveryvalve1)
+                    addPage(page_recoveryvalve2)
+                    addPage(page_recoveryvalve3)
+                    addPage(page_recoveryvalve4)
+                    addPage(page_recoveryvalve5)
+                }else if(compartment_num>3){
+                    removePage(page_recoveryvalve8)
+                    removePage(page_recoveryvalve7)
+                    removePage(page_recoveryvalve6)
+                    removePage(page_recoveryvalve5)
+                    addPage(page_recoveryvalve1)
+                    addPage(page_recoveryvalve2)
+                    addPage(page_recoveryvalve3)
+                    addPage(page_recoveryvalve4)
+                }else if(compartment_num>2){
+                    removePage(page_recoveryvalve8)
+                    removePage(page_recoveryvalve7)
+                    removePage(page_recoveryvalve6)
+                    removePage(page_recoveryvalve5)
+                    removePage(page_recoveryvalve4)
+                    addPage(page_recoveryvalve1)
+                    addPage(page_recoveryvalve2)
+                    addPage(page_recoveryvalve3)
+                }else if(compartment_num>1){
+                    removePage(page_recoveryvalve8)
+                    removePage(page_recoveryvalve7)
+                    removePage(page_recoveryvalve6)
+                    removePage(page_recoveryvalve5)
+                    removePage(page_recoveryvalve4)
+                    removePage(page_recoveryvalve3)
+                    addPage(page_recoveryvalve1)
+                    addPage(page_recoveryvalve2)
+                }else if(compartment_num>0){
+                    removePage(page_recoveryvalve8)
+                    removePage(page_recoveryvalve7)
+                    removePage(page_recoveryvalve6)
+                    removePage(page_recoveryvalve5)
+                    removePage(page_recoveryvalve4)
+                    removePage(page_recoveryvalve3)
+                    removePage(page_recoveryvalve2)
+                    addPage(page_recoveryvalve1)
+                }
+
+                addPage(pagetest)
+            }
+
+            function addPage(page){
+
+                for(var n=0; n<count; n++){
+                    if(page === itemAt(n))
+                        return
+                }
+
+                addItem(page)
+                page.visible = true
+            }
+
+            function removePage(page){
+                for(var n=0; n<count; n++){
+                    if(page === itemAt(n))
+                        takeItem(n)
+                }
+
+                page.visible = false
+            }
+
+            Component.onCompleted: {
+                //page_set.show()
+                //currentIndex=0
+            }
+
+        }
+
+        PageIndicator {
+            id: indicator
+            count: swipeView.count
+
+            currentIndex: swipeView.currentIndex
+            anchors.bottom: swipeView.bottom
+            anchors.horizontalCenter: parent.horizontalCenter
+
+            //interactive: true
+        }
+
+        Component.onCompleted: {
+            testService.init()
+            StandardManager.init()
+
+        }
+
+
+    }
+
+
+    RecoveryValve {
+        id:page_recoveryvalve1
+        compartment_id: 1
+        volume: 0
+        visible: false
+
+    }
+
+
+    RecoveryValve {
+        id:page_recoveryvalve2
+         compartment_id: 2
+         volume: 0
+         visible: false
+
+    }
+
+    RecoveryValve {
+        id:page_recoveryvalve3
+         compartment_id: 3
+         volume: 0
+         visible: false
+
+    }
+    RecoveryValve {
+        id:page_recoveryvalve4
+         compartment_id: 4
+         volume: 0
+         visible: false
+
+    }
+    RecoveryValve {
+        id:page_recoveryvalve5
+         compartment_id: 5
+         volume: 0
+         visible: false
+
+    }
+    RecoveryValve {
+        id:page_recoveryvalve6
+         compartment_id: 6
+         volume: 0
+         visible: false
+
+    }
+    RecoveryValve {
+        id:page_recoveryvalve7
+         compartment_id: 7
+         volume: 0
+         visible: false
+
+    }
+    RecoveryValve {
+        id:page_recoveryvalve8
+         compartment_id: 8
+         volume: 0
+         visible: false
+
+    }
+
+    //PageStandard {
+    //    id:pagestandard
+    //    visible: false
+
+    //}
+
+
+    Log{
+        id:log
+        z:10
+        width: 300
+        height: 50
+        anchors.centerIn: parent
+    }
+
+    Log{
+        id:genreportprogress
+        z:20
+        width: 300
+        height: 50
+        anchors.centerIn: parent
+    }
+
+    TestService{
+        id:testService
+    }
+
+
+
+    Component.onCompleted: {
+        //page_set.show()
+
+        testService.onNotice.connect(qmlProcessNotice);
+        testService.onWarning.connect(qmlProcessWarning);
+        testService.sigPressure.connect(qmlProcessPressure);
+
+        testService.sigState.connect(qmlProcessState);
+        testService.sigSystemResult.connect(qmlProcessSystemResult);
+        testService.sigValveResult.connect(qmlProcessValveResult);
+        testService.sigSelfTestResult.connect(qmlProcessSelfResult);
+        testService.onGenreportProgress.connect(qmlProcessReportProgress);
+
+        testService.sigStop.connect(qmlProcessStop);
+
+        console.log("main.qml tservice init: 222" )
+    }
+
+    function delay(duration) { // In milliseconds
+        var timeStart = new Date().getTime();
+
+        while (new Date().getTime() - timeStart < duration) {
+            // Do nothing
+        }
+
+        // Duration has passed
+    }
+
+    function qmlProcessReportProgress(str){
+
+        console.log("main.qml tservice qmlProcessReportProgress:", str )
+
+        if(str === "close"){
+            genreportprogress.exit()
+        }else{
+            genreportprogress.show(str)
+        }
+
+    }
+
+    function qmlProcessNotice(str){
+        console.log("main.qml tservice qmlProcessNotice: enter [%s]", str )
+        log.show(str)
+
+    }
+
+    function qmlProcessWarning(str){
+        console.log("main.qml tservice init: 222 [%s]", str )
+        //log.show2(str)
+        //id_mesDialog.text = str+", 是否继续?";
+        //id_mesDialog.open()
+    }
+
+    function getTestPage(id){
+        var page_var
+        switch(id){
+        case 1:page_var = page_recoveryvalve1
+            break
+        case 2:page_var = page_recoveryvalve2
+            break
+        case 3:page_var = page_recoveryvalve3
+            break
+        case 4:page_var = page_recoveryvalve4
+            break
+        case 5:page_var = page_recoveryvalve5
+            break
+        case 6:page_var = page_recoveryvalve6
+            break
+        case 7:page_var = page_recoveryvalve7
+            break
+        case 8:page_var = page_recoveryvalve8
+            break
+        default:
+            page_var = page_recoveryvalve1
+            break;
+        }
+
+        return page_var
+    }
+
+    function qmlProcessPressure(id, map){
+        console.log("main.qml qmlProcessPressure  [%d] []",id )
+        //log.show2(str)
+        //var textstring = ''
+        //var varmap = map
+        //textstring += map.pressure+":"
+        //textstring += map.direction.toString()+":"
+        //textstring += map.stage.toString()+":"
+        //textstring += map.step.toString()+":"
+
+        //console.log("main.qml qmlProcessPressure :",textstring.toString() )
+
+        if((id >= 1) &&(id<=8)){
+            var page_var = getTestPage(id)
+
+            //page_var.pressure = str
+            //page_var.add_record(str)
+            //page_var.pressureDisplayInput(str)
+            page_var.update_pressure(map);
+        }else if(id === 0){
+            pagetest.show_pressure(map.pressure)
+        }
+
+
+        //console.log("show compartment ",id, str )
+
+    }
+
+    function qmlProcessState(id, str1, str2){
+        if((id >= 1) &&(id<=8)){
+            var page_var = getTestPage(id)
+            page_var.update_runstate(str1, str2)
+        }else if(id === 0){
+            pagetest.show_selftestState(str1)
+            console.log("qmlProcessState pagetest ",id, str1 )
+        }
+
+    }
+
+    function qmlProcessSystemResult(id, str, bPassed){
+        if((id >= 1) &&(id<=8)){
+            var page_var = getTestPage(id)
+            page_var.show_systemresult(str, bPassed)
+        }
+
+    }
+
+    function qmlProcessValveResult(id, str, bPassed){
+
+        if((id >= 1) &&(id<=8)){
+            var page_var = getTestPage(id)
+            page_var.show_valveresult(str, bPassed)
+        }
+
+    }
+
+    function qmlProcessSelfResult(id, str, bPassed){
+        if(id === 0){
+            if(bPassed){
+                pagetest.show_selftestResult("通过")
+            }else{
+                pagetest.show_selftestResult("未通过")
+            }
+        }
+
+    }
+
+
+
+    function qmlProcessStop(id){
+        if((id >= 1) &&(id<=8)){
+            var page_var = getTestPage(id)
+            page_var.test_stoped()
+        }else if(id === 0){
+            pagetest.selftestStop()
+            console.log("qmlProcessStop pagetest ",id )
+        }
+    }
+
+}
+
+

+ 785 - 0
PageSetting.qml

@@ -0,0 +1,785 @@
+import QtQuick 2.15
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+import QtQuick.Controls.Styles 1.2
+import Qt.labs.qmlmodels 1.0
+import TService 1.0
+
+Item{
+    id: root
+    //anchors.fill: parent
+    //width:1024
+    //height: 768
+    //anchors.centerIn: parent
+
+    property var pagetype:rootitem.Page_Type_Settings
+
+    property  string title_str:"信息录入"
+    property string standard_name:"国标"
+    property string company:""
+    property string licenseplate: ""
+    property int compartment_num: 1
+    property int total_volume: 0
+    property var volume_arry: [0,0,0,0,0,0,0,0]
+
+
+
+/*
+    Loader{
+        id:loader
+        anchors.fill: parent
+        anchors.margins: 0
+        sourceComponent: componet
+    }
+    */
+
+/*
+    function show(){
+        if(loader.sourceComponent  === null){
+            loader.sourceComponent  = componet
+            console.debug("avans 1111")
+        }
+        loader.item.show()
+    }
+
+    function exit(){
+        if(loader.sourceComponent  !== null){
+            loader.item.exit()
+        }
+    }
+*/
+    function update_standard(){
+        var jsonObj = StandardManager.get_names();
+
+         lmd.clear()
+        for(var i=0; i<jsonObj.num; i++){
+            //console.log("name ===="+jsonArry.names[i]);
+            lmd.append({text:jsonObj.names[i]})
+        }
+
+        standard_name_comboBox.currentIndex = 0
+    }
+
+    function caculate_volume(){
+        if(root.total_volume > 0 && root.compartment_num >0){
+            var vol = root.total_volume/root.compartment_num;
+            var volume = parseInt(vol)
+            if(1 == root.compartment_num){
+                rectvolume_1.text=volume
+                rectvolume_2.text=0
+                rectvolume_3.text=0
+                rectvolume_4.text=0
+                rectvolume_5.text=0
+                rectvolume_6.text=0
+                rectvolume_7.text=0
+                rectvolume_8.text=0
+
+            }else if(2 == root.compartment_num){
+                rectvolume_1.text=volume
+                rectvolume_2.text=root.total_volume-volume
+                rectvolume_3.text=0
+                rectvolume_4.text=0
+                rectvolume_5.text=0
+                rectvolume_6.text=0
+                rectvolume_7.text=0
+                rectvolume_8.text=0
+            }else if(3 == root.compartment_num){
+                rectvolume_1.text=volume
+                rectvolume_2.text=volume
+                rectvolume_3.text=root.total_volume-volume*2
+                rectvolume_4.text=0
+                rectvolume_5.text=0
+                rectvolume_6.text=0
+                rectvolume_7.text=0
+                rectvolume_8.text=0
+            }else if(4 == root.compartment_num){
+                rectvolume_1.text=volume
+                rectvolume_2.text=volume
+                rectvolume_3.text=volume
+                rectvolume_4.text=root.total_volume-volume*3
+                rectvolume_5.text=0
+                rectvolume_6.text=0
+                rectvolume_7.text=0
+                rectvolume_8.text=0
+            }else if(5 == root.compartment_num){
+                rectvolume_1.text=volume
+                rectvolume_2.text=volume
+                rectvolume_3.text=volume
+                rectvolume_4.text=volume
+                rectvolume_5.text=root.total_volume-volume*4
+                rectvolume_6.text=0
+                rectvolume_7.text=0
+                rectvolume_8.text=0
+            }else if(6 == root.compartment_num){
+                rectvolume_1.text=volume
+                rectvolume_2.text=volume
+                rectvolume_3.text=volume
+                rectvolume_4.text=volume
+                rectvolume_5.text=volume
+                rectvolume_6.text=root.total_volume-volume*5
+                rectvolume_7.text=0
+                rectvolume_8.text=0
+            }else if(7 == root.compartment_num){
+                rectvolume_1.text=volume
+                rectvolume_2.text=volume
+                rectvolume_3.text=volume
+                rectvolume_4.text=volume
+                rectvolume_5.text=volume
+                rectvolume_6.text=volume
+                rectvolume_7.text=root.total_volume-volume*6
+                rectvolume_8.text=0
+            }else if(8 == root.compartment_num){
+                rectvolume_1.text=volume
+                rectvolume_2.text=volume
+                rectvolume_3.text=volume
+                rectvolume_4.text=volume
+                rectvolume_5.text=volume
+                rectvolume_6.text=volume
+                rectvolume_7.text=volume
+                rectvolume_8.text=root.total_volume-volume*7
+            }
+        }
+    }
+
+    function check_invalid(){
+        var valid = true
+        if(0 == licenseplate.length){
+            valid = false
+            log.show("车牌不能为空")
+            return valid
+        }
+
+        if(0 == company.length){
+            valid = false
+            log.show("车辆单位不能为空")
+            return valid
+        }
+
+        if(0 == total_volume){
+            valid = false
+            log.show("容积不能为空")
+            return valid
+        }
+        if(0 == compartment_num){
+            valid = false
+            log.show("仓数不能为空")
+            return valid
+        }
+
+        var all_volume = 0
+        for(var i=0; i<compartment_num; i++){
+            all_volume = all_volume + volume_arry[i]
+        }
+
+        if(all_volume !== total_volume){
+            valid = false
+            log.show("体积总容量与每仓数据不匹配")
+        }
+
+        return valid
+    }
+
+
+   // Component{
+    //    id:componet
+        DynamicGroupBox{
+            id:groupbox
+
+            //width: 1020
+            //height: 760
+
+            anchors.centerIn: parent
+            anchors.fill: parent
+
+            title: title_str
+
+/*
+            function show(){
+                animationShow.running = true
+            }
+
+            function exit(){
+                //BreatheTestJs.exit = true
+                animationExit.running = true
+                //startStopButton.running = false
+                //stopTimer.start()
+            }
+
+            //加载任务动画效果
+            NumberAnimation {
+                id: animationShow
+                target: groupbox
+                property: "x"
+                from: groupbox.x
+                to: 0
+                duration: 500
+            }
+            NumberAnimation {
+                id: animationExit
+                target: groupbox
+                property: "x"
+                from: groupbox.x
+                to: 1024
+                duration: 500
+            }
+
+*/
+            ColumnLayout{
+                spacing:2
+
+                Rectangle{
+                    Layout.alignment: Qt.AlignCenter
+                    //Layout.fillWidth: true
+                    color: "transparent"
+
+                    Layout.preferredHeight: 600
+                    Layout.preferredWidth: 1240
+
+                    Row{
+
+                        anchors.centerIn: parent
+                        spacing:10
+
+                        Column{
+                            spacing:20
+
+                        DynamicGroupBox{
+                            id:standard_select
+                            title: "标准选择:"
+                            //anchors.centerIn: parent
+
+                            width: 360
+                            height: 160
+
+                            Column{
+                                //spacing:5
+                               // anchors.centerIn: parent
+
+                                Rectangle{
+                                    width:320
+                                    height: 30
+                                    color: "transparent"
+                                    Row{
+                                        spacing:30
+                                        Label{
+                                            text: "执行标准"
+                                            //font.pixelSize: 24
+                                            font.bold: true
+                                            font.pixelSize: 20
+                                            //color: "red"
+
+                                        }
+
+                                        UserComboBox{
+                                           id:standard_name_comboBox
+                                           //anchors.fill:parent
+                                           implicitWidth: 100
+                                           implicitHeight: 30
+                                           bgColor:"#D2D5D9"
+                                           model: ListModel{
+                                                id:lmd
+                                           }
+                                           onCurrentTextChanged: {
+                                               root.standard_name = currentText
+                                               console.log("choose standard: "+root.standard_name)
+                                           }
+
+                                        }
+                                    }
+
+                                }
+
+                                UserButton{
+                                       text: "标准管理"
+                                       font.pixelSize: 20
+
+                                       implicitHeight: 120
+                                       implicitWidth: 160
+
+                                       //Layout.leftMargin: -30
+                                       //Layout.topMargin: 10
+                                       onClicked: {
+                                           var compMainPage = Qt.createComponent("PageStandard.qml")
+                                                       .createObject(main_window, {x:0, y:0, width:main_window.width, height:main_window.height});
+
+                                       }
+                                }
+
+                            }
+/*
+                        GridLayout{
+                            anchors.centerIn: parent
+                            columns: 2
+                            rows:2
+                            //columnSpacing:  10
+                            //rowSpacing: 5
+                            //Layout.rowSpan: 10
+                            Label{
+                                text: "执行标准"
+                                //width:120
+                                //height: 40
+                                //font.pixelSize: 24
+                                font.bold: true
+                                font.pixelSize: 20
+                                //color: "red"
+
+                            }
+
+                            //Rectangle{
+                            //    id:rectcom1
+                            //    implicitWidth: 100
+                            //    implicitHeight:30
+                                UserComboBox{
+                                   id:standard_name_comboBox
+                                   //anchors.fill:parent
+                                   implicitWidth: 100
+                                   implicitHeight: 30
+                                   bgColor:"#D2D5D9"
+                                   model: ListModel{
+                                        id:lmd
+                                   }
+                                   onCurrentTextChanged: {
+                                       root.standard_name = currentText
+                                       console.log("choose standard: "+root.standard_name)
+                                   }
+
+                                }
+
+                           // }
+
+                            UserButton{
+                                   text: "标准管理"
+                                   font.pixelSize: 24
+
+                                   implicitHeight: 120
+                                   implicitWidth: 140
+
+                                   //Layout.leftMargin: -30
+                                   //Layout.topMargin: 10
+                                   onClicked: {
+                                       var compMainPage = Qt.createComponent("PageStandard.qml")
+                                                   .createObject(main_window, {x:0, y:0, width:main_window.width, height:main_window.height});
+
+                                   }
+                            }
+                        }
+*/
+                        }
+
+                        DynamicGroupBox{
+                            id:tankinfo
+                            title: "罐车信息"
+
+                            width: 360
+                            height: 320
+                            //anchors.centerIn: parent
+                            //Layout.horizontalCenter: parent.horizontalCenter
+                            //Layout.verticalCenter: parent.verticalCenter
+
+                        ColumnLayout{
+
+                            anchors.centerIn: parent
+                            spacing: 20
+
+                            Column{
+                                    spacing: 10
+                                    //Layout.alignment: Qt.AlignLeft
+
+                                    InputLine{
+                                        id:manufactureInputLine
+                                        paraName: "  车辆单位:"
+                                        paraLength: 200
+                                        onTextChanged: {
+                                            root.company = text
+                                        }
+                                    }
+
+                                    InputLine{
+                                        id:carplate
+                                        paraName: "    车牌号:"
+                                        paraLength: 200
+                                        onTextChanged: {
+                                            root.licenseplate = text
+                                        }
+                                    }
+
+                                    InputLine{
+                                        id:t_volume
+                                        paraName: "总容积 (L):"
+                                        text: "0"
+                                        paraLength: 200
+                                        validator:RegExpValidator {
+                                            regExp: /[0-9]*/
+                                        }
+                                        onTextChanged: {
+                                            if(text.length > 0){
+                                                root.total_volume = Number(text)
+                                                if(0 == root.compartment_num){
+                                                    compartment.text = "1"
+                                                }
+                                                root.caculate_volume()
+                                            }else{
+                                                root.total_volume=0
+                                            }
+                                        }
+                                    }
+
+                                    InputLine{
+                                        id:compartment
+                                        paraName: "  仓    数:"
+                                        text: "1"
+                                        paraLength: 200
+
+                                        validator:IntValidator {
+                                            bottom:1;
+                                            top:8
+                                        }
+                                        onTextChanged: {
+                                            if(text.length > 0){
+                                                var n = Number(text);
+                                                if(n >0 && n<5 ){
+                                                    root.compartment_num = Number(text)
+
+                                                    root.caculate_volume()
+                                                    //console.log("compartment:"+text)
+                                                }else{
+                                                    if(n >4){
+                                                        log.show("仓数不能大于4")
+                                                        text="4"
+                                                    }
+                                                    if(n === 0){
+                                                        text="1"
+                                                    }
+                                                }
+                                            }else{
+                                                root.compartment_num=0;
+                                            }
+                                        }
+                                    }
+
+                                }
+
+                            GridLayout{
+                            //anchors.centerIn: parent
+                            columns: 2
+                            rows:4
+                            columnSpacing:  20
+                            rowSpacing: 5
+
+                            //Layout.rowSpan: 5
+
+                            InputLine{
+                                id:rectvolume_1
+                                paraName: "1仓:"
+                                text: "0"
+                                paraLength: 60
+                                validator:RegExpValidator {
+                                    regExp: /[0-9]*/
+                                }
+                                onTextChanged: {
+                                    root.volume_arry[0] = Number(text)
+                                    //console.log("1:volume[%d]", root.volume_arry[0])
+                                }
+                            }
+
+                            InputLine{
+                                id:rectvolume_2
+                                paraName: "2仓:"
+                                text: "0"
+                                paraLength: 60
+                                validator:RegExpValidator {
+                                    regExp: /[0-9]*/
+                                }
+                                onTextChanged: {
+                                    root.volume_arry[1] = Number(text)
+                                }
+                            }
+                            InputLine{
+                                id:rectvolume_3
+                                paraName: "3仓:"
+                                text: "0"
+                                paraLength: 60
+                                validator:RegExpValidator {
+                                    regExp: /[0-9]*/
+                                }
+                                onTextChanged: {
+                                    root.volume_arry[2] = Number(text)
+                                }
+                            }
+                            InputLine{
+                                id:rectvolume_4
+                                paraName: "4仓:"
+                                text: "0"
+                                paraLength: 60
+                                validator:RegExpValidator {
+                                    regExp: /[0-9]*/
+                                }
+                                onTextChanged: {
+                                    root.volume_arry[3] = Number(text)
+                                }
+                            }
+
+                            InputLine{
+                                id:rectvolume_5
+                                paraName: "5仓:"
+                                text: "0"
+                                paraLength: 60
+                                visible: false
+                                validator:RegExpValidator {
+                                    regExp: /[0-9]*/
+                                }
+                                onTextChanged: {
+                                    root.volume_arry[4] = Number(text)
+                                }
+                            }
+                            InputLine{
+                                id:rectvolume_6
+                                paraName: "6仓:"
+                                text: "0"
+                                paraLength: 60
+                                visible: false
+                                validator:RegExpValidator {
+                                    regExp: /[0-9]*/
+                                }
+                                onTextChanged: {
+                                    root.volume_arry[5] = Number(text)
+                                }
+                            }
+                            InputLine{
+                                id:rectvolume_7
+                                paraName: "7仓:"
+                                text: "0"
+                                paraLength: 60
+                                visible: false
+                                validator:RegExpValidator {
+                                    regExp: /[0-9]*/
+                                }
+                                onTextChanged: {
+                                    root.volume_arry[6] = Number(text)
+                                }
+                            }
+                            InputLine{
+                                id:rectvolume_8
+                                paraName: "8仓:"
+                                text: "0"
+                                paraLength: 60
+                                visible: false
+                                validator:RegExpValidator {
+                                    regExp: /[0-9]*/
+                                }
+                                onTextChanged: {
+                                    root.volume_arry[7] = Number(text)
+                                }
+                            }
+
+                        }
+
+                        }
+                        }
+
+                        }
+                        DynamicGroupBox{
+                            id:visual_inspection
+                            title: "外观检查"
+                            //anchors.centerIn: parent
+
+                            width: 820
+                            height: 500
+
+                            Row{
+                                spacing:10
+                                DynamicGroupBox{
+                                    id:visual_VRS
+                                    title: "油气回收系统"
+                                    titleFontPixel:18
+                                    //anchors.centerIn: parent
+
+                                    width: 390
+                                    height: 450
+
+                                    UserTableView{
+                                        id:table_vrs
+                                        table_name: "vrs"
+                                        anchors.fill:parent
+
+                                    }
+
+                                }
+
+                                DynamicGroupBox{
+                                    id:visual_BLS
+                                    title: "底部装油系统"
+                                    titleFontPixel:18
+                                    //anchors.centerIn: parent
+
+                                    width: 390
+                                    height: 450
+
+                                    UserTableView{
+                                        id:table_bls
+                                        table_name: "bls"
+                                        anchors.fill:parent
+
+                                    }
+                                }
+
+                            }
+                        }
+                    }
+
+                }
+
+                Rectangle{
+                    Layout.alignment: Qt.AlignBottom
+                    Layout.fillWidth: true
+                    color: "transparent"
+                    Layout.preferredHeight: 100
+                    Layout.preferredWidth: 300
+
+                    UserButton {
+                        id: prev_step
+                        text: "返回首页"
+                        height: 80
+                        width: 180
+                        font.pixelSize: 24
+                        anchors.left: parent.left;
+                        anchors.leftMargin: 40;
+                        anchors.bottom: parent.bottom;
+                        anchors.bottomMargin: 10;
+
+                        onClicked: myLoder.sourceComponent = null // 切换显示主页面
+                    }
+
+                    UserButton {
+
+                        id: next_step;
+                        text: "开始检测";
+                        //visible: false
+                        font.pixelSize: 24
+                        anchors.right: parent.right;
+                        anchors.rightMargin: 60;
+                        anchors.bottom: parent.bottom;
+                        anchors.bottomMargin: 10;
+                        height: 80
+                        width: 180
+
+                        onClicked: {
+                            //log.show(utr.state)
+                            //console.log("state ===="+utr.state);
+
+                            if(root.check_invalid()){
+                                var infoArry = [];
+                                standard_name = standard_name_comboBox.currentText;
+                                infoArry.push(standard_name)
+                                infoArry.push(licenseplate);
+                                infoArry.push(company);
+                                infoArry.push(total_volume);
+                                infoArry.push(compartment_num);
+                                for(var i=0; i<8; i++){
+                                    infoArry.push(volume_arry[i])
+                                }
+
+                                var ret = testService.setTankinfo(infoArry);
+                                if(false === ret){
+                                    log.show("设置罐车参数不成功")
+                                }else{
+
+                                    for(var n=0; n<8; n++){
+                                        switch(n){
+                                        case 0:
+                                            page_recoveryvalve1.volume = volume_arry[n]
+                                            page_recoveryvalve1.organize = company
+                                            page_recoveryvalve1.carplate = licenseplate
+                                            page_recoveryvalve1.total_volume = total_volume
+                                            break
+                                        case 1:
+                                            page_recoveryvalve2.volume = volume_arry[n]
+                                            page_recoveryvalve2.organize = company
+                                            page_recoveryvalve2.carplate = licenseplate
+                                            page_recoveryvalve2.total_volume = total_volume
+                                            break
+                                        case 2:
+                                            page_recoveryvalve3.volume = volume_arry[n]
+                                            page_recoveryvalve3.organize = company
+                                            page_recoveryvalve3.carplate = licenseplate
+                                            page_recoveryvalve3.total_volume = total_volume
+                                            break
+                                        case 3:
+                                            page_recoveryvalve4.volume = volume_arry[n]
+                                            page_recoveryvalve4.organize = company
+                                            page_recoveryvalve4.carplate = licenseplate
+                                            page_recoveryvalve4.total_volume = total_volume
+                                            break
+                                        case 4:
+                                            page_recoveryvalve5.volume = volume_arry[n]
+                                            page_recoveryvalve5.organize = company
+                                            page_recoveryvalve5.carplate = licenseplate
+                                            page_recoveryvalve5.total_volume = total_volume
+                                            break
+                                        case 5:
+                                            page_recoveryvalve6.volume = volume_arry[n]
+                                            page_recoveryvalve6.organize = company
+                                            page_recoveryvalve6.carplate = licenseplate
+                                            page_recoveryvalve6.total_volume = total_volume
+                                            break
+                                        case 6:
+                                            page_recoveryvalve7.volume = volume_arry[n]
+                                            page_recoveryvalve7.organize = company
+                                            page_recoveryvalve7.carplate = licenseplate
+                                            page_recoveryvalve7.total_volume = total_volume
+                                            break
+                                        case 7:
+                                            page_recoveryvalve8.volume = volume_arry[n]
+                                            page_recoveryvalve8.organize = company
+                                            page_recoveryvalve8.carplate = licenseplate
+                                            page_recoveryvalve8.total_volume = total_volume
+                                            break
+
+                                        }
+
+                                    }
+
+                                    swipeView.changePages(compartment_num)
+                                    swipeView.incrementCurrentIndex();
+                                    //swipeView.incrementCurrentIndex();
+                                }
+
+                            }else{
+                                //log.show("体积或仓数,不正确")
+                            }
+
+                        }
+                    }
+
+
+                }
+            }
+
+
+            }
+      //  }
+
+        Component.onCompleted: {
+
+            var jsonObj = StandardManager.get_names()
+
+             lmd.clear()
+            for(var i=0; i<jsonObj.num; i++){
+                //console.log("name ===="+jsonArry.names[i]);
+                lmd.append({text:jsonObj.names[i]})
+            }
+
+            standard_name_comboBox.currentIndex = 0
+
+            var jsonObj_vrs = testService.get_vrs_items()
+            for(var j=0; j<jsonObj_vrs.count; j++){
+                table_vrs.add_item(jsonObj_vrs.item[j])
+            }
+
+            var jsonObj_bls = testService.get_bls_items()
+            for( j=0; j<jsonObj_bls.count; j++){
+                table_bls.add_item(jsonObj_bls.item[j])
+            }
+
+        }
+    }

+ 477 - 0
PageStandard.qml

@@ -0,0 +1,477 @@
+import QtQuick 2.15
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+import QtQuick.Controls.Styles 1.2
+import TService 1.0
+
+
+Item {
+    id: standard_root
+    //property var pagetype:rootitem.Page_Type_Testing
+    property  string title_str:"标准管理"
+    property int para_len: 80
+
+    property string stdname_str:""
+    property double std_PTV: 0.0
+    property double std_NTV: 0.0
+
+    property var volume: [0,0,0,0]
+    property var s_threshold: [0.0, 0.0, 0.0, 0.0]
+    property var v_threshold: [0.0, 0.0, 0.0, 0.0]
+
+
+
+    function check_volume(){
+
+        for(var i=0; i<4-1; i++){
+            var v = volume[i]
+            for(var j=i+1; j<4; j++){
+                if(v < volume[j]){
+                    return false
+                }
+            }
+        }
+
+        return true
+
+    }
+
+    function update_listView(){
+        var jsonObj = StandardManager.get_names();
+
+        lmd.clear()
+
+        for(var i=0; i<jsonObj.num; i++){
+            lmd.append({text:jsonObj.names[i]})
+        }
+
+    }
+
+    function update_detail(){
+        var jsontmp = standard_listView.model.get(standard_listView.currentIndex)
+        //console.log("the index = "+index+", standardname = "+ jsontmp.text);
+        jsontmp = StandardManager.get_standard(jsontmp.text);
+        //console.log("the count = " + jsontmp.count +", json str:"+ JSON.stringify(jsontmp));
+
+        std_name.text = jsontmp.name
+        std_positive_target.text = jsontmp.ptv
+        std_negative_target.text = jsontmp.ntv
+
+        if(jsontmp.count === 1){
+           level1_v.text = jsontmp.item[0].volume
+           level1_st.text = jsontmp.item[0].s_threshold
+           level1_vt.text = jsontmp.item[0].v_threshold
+
+        }else if(jsontmp.count === 2){
+            level1_v.text = jsontmp.item[0].volume
+            level1_st.text = jsontmp.item[0].s_threshold
+            level1_vt.text = jsontmp.item[0].v_threshold
+
+            level2_v.text = jsontmp.item[1].volume
+            level2_st.text = jsontmp.item[1].s_threshold
+            level2_vt.text = jsontmp.item[1].v_threshold
+
+        }else if(jsontmp.count === 3){
+            level1_v.text = jsontmp.item[0].volume
+            level1_st.text = jsontmp.item[0].s_threshold
+            level1_vt.text = jsontmp.item[0].v_threshold
+
+            level2_v.text = jsontmp.item[1].volume
+            level2_st.text = jsontmp.item[1].s_threshold
+            level2_vt.text = jsontmp.item[1].v_threshold
+
+            level3_v.text = jsontmp.item[2].volume
+            level3_st.text = jsontmp.item[2].s_threshold
+            level3_vt.text = jsontmp.item[2].v_threshold
+
+        }else if(jsontmp.count === 4){
+            level1_v.text = jsontmp.item[0].volume
+            level1_st.text = jsontmp.item[0].s_threshold
+            level1_vt.text = jsontmp.item[0].v_threshold
+
+            level2_v.text = jsontmp.item[1].volume
+            level2_st.text = jsontmp.item[1].s_threshold
+            level2_vt.text = jsontmp.item[1].v_threshold
+
+            level3_v.text = jsontmp.item[2].volume
+            level3_st.text = jsontmp.item[2].s_threshold
+            level3_vt.text = jsontmp.item[2].v_threshold
+
+            level4_v.text = jsontmp.item[3].volume
+            level4_st.text = jsontmp.item[3].s_threshold
+            level4_vt.text = jsontmp.item[3].v_threshold
+
+            //console.log("the index = "+index+", tvolume[0] = "+ tvolume +", volume[0]"+ volume[0]);
+
+        }
+    }
+
+    DynamicGroupBox{
+        id:groupbox_all
+        anchors.centerIn: parent
+        anchors.fill: parent
+
+        title: title_str
+
+        Column {
+            id: column
+
+            //width: 600
+            //height:600
+
+            spacing: 40
+            anchors.centerIn: parent
+
+            Row {
+                id: row
+                //width: 600
+                //height: 500
+
+                 spacing: 30
+
+                 DynamicGroupBox{
+                     id:groupbox_list
+
+                     width: 150
+                     height: 400
+                     //anchors.centerIn: parent
+                     //anchors.fill: parent
+
+                     title: "标准列表"
+
+                     //Rectangle{
+                     //    id:rect_list
+                     //    width: 120
+                     //    height: 400
+                     //    anchors.margins: 10
+                     //    color: "white"
+                     //    radius: 6
+                     //    border.color: "black"
+
+                         ListView {
+                             //anchors.fill: parent
+                             anchors.centerIn: parent
+
+                             id: standard_listView
+                             width: 120
+                             height: 360
+
+                             model: ListModel{
+                                id: lmd
+                             }
+                             delegate: ItemDelegate {
+                                 text: modelData
+                                 font.bold: true
+                                 font.pixelSize: 24
+
+                                 highlighted: ListView.isCurrentItem
+
+                                 Binding {
+                                      target: background
+                                      property: "color"
+                                      //value: highlighted ? "#81A3CF" : "#B3B2B2"
+                                      value:highlighted ? "#C9DDF8" : "#B3B2B2"
+                                     }
+
+                                 //text: model.index + (highlighted ? " [highlighted]" : "")
+                                 //contentItem.color: "black"
+
+                                 Binding {
+                                      target: contentItem
+                                      property: "color"
+                                      value: "black"
+                                     }
+
+                                 onClicked:{
+
+                                     standard_listView.currentIndex = index
+                                     update_detail()
+                                 }
+                             }
+                         }
+
+                    // }
+
+                 }
+
+
+
+                Rectangle{
+                    id: rect_ops
+                    width: 180
+                    height: 400
+
+                    //anchors.margins: 10
+                    color: "transparent"
+                    //radius: 6
+                    //border.color: "black"
+
+                    Column{
+                        //anchors.fill: parent
+                        anchors.centerIn: parent
+                        spacing: 20
+
+                        UserButton {
+                            id: addButton
+                            text: "添加/修改"
+                            width: 180
+                            height: 60
+                            onClicked: {
+                                var standardJson={}
+                                var itemArrayJson=[]
+
+                                if(check_volume()){
+
+                                    standardJson.name = std_name.text
+                                    standardJson.ptv = std_PTV
+                                    standardJson.ntv = std_NTV
+                                    standardJson.count = 4
+                                    for(var i=0; i<4; i++){
+                                        var item={}
+                                        item.volume = volume[i]
+                                        item.s_threshold=s_threshold[i]
+                                        item.v_threshold=v_threshold[i]
+                                        itemArrayJson[i] = item
+                                    }
+                                    standardJson.item = itemArrayJson
+                                    StandardManager.add_standard(JSON.stringify(standardJson) );
+
+                                    update_listView()
+
+
+                                }else{
+                                    log.show("容积必须从大到小降序排列")
+                                }
+
+                            }
+                        }
+
+                        UserButton {
+                            id: removeButton
+                            text: "删除"
+                            width: 180
+                            height: 60
+                            onClicked: {
+                                var jsontmp = standard_listView.model.get(standard_listView.currentIndex)
+                                StandardManager.remove_standard(jsontmp.text);
+                                update_listView()
+
+                            }
+                        }
+
+                    }
+                }
+
+                DynamicGroupBox{
+                    id:groupbox_detail
+
+                    width: 640
+                    height: 400
+                    //anchors.centerIn: parent
+                    //anchors.fill: parent
+
+                    title: "标准详情"
+                    Column{
+                        spacing:10
+
+                        InputLine{
+                            id:std_name
+                            paraName: "标准名称:"
+                            paraLength: 160
+                            onTextChanged: {
+                                stdname_str=text
+                            }
+                        }
+
+                        Row{
+                            spacing:30
+
+                            InputLine{
+                                id:std_positive_target
+                                paraName: "正压目标值(Kpa):"
+                                paraLength: 60
+                                onTextChanged: {
+                                    std_PTV = Number(text)
+                                }
+                            }
+
+                            InputLine{
+                                id:std_negative_target
+                                paraName: "负压目标值(Kpa):"
+                                paraLength: 60
+                                onTextChanged: {
+                                    std_NTV = Number(text)
+                                }
+                            }
+                        }
+
+
+                    GridLayout {
+                        id: grid
+                        columns: 3
+                        columnSpacing: 30
+                        rows:5
+                        rowSpacing: 20
+
+
+
+                        Text { text: "单个油仓容积V(L)"; font.bold: true;  font.pointSize: 12; wrapMode: Text.WrapAnywhere; Layout.maximumWidth: 180}
+                        Text { text: "油气回收系统压力变动限值(Kpa)"; font.bold: true; font.pointSize: 12; wrapMode: Text.WrapAnywhere; Layout.maximumWidth: 180}
+                        Text { text: "油气回收阀压力变动限值(Kpa)"; font.bold: true; font.pointSize: 12; wrapMode: Text.WrapAnywhere; Layout.maximumWidth: 180}
+
+                        //level 1
+                        InputLine{
+                            id:level1_v
+                            paraName: " V≥ "
+                            paraLength: para_len
+                            validator:RegExpValidator {
+                                regExp: /[0-9]*/
+                            }
+                            onTextChanged: {
+                                volume[0] = Number(text)
+                                //console.log("level1 volume[0] == " + volume[0]);
+                            }
+                        }
+                        InputLine{
+                            id:level1_st
+                            paraName: " ≤ "
+                            paraLength: para_len
+                            onTextChanged: {
+                                s_threshold[0] = Number(text)
+                                //console.log("level1 s_threshold[0] == " + s_threshold[0]);
+                            }
+                        }
+
+                        InputLine{
+                            id:level1_vt
+                            paraName: " ≤ "
+                            paraLength: para_len
+                            onTextChanged: {
+                                v_threshold[0] = Number(text)
+                            }
+                        }
+
+                        //level 2
+                        InputLine{
+                            id:level2_v
+                            paraName: " V≥ "
+                            paraLength: para_len
+                            validator:RegExpValidator {
+                                regExp: /[0-9]*/
+                            }
+                            onTextChanged: {
+                                volume[1] = Number(text)
+                            }
+                        }
+                        InputLine{
+                            id:level2_st
+                            paraName: " ≤ "
+                            paraLength: para_len
+                            onTextChanged: {
+                                s_threshold[1] = Number(text)
+                            }
+                        }
+
+                        InputLine{
+                            id:level2_vt
+                            paraName: " ≤ "
+                            paraLength: para_len
+                            onTextChanged: {
+                                v_threshold[1] = Number(text)
+                            }
+                        }
+
+                        //level 3
+                        InputLine{
+                            id:level3_v
+                            paraName: " V≥ "
+                            paraLength: para_len
+                            validator:RegExpValidator {
+                                regExp: /[0-9]*/
+                            }
+                            onTextChanged: {
+                                volume[2] = Number(text)
+                            }
+                        }
+                        InputLine{
+                            id:level3_st
+                            paraName: " ≤ "
+                            paraLength: para_len
+                            onTextChanged: {
+                                s_threshold[2] = Number(text)
+                            }
+                        }
+
+                        InputLine{
+                            id:level3_vt
+                            paraName: " ≤ "
+                            paraLength: para_len
+                            onTextChanged: {
+                                v_threshold[2] = Number(text)
+                            }
+                        }
+
+                        //level 4
+                        InputLine{
+                            id:level4_v
+                            paraName: " V≥ "
+                            paraLength: para_len
+                            validator:RegExpValidator {
+                                regExp: /[0-9]*/
+                            }
+                            text:"0"
+                            onTextChanged: {
+                                volume[3] = Number(text)
+                            }
+                        }
+                        InputLine{
+                            id:level4_st
+                            paraName: " ≤ "
+                            paraLength: para_len
+                            onTextChanged: {
+                                s_threshold[3] = Number(text)
+                            }
+                        }
+
+                        InputLine{
+                            id:level4_vt
+                            paraName: " ≤ "
+                            paraLength: para_len
+                            onTextChanged: {
+                                v_threshold[3] = Number(text)
+                            }
+                        }
+
+
+
+                    }
+
+                    }
+
+                }
+
+
+            }
+
+            UserButton {
+                id: exitButton
+                text: "退出"
+                width: 120
+                height: 60
+                //anchors.horizontalCenter: parent
+                onClicked: {
+                    page_set.update_standard()
+                    standard_root.destroy()
+                }
+            }
+        }
+
+    }
+
+    Component.onCompleted: {
+        update_listView()
+        standard_listView.currentIndex = 0;
+        update_detail()
+
+    }
+}

+ 502 - 0
PageTest.qml

@@ -0,0 +1,502 @@
+import QtQuick 2.15
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+import QtQuick.Controls.Styles 1.2
+import TService 1.0
+
+Item{
+    id: root
+    //anchors.fill: parent
+    //width:1024
+    //height: 768
+    //anchors.centerIn: parent
+    property var pagetype:rootitem.Page_Type_Testing
+    property  string title_str:"手动测试"
+    property double pressvalue: 1.22
+    property bool bSelfTest_Started: false
+    property  string selfTest_State_str:""
+    property  string selfTest_Result_str:""
+
+
+    function show_pressure(pressure_str){
+        lcd_pressure.text = pressure_str;
+    }
+
+    function show_selftestState(str){
+        selfTest_State_str = str
+    }
+
+    function show_selftestResult(str){
+        selfTest_Result_str = str
+    }
+
+    function selftestStop(){
+        var ret1 = testService.tstop(0);
+        if(ret1){
+            bSelfTest_Started = false;
+            //selftest_result.text = ""
+            selftest_button.text = "开始"
+
+            readbutton.enabled = true;
+            adjustbutton.enabled = true;
+            //timer.stop()
+        }
+    }
+
+
+   // Component{
+    //    id:componet
+        DynamicGroupBox{
+            id:groupbox
+            //x:width
+            //x:0
+
+            anchors.centerIn: parent
+            anchors.fill: parent
+
+            title: title_str
+
+            Column{
+                spacing: 10
+                anchors.centerIn: parent
+
+            DynamicGroupBox{
+                id:relays_control
+                title: "继电器控制"
+
+                width: 800
+                height: 300
+
+                GridLayout{
+                    anchors.centerIn: parent
+                    columns: 4
+                    rows:3
+                    columnSpacing:  80
+                    rowSpacing: 30
+
+
+                    UserSwitch{
+                        id:switch1
+                        text: "粗调阀1关"
+                        onCheckedChanged: {
+                            //console.log("switch 1 onCheckedChanged")
+                            switch1.text = switch1.checked ? "粗调阀1开":"粗调阀1关"
+
+
+                        }
+                        onClicked: {
+                            //console.log("switch 1 clicked")
+
+                            if(switch1.checked){
+                                testService.valve_open(TestService.Valve_ID_ROUGH_0)
+                            }else{
+                                testService.valve_close(TestService.Valve_ID_ROUGH_0)
+                            }
+
+                        }
+                    }
+
+                    UserSwitch{
+                        id:switch2
+                        text: "粗调阀2关"
+                        onCheckedChanged: {
+                            switch2.text = switch2.checked ? "粗调阀2开":"粗调阀2关"
+
+                        }
+                        onClicked: {
+                            if(switch2.checked){
+                                testService.valve_open(TestService.Valve_ID_ROUGH_1)
+                            }else{
+                                testService.valve_close(TestService.Valve_ID_ROUGH_1)
+                            }
+                        }
+                    }
+                    UserSwitch{
+                        id:switch3
+                        text: "粗调阀3关"
+                        onCheckedChanged: {
+                            switch3.text = switch3.checked ? "粗调阀3开":"粗调阀3关"
+
+                        }
+
+                        onClicked: {
+                            if(switch3.checked){
+                                testService.valve_open(TestService.Valve_ID_ROUGH_2)
+                            }else{
+                                testService.valve_close(TestService.Valve_ID_ROUGH_2)
+                            }
+                        }
+                    }
+                    UserSwitch{
+                        id:switch4
+                        text: "校准阀 关"
+                        onCheckedChanged: {
+                            switch4.text = switch4.checked ? "校准阀 开":"校准阀 关"
+
+                        }
+
+                        onClicked: {
+                            if(switch4.checked){
+                                testService.valve_open(TestService.Valve_ID_CALIBRATION)
+                            }else{
+                                testService.valve_close(TestService.Valve_ID_CALIBRATION)
+                            }
+                        }
+                    }
+                    UserSwitch{
+                        id:switch5
+                        text: "传感阀 关"
+                        onCheckedChanged: {
+                            switch5.text = switch5.checked ? "传感阀 开":"传感阀 关"
+
+                        }
+
+                        onClicked: {
+                            if(switch5.checked){
+                                testService.valve_open(TestService.Valve_ID_PRESSURESENSOR)
+                            }else{
+                                testService.valve_close(TestService.Valve_ID_PRESSURESENSOR)
+                            }
+                        }
+                    }
+                    UserSwitch{
+                        id:switch6
+                        text: "真空阀 关"
+                        onCheckedChanged: {
+                            switch6.text = switch6.checked ? "真空阀 开":"真空阀 关"
+
+                        }
+
+                        onClicked: {
+                            if(switch6.checked){
+                                testService.valve_open(TestService.Valve_ID_VACUUM)
+                            }else{
+                                testService.valve_close(TestService.Valve_ID_VACUUM)
+                            }
+                        }
+                    }
+                    UserSwitch{
+                        id:switch7
+                        text: "泄气阀 关"
+                        onCheckedChanged: {
+                            switch7.text = switch7.checked ? "泄气阀 开":"泄气阀 关"
+
+                        }
+
+                        onClicked: {
+                            if(switch7.checked){
+                                testService.valve_open(TestService.Valve_ID_VENT)
+                            }else{
+                                testService.valve_close(TestService.Valve_ID_VENT)
+                            }
+                        }
+                    }
+                    UserSwitch{
+                        id:switch8
+                        text: "进气阀 关"
+                        onCheckedChanged: {
+                            switch8.text = switch8.checked ? "进气阀 开":"进气阀 关"
+
+                        }
+
+                        onClicked: {
+                            if(switch8.checked){
+                                testService.valve_open(TestService.Valve_ID_INTAKE)
+                            }else{
+                                testService.valve_close(TestService.Valve_ID_INTAKE)
+                            }
+                        }
+                    }
+
+                    UserSwitch{
+                        id:switchall
+                        text: "全关"
+                        onCheckedChanged: {
+                            switchall.text = switch8.checked ? "全关":"全开"
+                            if(switchall.checked){
+                                testService.valve_open(TestService.Valve_ID_All)
+                                switch1.checked=true
+                                switch2.checked=true
+                                switch3.checked=true
+                                switch4.checked=true
+                                switch5.checked=true
+                                switch6.checked=true
+                                switch7.checked=true
+                                switch8.checked=true
+                            }else{
+                                testService.valve_close(TestService.Valve_ID_All)
+                                switch1.checked=false
+                                switch2.checked=false
+                                switch3.checked=false
+                                switch4.checked=false
+                                switch5.checked=false
+                                switch6.checked=false
+                                switch7.checked=false
+                                switch8.checked=false
+                            }
+                        }
+                    }
+
+                }
+
+
+            }
+
+            DynamicGroupBox{
+                id:adjust_control
+                title: "调节阀控制"
+
+                width: 800
+                height: 100
+
+
+                Row{
+                        anchors.verticalCenter: parent.verticalCenter
+                        anchors.left: parent.left
+
+                        spacing: 20
+
+                        Text {
+                            id: text1
+                            //anchors.top: parent.top
+                            //anchors.bottom: parent.bottom
+                            //anchors.centerIn: parent
+                            anchors.verticalCenter: parent.verticalCenter
+                            text: qsTr("调压阀:")
+                            font.pixelSize: 20
+
+                        }
+
+                        UserButton {
+                            id: adjustbutton;
+                            text: "调压";
+                            font.pixelSize: 20
+
+                            anchors.verticalCenter: parent.verticalCenter
+
+                            implicitWidth: 100
+                            implicitHeight: 60
+
+                            onClicked: {
+                                //var str_number = voltage.text
+                                var num = Number(voltage.text)
+                                if((num>0) && (num<1000)){
+                                    testService.adjust_Pressure(voltage.text)
+                                }else{
+                                    console.log("input voltage invalid")
+                                    log.show("Voltage invalid, please retry")
+                                }
+
+                            }
+                        }
+
+
+                        InputLine{
+                            id:voltage
+                            paraName: "Voltage:"
+                            paraLength: 60
+
+                            anchors.verticalCenter: parent.verticalCenter
+
+                            validator:RegExpValidator {
+                                regExp: /[0-9]*/
+                            }
+                            onTextChanged: {
+                                //root.manufacture = text
+                            }
+                        }
+
+
+                    }
+
+            }
+
+            DynamicGroupBox{
+                id:pressure
+                title: "实时压力"
+
+                width: 800
+                height: 100
+
+
+                Row{
+                    anchors.verticalCenter: parent.verticalCenter
+                    anchors.left: parent.left
+
+                    spacing: 20
+
+                    Timer {
+                        id: timer;
+                        interval: 1000;//设置定时器定时时间为500ms,默认1000ms
+                        repeat: true //是否重复定时,默认为false
+                        running: false //是否开启定时,默认是false,当为true的时候,进入此界面就开始定时
+                        triggeredOnStart: false // 是否开启定时就触发onTriggered,一些特殊用户可以用来设置初始值。
+                        onTriggered: {
+                            lcd_pressure.text = testService.read_PressureValue();
+                        }
+                        //restart ,start,stop,定时器的调用方式,顾名思义
+
+                    }
+
+
+                    UserButton {
+                    id: readbutton;
+                    text: "开始";
+                    font.pixelSize: 20
+                    anchors.verticalCenter: parent.verticalCenter
+
+                    implicitWidth: 100
+                    implicitHeight: 60
+
+                    onEnabledChanged: {
+                        if(timer.running){
+                            timer.stop()
+                            text= "开始"
+                        }else{
+                            //timer.start()
+                            //text= "停止"
+                         }
+                    }
+
+                    onClicked: {
+
+                        if(timer.running){
+                            timer.stop()
+                            text= "开始"
+                        }else{
+                            timer.start()
+                            text= "停止"
+                         }
+
+                        //lcd_pressure.text = pressvalue.toFixed(3).toString()
+                    }
+                }
+
+                    Rectangle{
+                        id:pressureWindow
+                        //anchors.fill: parent
+                        anchors.verticalCenter: parent.verticalCenter
+                        width: 120
+                        height: 40
+                        //color: "white"
+                        radius: 4
+
+                        LCDNumber{
+                             id:lcd_pressure
+                             anchors.centerIn: parent
+                             //anchors.verticalCenter: parent.verticalCenter
+                             text: "5.00"
+                             fontsize: 40
+                        }
+
+
+
+                    }
+
+                    Text {
+                        id: kpa
+                        anchors.left: lcd_pressure.right
+                        anchors.verticalCenter: parent.verticalCenter
+                        text: qsTr("kPa")
+                        //font: 40
+                        font.bold: true
+                        font.pixelSize: 25
+                    }
+
+                }
+
+            }
+
+            DynamicGroupBox{
+                id:selftest
+                title: "系统自测"
+
+                width: 800
+                height: 100
+
+                Row{
+                    anchors.verticalCenter: parent.verticalCenter
+                    anchors.left: parent.left
+
+                    spacing: 30
+
+                    UserButton {
+                        id: selftest_button;
+                        text: "开始";
+                        font.pixelSize: 20
+
+                        //height: 40
+                        //width: 160
+                        implicitWidth: 100
+                        implicitHeight: 60
+                        onClicked: {
+                            //var str_number = voltage.text
+                            if(false == bSelfTest_Started){
+                                //bSelfTest_Started = true;
+                                //selftest_result.text= "测试通过"
+                                if(timer.running){
+                                    timer.stop()
+                                }
+
+                                var ret = testService.tselfstart(0, 0)
+                                if(ret){
+                                    bSelfTest_Started = true;
+                                    readbutton.enabled = false;
+                                    adjustbutton.enabled = false;
+                                    text = "停止"
+                                    selfTest_State_str=""
+                                    selfTest_Result_str=""
+                                    //timer.start()
+                                }else{
+
+                                }
+
+                            }else{
+                                var ret1 = testService.tstop(0);
+                                if(ret1){
+                                    bSelfTest_Started = false;
+                                    //selftest_result.text = ""
+                                    text = "开始"
+
+                                    readbutton.enabled = true;
+                                    adjustbutton.enabled = true;
+                                    //timer.stop()
+                                }
+
+
+                            }
+
+                        }
+                    }
+
+
+
+                    Text {
+                        id: selftest_state
+                        anchors.verticalCenter: parent.verticalCenter
+                        text: qsTr("自测状态:")+selfTest_State_str
+                        font.pixelSize: 20
+
+                    }
+
+                    Text {
+                        id: selftest_result
+                        anchors.verticalCenter: parent.verticalCenter
+                        text: qsTr("自测结果:")+selfTest_Result_str
+                        font.pixelSize: 20
+
+                    }
+
+
+
+                }
+
+            }
+
+            }
+
+
+
+            }
+      //  }
+    }

+ 47 - 0
RecordTable.qml

@@ -0,0 +1,47 @@
+import QtQuick 2.11
+
+Rectangle {
+    id:root
+    anchors.fill: parent
+    property alias modelData: listModel
+
+    GridView{
+        id:gridview
+
+        anchors.fill: parent
+        anchors.margins: 5
+        cellWidth:width/20
+        cellHeight: height/10
+        clip: true
+        delegate: componet
+        model: listModel
+
+
+
+        Component {
+            id:componet
+
+            Rectangle{
+                width:gridview.cellWidth-2
+                height: gridview.cellHeight-2
+                color: "#DFE2E6"
+                radius: 3
+                Text {
+                    id: name
+                    text: pressure
+                    anchors.centerIn: parent
+                }
+            }
+
+        }
+
+        ListModel{
+            id:listModel
+        }
+
+
+
+    }
+}
+
+

+ 604 - 0
RecoveryValve.qml

@@ -0,0 +1,604 @@
+import QtQuick 2.11
+//import QtQuick.VirtualKeyboard 2.14
+//import QtQuick.VirtualKeyboard.Settings 2.14
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+
+import QtQuick.Layouts 1.3
+import QtTest 1.14
+//import "modbus.js" as ModbusJs
+//import "breatheTest.js" as BreatheTestJs
+import Qt.labs.platform 1.1
+
+
+Item{
+    id:root
+
+    property var pagetype:rootitem.Page_Type_ValveTest
+    //车辆单位
+    property  string organize
+    //车牌号
+    property  string carplate
+    //总容积
+    property  string total_volume
+    //油仓数量
+    property  string compartment_num
+    //当前油仓ID
+    property  int compartment_id
+    //当前油仓体积
+    property  int volume
+    property  int test_direction:0
+    //
+    property  string state
+    property  string pressure:"0.00"
+
+    property int  pressureCnt:0
+    property  var  syskpArray: []
+    property  var  valvekpArray: []
+    property  var  allArray: []
+    property  real m_maxY: 0.0
+    property  real m_minY: 0.0
+    property  bool bStart: false;
+
+
+
+/*
+    Loader{
+        id:loader
+        anchors.fill: parent
+        //anchors.margins: 5
+        sourceComponent: componet
+    }
+
+    */
+/*
+    function show(){
+        if(loader.sourceComponent  === null){
+            loader.sourceComponent  = componet
+            console.debug("avans 1111")
+        }
+        loader.item.show()
+    }
+
+    function exit(){
+        if(loader.sourceComponent  !== null){
+            loader.item.exit()
+        }
+    }
+*/
+
+    function update_pressure(pressure_map){
+        //textstring += pressure_map.pressure+":"
+        //textstring += pressure_map.direction.toString()+":"
+        //textstring += pressure_map.stage.toString()+":"
+        //textstring += pressure_map.step.toString()+":"
+        console.debug("avans 1111 update_pressure: ", pressure_map.pressure)
+
+        pressure = pressure_map.pressure
+        add_record(pressure_map.pressure)
+        pressureDisplayInput(Number(pressure_map.pressure))
+
+        if(pressure_map.step === 3){  // keep pressure
+            if(pressure_map.stage === 0){  //sys test
+                syskpArray.push(Number(pressure_map.pressure))
+                //console.debug("avans 1111 sys keep pressure: ", pressure_map.pressure)
+
+            }else if(pressure_map.stage === 1){  //valve test
+                valvekpArray.push(Number(pressure_map.pressure))
+            }
+        }
+
+        allArray.push(Number(pressure_map.pressure))
+    }
+
+    function add_record(str){
+        var obj={}
+        obj.pressure = str
+        recordtable.modelData.append(obj)
+    }
+
+    function cleardata(){
+        recordtable.modelData.clear()
+        allArray = []
+        syskpArray = []
+        valvekpArray = []
+
+        curveDisplay.spline.clear()
+        pressureCnt =0
+
+
+        resulttable.systemPressure_delta = "  ";
+        resulttable.systemPressure_fontcolor="black"
+        resulttable.systemPressure_pass = "未知";
+
+        resulttable.valvePressure_delta = "  ";
+        resulttable.valvePressure_fontcolor ="black"
+        resulttable.valvePressure_pass = "未知";
+
+        statetable.state_str1 = "  ";
+        statetable.state_str2 = "  ";
+    }
+
+    function pressureDisplayInput(number){
+        pressureCnt++
+
+        m_maxY = (m_maxY < number)? number:m_maxY
+        m_minY = (m_minY > number)? number:m_minY
+
+        curveDisplay.setRange_Y(m_minY-2.0, m_maxY+2.0)
+
+        if(pressureCnt <= 180){
+            //dataArray.push(number)
+            curveDisplay.spline.append(pressureCnt-1,number)
+        }
+        else{
+
+            curveDisplay.setRange_X(0, pressureCnt-1)
+            curveDisplay.spline.append(pressureCnt-1,number)
+
+            /*
+            dataArray.push(number)
+            dataArray.shift()
+            curveDisplay.spline.clear()
+            for(var i=0; i<61; i++){
+                curveDisplay.spline.append(i,dataArray[i])
+            }
+            */
+        }
+        //gauge.value = number
+    }
+
+
+    function show_systemresult(delta, bPassed)
+    {
+        if(bPassed){
+            resulttable.systemPressure_delta = delta;
+            resulttable.systemPressure_fontcolor="green"
+            resulttable.systemPressure_pass = "合格";
+        }else{
+            resulttable.systemPressure_delta = delta;
+            resulttable.systemPressure_fontcolor="red"
+            resulttable.systemPressure_pass = "超标";
+        }
+    }
+
+    function show_valveresult(delta, bPassed)
+    {
+        if(bPassed){
+            resulttable.valvePressure_delta = delta;
+            resulttable.valvePressure_fontcolor ="green"
+            resulttable.valvePressure_pass = "合格";
+        }else{
+            resulttable.valvePressure_delta = delta;
+            resulttable.valvePressure_fontcolor="red"
+            resulttable.valvePressure_pass = "超标";
+        }
+    }
+
+    function update_runstate(str1, str2)
+    {
+        statetable.state_str1 = str1;
+        statetable.state_str2 = str2;
+    }
+
+    function test_stoped(){
+        startStopButton.running = false;
+    }
+
+
+   // Component{
+   //     id:componet
+        DynamicGroupBox{
+            id:groupbox
+            //x:width
+            //x:0
+            title: "油气回收系统密封检测  第"+compartment_id+"仓: 容积"+volume+"(L)"
+            //width: 1024
+            //height: 768
+            anchors.centerIn: parent
+            anchors.fill: parent
+
+            function show(){
+                animationShow.running = true
+            }
+
+            function exit(){
+                //BreatheTestJs.exit = true
+                animationExit.running = true
+                //startStopButton.running = false
+                //stopTimer.start()
+            }
+
+            function allTestGeneratePicture(){
+                var filename = root.carplate+"_"+root.compartment_id+"_all"
+                reportPicture_all.delayms = 300
+                reportPicture_all.generatePicture(filename, allArray)
+            }
+            function sysTestGeneratePicture(){
+                var filename = root.carplate+"_"+root.compartment_id+"_sys"
+                reportPicture_sys.delayms = 500
+                reportPicture_sys.generatePicture(filename, syskpArray)
+            }
+
+            function valveTestGeneratePicture(){
+                var filename = root.carplate+"_"+root.compartment_id+"_valve"
+                reportPicture_valve.delayms = 800
+                reportPicture_valve.generatePicture(filename, valvekpArray)
+            }
+
+
+/*
+            //加载任务动画效果
+            NumberAnimation {
+                id: animationShow
+                target: groupbox
+                property: "x"
+                from: groupbox.x
+                to: 0
+                duration: 500
+            }
+            NumberAnimation {
+                id: animationExit
+                target: groupbox
+                property: "x"
+                from: groupbox.x
+                to: 1024
+                duration: 500
+            }
+
+*/
+
+            //报告
+            Connections{
+                target: reportButton
+                onUserClicked:{
+
+                    //if(allArray.length > 0){
+                        console.log("allTestGeneratePicture")
+                        groupbox.allTestGeneratePicture()
+                   // }
+
+                    //if(syskpArray.length > 0){
+                        console.log("sysTestGeneratePicture")
+                        groupbox.sysTestGeneratePicture()
+                   // }
+
+                   // if(valvekpArray.length > 0){
+                        console.log("valveTestGeneratePicture")
+                        groupbox.valveTestGeneratePicture()
+                   // }
+
+
+                    testService.reportpic_Ready(compartment_id);
+
+                    if(testService.check_alltest_ok()){
+                        var fileName = root.carplate
+                        var text = getWordSaveFileName(fileName)
+                        console.log(text)
+
+                        saveWordDialog.currentFile = getWordSaveFileName(fileName)
+                        saveWordDialog.open()
+                    }
+
+                }
+            }
+
+            FileDialog {
+                id: saveWordDialog
+                title: "保存为"
+                //nameFilters: [ "Word files (*.doc)"]
+                nameFilters: [ "Word files (*.doc)", "Text files (*.pdf)"]
+                fileMode: FileDialog.SaveFile
+                onAccepted: {
+                    var savePath = file.toString().substring(8)
+
+                    console.log("saveWordDialog savePath:")
+                    console.log(savePath)
+
+                    //reportWord.generateBreatheValveWord(savePath,para,obj1,obj2,obj3)
+                    testService.genReport(savePath, "D:/tmp/")
+                }
+            }
+
+
+            Column{
+                anchors.left: parent.left
+                anchors.leftMargin: 3
+                anchors.top: parent.top
+                anchors.topMargin: 10
+                spacing: 0
+
+
+                Row{
+                   x:-10
+
+                   CurveDisplay{
+                       id:curveDisplay
+                       anchors.verticalCenter: parent.verticalCenter
+
+                       width: 900
+                       height: 460
+                       axisxMax:180
+                       axisxMin:0
+                       axisyMax:14
+                       axisyMin:0
+                       name:"横轴时间(秒) 纵轴压力(kPa)"
+                   }
+
+
+
+                   Item {
+                       id:button_root
+                       width: 360
+                       height: 460
+
+                       Column{
+                           id:button_column
+                           spacing: 10
+
+                           Rectangle{
+                               id:buttonWindow
+                               //anchors.fill: parent
+                               width: 350
+                               height: 70
+
+                               color: "white"
+                               radius: 6
+                                border.color: "black"
+
+                               Row{
+                                   anchors.verticalCenter: parent.verticalCenter
+                                   anchors.horizontalCenter: parent.horizontalCenter
+                                   spacing: 50
+
+                                   StartStopButton{
+                                       id:startStopButton
+                                       width: 50
+                                       height: 50
+                                       anchors.verticalCenter: parent.verticalCenter
+                                       onRunningChanged: {
+                                           if(running){
+                                               //clearCurveDisplay()
+                                               cleardata()
+                                              bStart = testService.tstart(compartment_id, test_direction)
+                                              if(!bStart){
+                                                  running=false;
+                                              }
+                                           }else{
+                                               if(bStart){
+                                                    testService.tstop(compartment_id)
+                                                   bStart=false
+                                               }
+                                           }
+                                      }
+                                   }
+
+                                   ReportButton{
+                                       id:reportButton
+                                       width: 50
+                                       height: 50
+                                       anchors.verticalCenter: parent.verticalCenter
+                                   }
+
+                                }
+
+                            }
+
+                           Rectangle{
+                               id:test_selrect
+                               //anchors.fill: parent
+                               anchors.margins: 10
+                               width: 350
+                               height: 50
+                               color: "white"
+                               radius: 6
+                               border.color: "black"
+                               UserComboBox{
+                                  id:test_comboBox
+                                  //anchors.fill:parent
+                                  implicitWidth:350
+                                  implicitHeight:50
+                                  bgColor:"#D2D5D9"
+                                  model: ["正压密闭性检测","负压密闭性检测"]
+                                  onCurrentTextChanged: {
+                                      //root.standard_name = currentText
+                                      test_direction = currentIndex
+                                      console.log("choose test direction : "+test_direction)
+                                      if(0 == currentIndex){
+                                          resulttable.titlestr = currentText
+
+                                      }else{
+                                          resulttable.titlestr = currentText
+
+                                      }
+                                  }
+
+                               }
+
+                           }
+
+                           Rectangle{
+                               id:pressureWindow
+                               //anchors.fill: parent
+                               anchors.margins: 10
+                               width: 350
+                               height: 100
+                               color: "white"
+                               radius: 6
+                               border.color: "black"
+
+
+                               Text {
+                                   id: pressurekpa
+                                   anchors.right: pressureWindow.right
+                                   anchors.verticalCenter: parent.verticalCenter
+                                   text: qsTr("kPa ")
+                                   //font: 40
+                                   font.bold: true
+                                   font.pixelSize: 35
+
+                               }
+
+                               Rectangle{
+                                   id:pressure_rect
+
+                                   anchors.verticalCenter: parent.verticalCenter
+                                   anchors.right: pressurekpa.left;
+
+                                   width: 250
+                                   height: 80
+                                   LCDNumber{
+                                        id:lcd_pressure
+                                        anchors.centerIn: parent
+                                        text: root.pressure
+                                   }
+                               }
+
+
+                           }
+
+                           Rectangle{
+                               id:resultWindow
+                               //anchors.fill: parent
+                               anchors.margins: 5
+                               width: 350
+                               height: 100
+                               color: "white"
+                               radius: 6
+                               border.color: "black"
+
+                               ResultTable{
+                                id:resulttable
+                                anchors.fill: parent
+                               }
+
+                             }
+
+                           Rectangle{
+                               id:stateWindow
+                               //anchors.fill: parent
+                               anchors.margins: 5
+                               width: 350
+                               height: 100
+                               color: "white"
+                               radius: 6
+                               border.color: "black"
+
+                               StateTable{
+                                id:statetable
+                                anchors.fill: parent
+                               }
+
+                             }
+                       }
+
+                   }
+
+                }
+
+                Row{
+                    id: records
+                    spacing: 10
+
+                    function dataRandomSet(modelData,max){
+                        for(var i=0;i<max; i++){
+                            //var number= Math.round(Math.random()*10)
+                            var number= Math.random()*10
+                            //number *= 10
+
+                            var obj={}
+                            obj.pressure= 0 - number.toFixed(3)
+                            modelData.append(obj)
+                        }
+                    }
+
+                    Rectangle{
+                        width: 1250
+                        height: 240
+                        color: "white"
+                        radius: 6
+
+                        GroupBox{
+                            id:groupboxrecord
+                             //x:width
+                            //x:0
+                            title: "历史数据"
+                            anchors.fill: parent
+                            anchors.margins: 0
+
+                            RecordTable{
+                                id:recordtable
+                                Component.onCompleted: {
+                                    //records.dataRandomSet(modelData,500)
+                                }
+                            }
+
+                        }
+                    }
+
+                }
+
+
+            }
+
+        }
+
+   // }
+
+
+        ReportPicture{
+            id:reportPicture_sys
+        }
+
+        ReportPicture{
+            id:reportPicture_valve
+        }
+
+        ReportPicture{
+            id:reportPicture_all
+        }
+
+
+        function pad_with_zeroes(number, length) {
+            var my_string = '' + number;
+            while (my_string.length < length) {
+                my_string = '0' + my_string;
+            }
+            return my_string;
+        }
+
+        function getWordSaveFileName( para){
+            var date = new Date;
+            var year = date.getFullYear()
+            var month = pad_with_zeroes(date.getMonth()+1,2)
+            var day = pad_with_zeroes(date.getDate(),2)
+            var hour = pad_with_zeroes(date.getHours(),2)
+            var minute = pad_with_zeroes(date.getMinutes(),2)
+            var second = pad_with_zeroes(date.getSeconds(),2)
+
+            var time = year+month+day+hour+minute+second
+            return "file:///"+time+"_"+para
+        }
+
+
+        Timer {
+            id: timer;
+            interval: 300;//设置定时器定时时间为500ms,默认1000ms
+            repeat: true //是否重复定时,默认为false
+            running: false //是否开启定时,默认是false,当为true的时候,进入此界面就开始定时
+            triggeredOnStart: false // 是否开启定时就触发onTriggered,一些特殊用户可以用来设置初始值。
+            onTriggered: {
+                //qreal y = 12/2 + (12/2.0)*sin(pressureCnt)
+                pressureDisplayInput(12/2 + (12/2.0)*Math.sin(Math.PI*pressureCnt/60))
+            }
+            //restart ,start,stop,定时器的调用方式,顾名思义
+
+        }
+
+        Component.onCompleted: {
+            //timer.start()
+
+        }
+
+}
+

+ 22 - 0
ReportButton.qml

@@ -0,0 +1,22 @@
+import QtQuick 2.11
+
+Item {
+    signal userClicked
+    Image {
+        id:image
+        anchors.fill: parent
+        source: "qrc:/img/reports-icon.png"
+        MouseArea{
+            anchors.fill: parent
+            onPressed: {
+                image.opacity = 0.5
+            }
+            onReleased: {
+                image.opacity = 1.0
+            }
+            onClicked: {
+                userClicked()
+            }
+        }
+    }
+}

+ 71 - 0
ReportPicture.qml

@@ -0,0 +1,71 @@
+import QtQuick 2.11
+
+Rectangle {
+    id:root
+    z:-1
+
+    width:900
+    height:460
+
+    color: "white"
+    visible: false
+    property string fileName
+    property int  delayms:300
+
+    property  real m_maxY: 0.0
+    property  real m_minY: 0.0
+
+   // property var pointList:[]
+
+
+    function generatePicture(filename, dataArray){
+
+        for(var i=0; i<dataArray.length;i++){
+            m_maxY = (m_maxY < dataArray[i])? dataArray[i]:m_maxY
+            m_minY = (m_minY > dataArray[i])? dataArray[i]:m_minY
+            //console.log("dataArray  ",i,dataArray[i])
+        }
+
+        curveDisplay_pic.spline.clear()
+
+        m_minY = (m_minY-2) < 0?  0:(m_minY-2)
+        m_maxY = m_maxY+2
+
+        curveDisplay_pic.setRange_Y(m_minY, m_maxY)
+        curveDisplay_pic.setRange_X(0, dataArray.length-1)
+
+        for(var j=0; j<dataArray.length; j++){
+            //curveDisplay.charView.series(j).replace(j,dataArray[j])
+            curveDisplay_pic.spline.append(j,dataArray[j])
+        }
+
+        //dataSource.update(curveDisplay.charView.series(0),root.pointList)
+
+        root.fileName = "D:/tmp/"+filename +".jpg"
+        timer.start()
+    }
+
+
+    Timer{
+        id:timer
+        repeat: false
+        interval: delayms
+        onTriggered: {
+            root.grabToImage(function(result) {
+                result.saveToFile(root.fileName);
+            });
+        }
+    }
+
+
+    CurveDisplay{
+        id:curveDisplay_pic
+        anchors.fill: parent
+        name: "横轴时间(秒) 纵轴压力(kPa)"
+    }
+
+
+
+
+
+}

+ 40 - 0
ResultDisplayText.qml

@@ -0,0 +1,40 @@
+import QtQuick 2.0
+
+Rectangle{
+
+    property string     paraName:""
+    property string     paraName_fontColor:"#272727"
+    property string     paraResult:""
+    property string     paraResult_fontColor:"#272727"
+    property string     paraUnit:""
+    property string     paraUnit_fontColor:"#272727"
+    Row{
+        anchors.verticalCenter: parent.verticalCenter
+        spacing: 10
+        Text {
+            color:paraName_fontColor
+            font.bold: true
+            font.pixelSize: 20
+            text: paraName
+        }
+
+        Text {
+            color:paraResult_fontColor
+            font.bold: true
+            font.pixelSize: 20
+            text: paraResult
+        }
+
+    }
+    Text {
+        anchors.verticalCenter: parent.verticalCenter
+        anchors.right: parent.right
+        anchors.rightMargin: 5
+        color:paraUnit_fontColor
+        font.bold: true
+        font.pixelSize: 20
+        text: paraUnit
+    }
+}
+
+

+ 115 - 0
ResultTable.qml

@@ -0,0 +1,115 @@
+import QtQuick 2.11
+
+Item {
+    id:root
+    anchors.fill: parent
+    anchors.margins: 10
+    property int resultHeight: 25
+
+    property string  titlestr
+
+    property string  systemPressure_delta
+    property string  systemPressure_fontcolor:"#272727"
+    property string  systemPressure_pass:"未知"
+
+    property string  valvePressure_delta
+    property string  valvePressure_fontcolor:"#272727"
+    property string  valvePressure_pass:"未知"
+
+    Column{
+        anchors.centerIn: parent
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "white"
+            paraName: titlestr+"结果:"
+            paraResult:""
+            paraUnit:""
+        }
+
+        Row{
+
+            ResultDisplayText{
+                width: root.width*3/4
+                height: root.resultHeight
+                color: "#D2D5D9"
+                paraName: "系统密闭性:"
+                paraResult:systemPressure_delta
+                paraResult_fontColor: systemPressure_fontcolor
+                paraUnit:"kPa"
+            }
+
+            ResultDisplayText{
+                width: root.width/4
+                height: root.resultHeight
+                color: "#D2D5D9"
+                paraName: "  "
+                paraResult:systemPressure_pass
+                paraResult_fontColor: systemPressure_fontcolor
+                paraUnit:""
+            }
+        }
+
+        Row{
+
+            ResultDisplayText{
+                width: root.width*3/4
+                height: root.resultHeight
+                color: "#DFE2E6"
+                paraName: "阀门密闭性:"
+                paraResult:valvePressure_delta
+                paraResult_fontColor:valvePressure_fontcolor
+                paraUnit:"kPa"
+            }
+
+            ResultDisplayText{
+                width: root.width/4
+                height: root.resultHeight
+                color: "#DFE2E6"
+                paraName: "  "
+                paraResult:valvePressure_pass
+                paraResult_fontColor:valvePressure_fontcolor
+                paraUnit:""
+            }
+        }
+
+ /*
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "white"
+            paraName: ""
+            paraResult:""
+            paraUnit:""
+        }
+
+
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "white"
+            paraName: "负压测试"
+            paraResult:""
+            paraUnit:""
+        }
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "#DFE2E6"
+            paraName: "系统密封性:"
+            paraResult:negativeSysPressure
+            paraUnit:"kPa"
+        }
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "#D2D5D9"
+            paraName: "阀门密封性:"
+            paraResult:negativeValvePressure
+            paraUnit:"kPa"
+        }
+*/
+
+    }
+
+}

+ 416 - 0
Standard.cpp

@@ -0,0 +1,416 @@
+#include "Standard.h"
+#include <QDebug>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QByteArray>
+#include <QFile>
+
+//#define JSON_FILE_NAME "standards"
+//#define JSON_FILE_TAG "STANDARDS_JLWL"
+
+#define JSON_FILE_VERSION "V1.0"
+
+static StandardManager* _standardmanager = nullptr;
+
+StandardManager::StandardManager(QObject* parent)
+    :QObject(parent)
+{
+
+}
+
+StandardManager::~StandardManager(){
+
+}
+
+StandardManager* StandardManager::instance(){
+    if(nullptr == _standardmanager){
+        _standardmanager = new StandardManager();
+    }
+
+    return _standardmanager;
+}
+
+void StandardManager::add_GB()
+{
+    Standard std;
+    std.standard_name = "国标";
+    std.positive_target = 4.5;
+    std.negative_target = -1.5;
+
+    std.item_count = 4;
+    std.item[0].oilcompartment_volume = 9500;
+    std.item[0].system_threshold = 0.25;
+    std.item[0].valve_threshold = 1.30;
+
+    std.item[1].oilcompartment_volume = 5500;
+    std.item[1].system_threshold = 0.38;
+    std.item[1].valve_threshold = 1.30;
+
+    std.item[2].oilcompartment_volume = 3800;
+    std.item[2].system_threshold = 0.50;
+    std.item[2].valve_threshold = 1.30;
+
+    std.item[3].oilcompartment_volume = 0;
+    std.item[3].system_threshold = 0.65;
+    std.item[3].valve_threshold = 1.30;
+
+    m_standard.push_back(std);
+}
+
+void StandardManager::load_standards()
+{
+    QFile file("./standards.json");
+    if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){
+        //QJsonObject jsonObject;
+        //jsonObject["name"] =""
+        qDebug() << "load_standards file open failed ";
+        return ;
+    }
+
+    QTextStream jsonstream(&file);
+
+    jsonstream.setCodec("UTF-8");
+
+    //jsonstream.readAll();
+    qDebug() << "load_standards enter";
+
+    QString jsonString = jsonstream.readAll();
+    file.close();
+
+
+    QJsonParseError json_error;
+    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8(), &json_error);
+    if(json_error.error == QJsonParseError::NoError){
+        QJsonObject rootObj = jsonDoc.object();
+        QJsonArray  jsonArray;
+        QString str;
+
+        qDebug() << "load_standards enter 22222222";
+
+        if(rootObj.contains("version") && rootObj.value("version").isString()){
+            str = rootObj.value("version").toString();
+            //qDebug() <<  str ;
+            if(str != JSON_FILE_VERSION){
+                qDebug() <<  str << " not equal:" << JSON_FILE_VERSION;
+               return;
+            }
+        }
+
+        if(rootObj.contains("standards") && rootObj.value("standards").isArray()){
+            jsonArray = rootObj.value("standards").toArray();
+            for(int i=0; i < jsonArray.size(); i++){
+
+                Standard std;
+                std.item_count = 0;
+                QJsonObject childObj = jsonArray[i].toObject();
+                if(childObj.contains("name") && childObj.value("name").isString()){
+                    std.standard_name = childObj.value("name").toString();
+                }
+
+                if(childObj.contains("pt_v") && childObj.value("pt_v").isDouble()){
+                    std.positive_target = childObj.value("pt_v").toDouble();
+                }
+
+
+                if(childObj.contains("nt_v") && childObj.value("nt_v").isDouble()){
+                    std.negative_target = childObj.value("nt_v").toDouble();
+                }
+
+                if(childObj.contains("items") && childObj.value("items").isArray()){
+                    QJsonArray  jsonArray_i;
+                    jsonArray_i = childObj.value("items").toArray();
+                    std.item_count = jsonArray_i.size();
+
+                    if(std.item_count > 4){
+                       std.item_count = 4;
+                    }
+
+                    qDebug() << "item_count:" << std.item_count;
+
+                    for(int j =0 ; j<std.item_count; j++){
+                        QJsonObject itemObj = jsonArray_i[j].toObject();
+
+                        if(itemObj.contains("volume") && itemObj.value("volume").isDouble()){
+                            std.item[j].oilcompartment_volume = itemObj.value("volume").toInt();
+                        }
+
+                        if(itemObj.contains("s_threshold") && itemObj.value("s_threshold").isDouble()){
+                            std.item[j].system_threshold = itemObj.value("s_threshold").toDouble();
+                        }
+
+                        if(itemObj.contains("v_threshold") && itemObj.value("v_threshold").isDouble()){
+                            std.item[j].valve_threshold = itemObj.value("v_threshold").toDouble();
+                        }
+
+                    }
+                }
+
+                if(true != std.standard_name.isEmpty() && std.item_count > 0){
+                    m_standard.push_back(std);
+                     qDebug() << " m_standard.push_back(std)" ;
+                }
+            }
+        }
+
+
+    }else{
+        qDebug() << "json_error.error occurred";
+    }
+
+}
+
+void StandardManager::save_standards()
+{
+    QJsonArray stdArray;
+    //QJsonArray itemArray;
+    QJsonObject rootObj;
+
+    rootObj.insert("version", JSON_FILE_VERSION);
+
+    for(int i=0; i < static_cast<int>(m_standard.size()); i++){
+
+        QJsonObject stdObj;
+        QJsonArray itemArray;
+
+        stdObj.insert("name", m_standard[i].standard_name);
+
+        stdObj.insert("pt_v", m_standard[i].positive_target);
+        stdObj.insert("nt_v", m_standard[i].negative_target);
+
+       for(int j=0; j < m_standard[i].item_count; j++){
+           QJsonObject itemObj;
+           itemObj.insert("volume", m_standard[i].item[j].oilcompartment_volume);
+           itemObj.insert("s_threshold", m_standard[i].item[j].system_threshold);
+           itemObj.insert("v_threshold", m_standard[i].item[j].valve_threshold);
+
+           itemArray.append(itemObj);
+       }
+
+       stdObj.insert("items", itemArray);
+       stdArray.append(stdObj);
+    }
+
+    rootObj.insert("standards", stdArray);
+
+    QJsonDocument jsonDoc;
+    jsonDoc.setObject(rootObj);
+
+    QByteArray byteArray = jsonDoc.toJson(QJsonDocument::Indented);
+    QFile file("./standards.json");
+    if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
+    {
+        qDebug() << QString("fail to open the file: %1, %2, %3").arg(__FILE__).arg(__LINE__).arg(__FUNCTION__);
+        return;
+    }
+    QTextStream out(&file);
+    out.setCodec("UTF-8");
+    out << byteArray;
+    file.close();
+
+    qDebug() << QString("save standards ok : %1, %2, %3").arg(__FILE__).arg(__LINE__).arg(__FUNCTION__);
+
+}
+
+void StandardManager::init()
+{
+    qDebug()<< QString("init enter : %1, %2, %3").arg(__FILE__).arg(__LINE__).arg(__FUNCTION__);
+    load_standards();
+
+    //check GB
+    QString gb_name = "国标";
+    bool gb_inside = false;
+
+    for(int i=0; i < static_cast<int>(m_standard.size()); i++){
+       if(gb_name == m_standard[i].standard_name){
+           gb_inside =  true;
+       }
+    }
+
+    if(false == gb_inside){
+        add_GB();
+    }
+}
+
+
+QJsonObject StandardManager::get_names()
+{
+    QJsonObject jsonObj;
+    QJsonArray nameArray;
+
+    //int num = static_cast<int>m_standard.size();
+
+    jsonObj.insert("num", static_cast<int>(m_standard.size()));
+
+    for(int i=0; i < static_cast<int>(m_standard.size()); i++){
+        nameArray.append(m_standard[i].standard_name);
+    }
+
+    jsonObj.insert("names", nameArray);
+
+    return jsonObj;
+}
+
+QJsonObject StandardManager::get_standard(const QString name)
+{
+    QJsonObject stdObj;
+
+    for(int i=0; i < static_cast<int>(m_standard.size()); i++){
+        if(name == m_standard[i].standard_name){
+
+            stdObj.insert("name", m_standard[i].standard_name);
+            stdObj.insert("ptv", m_standard[i].positive_target);
+            stdObj.insert("ntv", m_standard[i].negative_target);
+
+            stdObj.insert("count", m_standard[i].item_count);
+            QJsonArray itemArray;
+
+            for(int j=0; j < m_standard[i].item_count; j++){
+                QJsonObject itemObj;
+                itemObj.insert("volume", m_standard[i].item[j].oilcompartment_volume);
+                itemObj.insert("s_threshold", m_standard[i].item[j].system_threshold);
+                itemObj.insert("v_threshold", m_standard[i].item[j].valve_threshold);
+
+                itemArray.append(itemObj);
+            }
+
+            stdObj.insert("item", itemArray);
+            break;
+        }
+    }
+
+
+    return stdObj;
+
+}
+
+void StandardManager::remove_standard(const QString name)
+{
+    bool bExist = false;
+    for(int i=0; i < static_cast<int>(m_standard.size()); i++){
+        if(name == m_standard[i].standard_name){
+            bExist = true;
+            m_standard.erase(m_standard.begin()+i);
+            break;
+        }
+    }
+
+    if(true == bExist){
+        save_standards();
+    }
+
+}
+
+bool StandardManager::add_standard(const QString& jsonStr )
+{
+    bool bExist = false;
+    Standard std;
+
+    qDebug() << jsonStr;
+
+    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8());
+    QJsonObject jsonObj = jsonDoc.object();
+
+    std.item_count = 0;
+    //QJsonObject childObj = jsonArray[i].toObject();
+
+    if(jsonObj.contains("name") && jsonObj.value("name").isString()){
+        std.standard_name = jsonObj.value("name").toString();
+    }else{
+        qDebug() << "add_standard no name";
+        return false;
+    }
+
+    if(jsonObj.contains("ptv") && jsonObj.value("ptv").isDouble()){
+        std.positive_target = jsonObj.value("ptv").toDouble();
+    }else{
+        qDebug() << "add_standard no ptv";
+        return false;
+    }
+
+    if(jsonObj.contains("ntv") && jsonObj.value("ntv").isDouble()){
+        std.negative_target = jsonObj.value("ntv").toDouble();
+    }else{
+        qDebug() << "add_standard no ntv";
+        return false;
+    }
+
+    if(jsonObj.contains("count") && jsonObj.value("count").isDouble()){
+        std.item_count = jsonObj.value("count").toInt();
+    }else{
+        qDebug() << "add_standard no count";
+        return false;
+    }
+
+    if(jsonObj.contains("item") && jsonObj.value("item").isArray()){
+        QJsonArray  jsonArray_i;
+        jsonArray_i = jsonObj.value("item").toArray();
+
+        if(std.item_count > 4){
+           std.item_count = 4;
+        }
+
+        for(int j =0 ; j<std.item_count; j++){
+            QJsonObject itemObj = jsonArray_i[j].toObject();
+
+            if(itemObj.contains("volume") && itemObj.value("volume").isDouble()){
+                std.item[j].oilcompartment_volume = itemObj.value("volume").toInt();
+            }
+
+            if(itemObj.contains("s_threshold") && itemObj.value("s_threshold").isDouble()){
+                std.item[j].system_threshold = itemObj.value("s_threshold").toDouble();
+            }
+
+            if(itemObj.contains("v_threshold") && itemObj.value("v_threshold").isDouble()){
+                std.item[j].valve_threshold = itemObj.value("v_threshold").toDouble();
+            }
+
+        }
+
+
+    }else{
+        qDebug() << "add_standard no item";
+        return false;
+    }
+
+    //check standard is exist?
+    for(int i=0; i < static_cast<int>(m_standard.size()); i++){
+        if(std.standard_name == m_standard[i].standard_name){
+            bExist = true;
+
+            m_standard[i].positive_target = std.positive_target;
+            m_standard[i].negative_target = std.negative_target;
+
+            m_standard[i].item_count = std.item_count;
+            for(int j=0; j< std.item_count; j++){
+                m_standard[i].item[j].oilcompartment_volume = std.item[j].oilcompartment_volume;
+                m_standard[i].item[j].system_threshold = std.item[j].system_threshold;
+                m_standard[i].item[j].valve_threshold = std.item[j].valve_threshold;
+            }
+
+        }
+    }
+
+    if(false == bExist){
+        m_standard.push_back(std);
+    }
+
+    save_standards();
+    qDebug() << "add_standard ok";
+
+    return true;
+}
+
+
+bool StandardManager::getStandard(const QString& name, Standard& standard)
+{
+
+    for(int i=0; i < static_cast<int>(m_standard.size()); i++){
+        if(name == m_standard[i].standard_name){
+            standard = m_standard.at(i);
+            return true;
+        }
+    }
+
+     return false;
+}

+ 67 - 0
Standard.h

@@ -0,0 +1,67 @@
+#ifndef STANDARD_H
+#define STANDARD_H
+
+#include <QObject>
+#include <QString>
+#include <QJsonObject>
+#include <QMap>
+
+#define MAX_STANDARD_ITEM  (8)
+#define MAX_STANDARD_NUM   (8)
+
+class StandardItem
+{
+public:
+   int oilcompartment_volume;   // L per unit
+   double system_threshold;      //Kpa
+   double valve_threshold;       //Kpa
+};
+
+
+class Standard
+{
+public:
+    QString standard_name;
+    double positive_target;
+    double negative_target;
+    int item_count;
+    StandardItem  item[MAX_STANDARD_ITEM];
+};
+
+
+
+class StandardManager: public QObject
+{
+    Q_OBJECT
+public:
+    static StandardManager* instance();
+    ~StandardManager();
+
+    bool getStandard(const QString& name, Standard& standard);
+    //void addStandard(const Standard& standard);
+    //void removeStandard(const QString& name);
+
+    Q_INVOKABLE void init();
+    //Q_INVOKABLE int getcount();
+    Q_INVOKABLE QJsonObject get_names();
+    Q_INVOKABLE QJsonObject get_standard(const QString name);
+    //add or modify
+    Q_INVOKABLE bool add_standard(const QString& jsonStr );
+    //remove
+    Q_INVOKABLE void remove_standard(const QString name);
+
+
+private:
+    explicit StandardManager(QObject* parent = nullptr);
+    std::vector<Standard>  m_standard;
+    //QMap<QString, QJsonObject> m_standardMap;
+    void add_GB();
+    void load_standards();
+    void save_standards();
+
+};
+
+#define g_StandardManager  StandardManager::instance()
+
+
+#endif // STANDARD_H

+ 20 - 0
StartStopButton.qml

@@ -0,0 +1,20 @@
+import QtQuick 2.11
+
+Item {
+    property bool running: false
+    Image {
+        id:image
+        anchors.fill: parent
+        source: running === true ?"qrc:/img/stop1.png":"qrc:/img/start1.png"
+        MouseArea{
+            anchors.fill: parent
+            onClicked: {
+                if(running === false)
+                    running = true
+                else
+                    running = false
+            }
+        }
+    }
+
+}

+ 95 - 0
StateTable.qml

@@ -0,0 +1,95 @@
+import QtQuick 2.11
+
+Item {
+    id:root
+    anchors.fill: parent
+    anchors.margins: 10
+    property int resultHeight: 25
+
+    //property string  titlestr
+    property string  state_str1
+    property string  state_str2
+    //property string  valvePressure_delta
+    //property string  negativeSysPressure
+    //property string  negativeValvePressure
+
+
+    Column{
+        anchors.centerIn: parent
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "white"
+            paraName: "系统运行状态:"
+            paraResult:""
+            paraUnit:""
+        }
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "#D2D5D9"
+            paraName: ""
+            paraResult:state_str1
+            paraResult_fontColor: "green"
+            paraUnit:""
+        }
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "#D2D5D9"
+            paraName: ""
+            paraResult:state_str2
+            paraResult_fontColor: "green"
+            paraUnit:""
+        }
+
+ /*
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "#DFE2E6"
+            paraName: "阀门密封性:"
+            paraResult:valvePressure_delta
+            paraUnit:"kPa"
+        }
+
+
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "white"
+            paraName: ""
+            paraResult:""
+            paraUnit:""
+        }
+
+
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "white"
+            paraName: "负压测试"
+            paraResult:""
+            paraUnit:""
+        }
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "#DFE2E6"
+            paraName: "系统密封性:"
+            paraResult:negativeSysPressure
+            paraUnit:"kPa"
+        }
+        ResultDisplayText{
+            width: root.width
+            height: root.resultHeight
+            color: "#D2D5D9"
+            paraName: "阀门密封性:"
+            paraResult:negativeValvePressure
+            paraUnit:"kPa"
+        }
+*/
+
+    }
+
+}

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 2079 - 0
TestService.cpp


+ 214 - 0
TestService.h

@@ -0,0 +1,214 @@
+#ifndef TESTSERVICE_H
+#define TESTSERVICE_H
+
+#include <QTimer>
+#include <QDateTime>
+#include <QtSerialPort/QSerialPort>
+#include <QObject>
+#include <QSemaphore>
+#include <QThread>
+#include <QString>
+#include <QVector>
+#include <QMutex>
+#include <QDebug>
+//#include"Standard.h"
+#include "tank.h"
+#include "report.h"
+#include"Msgbox.h"
+#include"serialui.h"
+#include <QSignalSpy>
+
+//#define MAX_COMPARTMENT_NUM  (4)
+#define AVERAGE_PRESSURE_COUNT (2)   //5个不代表5秒, 要看采样频率
+
+typedef enum _Ret_Value{
+    Ret_Failed = -2,
+    Ret_Timeout = -1,
+    Ret_OK = 0,
+    Ret_Exit = 1
+}Ret_Value;
+
+
+enum Valve_OP{
+    Valve_OP_Open = 0,
+    Valve_OP_Close,
+};
+
+enum Test_Step{
+    Test_Step_Start,
+    Test_Step_AddPressure,
+    Test_Step_AdjustPressure,
+    Test_Step_KeepPressure,
+    Test_Step_reliefPressure,
+    Test_Step_End,
+};
+
+enum Test_Stage{
+    Test_Stage_SysTest,
+    Test_Stage_ValveTest,
+    Test_Step_UNKown,
+};
+
+enum Test_Direction{
+    Test_Direction_Positive,
+    Test_Direction_Negative,
+    Test_Direction_Unkown,
+};
+
+
+class TestExpect{
+public:
+    int start_voltage;
+    float target;   //pressure value
+    int timeout;       // timeout (s)
+};
+
+
+class TestService: public QThread
+{
+    Q_OBJECT
+    Q_ENUMS(Valve_ID)
+
+public:
+    TestService(QThread *parent = nullptr);
+    ~TestService();
+
+    enum Valve_ID {
+        Valve_ID_ROUGH_0=0,       //粗调阀
+        Valve_ID_ROUGH_1,         //
+        Valve_ID_ROUGH_2,
+        Valve_ID_CALIBRATION,     //压力校准阀
+        Valve_ID_PRESSURESENSOR,  //压力传感阀
+        Valve_ID_VACUUM,          //真空阀
+        Valve_ID_VENT,            //泄气阀
+        Valve_ID_INTAKE,          //进气阀
+        Valve_ID_8,
+        Valve_ID_9,
+        Valve_ID_10,
+        Valve_ID_11,
+        Valve_ID_12,
+        Valve_ID_13,
+        Valve_ID_14,
+        Valve_ID_15,
+        Valve_ID_All,
+    };
+
+
+    Q_INVOKABLE  void init();
+    Q_INVOKABLE  bool setTankinfo(const QVariantList& list);
+    Q_INVOKABLE  void valve_open(Valve_ID id);
+    Q_INVOKABLE  void valve_close(Valve_ID id);
+    Q_INVOKABLE QString read_PressureValue();
+    Q_INVOKABLE void adjust_Pressure(QString voltage_str);
+    Q_INVOKABLE bool tstart(int compartmentid, int direction);  //direction : 0 positive test , 1 negative test
+    Q_INVOKABLE bool tselfstart(int compartmentid, int direction);  //direction : 0 positive test , 1 negative test
+    Q_INVOKABLE bool tstop(int compartmentid);
+    Q_INVOKABLE bool reportpic_Ready(int compartmentid);
+    Q_INVOKABLE bool check_alltest_ok();
+    Q_INVOKABLE bool genReport(QString word_path, QString pic_dir);
+
+    Q_INVOKABLE QJsonObject get_vrs_items();
+    Q_INVOKABLE QJsonObject get_bls_items();
+    Q_INVOKABLE bool set_item_result(const QString& jsonStr );
+
+
+signals:
+   void sigPressure(int id, QVariantMap  pressure_map);
+
+   void sigState(int id, QString state_str1, QString state_str2);
+   void sigSystemResult(int id, QString delta_str, bool bPassed);
+   void sigValveResult(int id, QString delta_str, bool bPassed);
+   void sigSelfTestResult(int id, QString delta_str, bool bPassed);
+   void sigStop(int id);
+
+   void onNotice(QString qstr);
+   void onWarning(QString qstr);
+   void onGenreportProgress(QString qstr);
+
+   void operate();
+
+public slots:
+   void receive_reportprogress(QString qstr);
+
+private:
+
+    unsigned short Calcrc(const unsigned char *ptr, int count);
+    void SendCmd(QSerialPort* pSerial, QByteArray data);
+    bool check_crc(QByteArray data);
+
+
+    bool Valve_op(Valve_ID id, Valve_OP op);
+    bool Read_pressure(float & pressure);
+    bool Adjust_pressure(unsigned short voltage);
+
+    void push_pressurelist(float pressure);
+    void clear_pressurelist();
+    float calculate_averagepressure();
+
+    bool OpenSerial3();
+    bool OpenSerial4();
+
+    // 0   ok
+    // -1  timeout
+    // -2  error
+    Ret_Value  Pressure_Adjust(const TestExpect& expect);
+
+    // 0   ok
+    // -1  timeout
+    // -2  error
+    Ret_Value  Pressure_RoughAdjust(const TestExpect& expect);
+
+    // 0   ok
+    // -1  timeout
+    // -2  error
+    Ret_Value  Pressure_Relief(const TestExpect& expect);
+
+
+    //0 pass
+    //-1 nopass
+    Ret_Value  Pressure_Keep(int keeptime, float threshold, float& delta);
+
+
+    int make_messagebox(Test_Direction direction, Test_Step step, Ret_Value ret_v);
+
+
+   QSerialPort * m_SerialPort3;
+   QSerialPort * m_SerialPort4;
+   QMutex        m_Serial3mutex;
+   QMutex        m_Serial4mutex;
+   //QSignalSpy    m_spy3
+   SerialUi      m_SerialUi3;
+   SerialUi      m_SerialUi4;
+
+   QTimer *      m_pTimer_1;  //read pressure value
+   QTimer*       m_pTimer_2;  // testing process
+   //QThread       m_Thread;
+   int           m_compartmentid;
+   bool          m_bRunning;
+
+   Tanker        m_tank;
+   QString       m_standardname;
+   Report        m_report;
+
+   QList<float>  m_pressurelist; //用来计算平均压力
+   QMutex        m_pressuremutex;
+
+   Test_Stage     m_stage;
+   Test_Step      m_step;
+   Test_Direction m_direction;
+
+   MsgBox         m_msgbox;
+
+
+ protected:
+    void run() override;
+
+ public slots:
+
+ private slots:
+     void OnTimer1();
+     void OnTimer2();
+
+ };
+
+#endif // TESTSERVICE_H

+ 50 - 0
UserButton.qml

@@ -0,0 +1,50 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.4
+
+Button {
+    id: root_Button
+    font.pointSize: 16 // 设置字体大小
+
+    property color clr_font: "#ffffff"
+    property color clr_backNormal: "#498ff8"
+    property color clr_backPress: "#0066FF"
+    property color clr_boardNormal: "#498ff8"
+    property color clr_boardPress: "#0066FF"
+
+    // 设置按钮文本
+    contentItem: Text {
+        id: text2
+        text: root_Button.text
+        font: root_Button.font
+        opacity: enabled ? 1.0 : 0.3
+        //color: clr_font
+        horizontalAlignment: Text.AlignHCenter
+        verticalAlignment: Text.AlignVCenter
+        elide: Text.ElideRight
+    }
+
+    // 设置按钮背景
+    background: Rectangle {
+        implicitWidth: 100
+        implicitHeight: 60
+        opacity: enabled ? 1 : 0.3
+        color: "transparent"
+            Image {
+            anchors.fill:parent
+            fillMode: Image.PreserveAspectFit
+            source:"img/blue_button.png"
+        }
+    }
+
+   /*
+        Rectangle {
+        implicitWidth: 100
+        implicitHeight: 40
+        opacity: enabled ? 1 : 0.3
+        color: root_Button.down ? clr_backPress : clr_backNormal
+        border.color: root_Button.down ? clr_boardPress : clr_boardNormal
+        border.width: 1
+        radius: 6
+    }
+    */
+}

+ 90 - 0
UserComboBox.qml

@@ -0,0 +1,90 @@
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+
+ComboBox {
+    id: control
+    property var bgColor
+    font.bold: true
+    font.pixelSize: 20
+
+    delegate: ItemDelegate {
+        width: control.width
+        height: control.height
+        contentItem: Text {
+            text: modelData
+            color: "black"
+            font: control.font
+            elide: Text.ElideRight
+            verticalAlignment: Text.AlignVCenter
+        }
+        highlighted: control.highlightedIndex === index
+    }
+
+    indicator: Canvas {
+        id: canvas
+        x: control.width - width - control.rightPadding
+        y: control.topPadding + (control.availableHeight - height) / 2
+        width: 12
+        height: 8
+        contextType: "2d"
+        Connections {
+            target: control
+            function onPressedChanged() { canvas.requestPaint(); }
+        }
+
+        onPaint: {
+            context.reset();
+            context.moveTo(0, 0);
+            context.lineTo(width, 0);
+            context.lineTo(width / 2, height);
+            context.closePath();
+            //context.fillStyle = control.pressed ? "red" : "green";
+            context.fillStyle ="gray"
+            context.fill();
+        }
+    }
+
+    contentItem: Text {
+        leftPadding: 5
+        rightPadding: control.indicator.width + control.spacing
+
+        text: control.displayText
+        font: control.font
+        color: "black"
+        //color: control.pressed ? "#17a81a" : "#21be2b"
+        verticalAlignment: Text.AlignVCenter
+        elide: Text.ElideRight
+    }
+
+    background: Rectangle {
+        implicitWidth: control.width-2
+        implicitHeight: control.height-2
+        color: bgColor
+        //border.color: control.pressed ? "#17a81a" : "#21be2b"
+        //border.width: control.visualFocus ? 2 : 0
+        radius: 3
+    }
+
+    popup: Popup {
+        y: control.height - 1
+        width: control.width
+        implicitHeight: contentItem.implicitHeight
+        padding: 1
+
+
+        contentItem: ListView {
+            clip: true
+            implicitHeight: contentHeight+3
+            model: control.popup.visible ? control.delegateModel : null
+            currentIndex: control.highlightedIndex
+
+            ScrollIndicator.vertical: ScrollIndicator { }
+        }
+
+        background: Rectangle {
+            border.color: "gray"//"#21be2b"
+            radius: 2
+            opacity:1.0
+        }
+    }
+}

+ 37 - 0
UserRadioButton.qml

@@ -0,0 +1,37 @@
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+
+//自定义单选按钮
+RadioButton {
+      id: control
+      text: qsTr("UserRadioButton")
+      checked: true
+
+      indicator: Rectangle {
+          implicitWidth: 18
+          implicitHeight: 18
+          x: control.leftPadding
+          y: parent.height / 2 - height / 2
+          radius: 9
+          border.color: control.down ? "#17a81a" : "#0099cc"
+
+          Rectangle {
+              width: 12
+              height: 12
+              x: 3  // (56 - 34) / 2
+              y: 3
+              radius: 6
+              color: control.down ? "#17a81a" : "#0099cc"
+              visible: control.checked
+          }
+      }
+
+      contentItem: Text {
+          text: control.text
+          font: control.font
+          opacity: enabled ? 1.0 : 0.3
+          //color: control.down ? "#17a81a" : "#21be2b"
+          verticalAlignment: Text.AlignVCenter
+          leftPadding: control.indicator.width + control.spacing
+      }
+}

+ 61 - 0
UserSwitch.qml

@@ -0,0 +1,61 @@
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+
+  Switch {
+      id: control
+      text: qsTr("Switch")
+
+      //background: Rectangle{
+          //color: "lightyellow"
+     //     implicitWidth: 60
+     //     implicitHeight: 40
+     // }
+
+      indicator: Rectangle {
+          implicitWidth: 48
+          implicitHeight: 26
+          x: control.leftPadding
+          y: parent.height / 2 - height / 2
+
+          radius: 13
+          color: control.checked ? "green" : "#ffffff"
+          border.color: control.checked ? "green" : "#cccccc"
+
+          //小圆点
+          Rectangle {
+              id : smallRect
+              width: 26
+              height: 26
+              radius: 13
+              color: control.down ? "#cccccc" : "#ffffff"
+              border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999"
+
+            //改变小圆点的位置
+              NumberAnimation on x{
+                  to: smallRect.width
+                  running: control.checked ? true : false
+                  duration: 200
+              }
+
+            //改变小圆点的位置
+              NumberAnimation on x{
+                  to: 0
+                  running: control.checked ? false : true
+                  duration: 200
+              }
+          }
+      }
+
+      //要显示的文本
+      contentItem: Text {
+          //text: control.checked.toString()
+          text: control.text
+          font.pixelSize: 13
+          font.bold: true
+          //鼠标按下时  control.down
+          color: control.checked ? "green" : "gray"
+          verticalAlignment: Text.AlignVCenter
+          anchors.left: indicator.right
+      }
+}
+

+ 166 - 0
UserTableView.qml

@@ -0,0 +1,166 @@
+import QtQuick 2.13
+import QtQuick.Controls 2.13
+import Qt.labs.qmlmodels 1.0
+
+Rectangle {
+    property  string table_name:"null"
+    color:"transparent"
+    //anchors.fill: parent
+
+    function add_item(item)
+    {
+        //console.log("add_item name:"+item.name+", value :" + item.value)
+        tableModel.appendRow({"name":item.name,"value":item.value})
+    }
+
+
+    Rectangle{
+        id:header
+        width: parent.width
+        height: 30
+        color: "transparent"
+
+        Row{
+            spacing: 0
+
+            Repeater{
+                model: ["项目","外观检查结果"]
+
+                Rectangle{
+                    width: {
+                        var w = 0
+                        switch(index){
+                        case 0: w = 130;break;
+                        case 1: w = 230;break;
+                        }
+                        return w
+                    }
+                    height: header.height
+                    color: "#C9DDF8"  //"#666666"
+                    border.width: 1
+                    border.color: "#97C4F5"   //"#848484"
+                    Text {
+                        text: modelData
+                        anchors.centerIn: parent
+                        font.pointSize: 12
+                        color: "black"
+                    }
+                }
+            }
+        }
+    }
+    TableView{
+        id:tableView
+        width: parent.width
+        anchors.top:header.bottom
+        anchors.left: parent.left
+        anchors.right: parent.right
+        anchors.bottom: parent.bottom
+        clip: true
+        boundsBehavior: Flickable.OvershootBounds
+
+/*
+        ScrollBar.vertical: ScrollBar {
+            anchors.right:parent.right
+            anchors.rightMargin: 0
+            visible: tableModel.rowCount > 5
+            background: Rectangle{
+                color:"#666666"
+            }
+            onActiveChanged: {
+                active = true;
+            }
+            contentItem: Rectangle
+            {
+                implicitWidth  : 6
+                implicitHeight : 30
+                radius : 3
+                color  : "#848484"
+            }
+        }
+
+        */
+
+        model: TableModel {
+            id:tableModel
+
+            TableModelColumn{display: "name"}
+            TableModelColumn{display: "value"}
+
+        }
+        delegate:DelegateChooser{
+
+            DelegateChoice{
+                column: 0
+                delegate: Rectangle{
+                    color: "transparent" //"#666666"
+                    implicitWidth: 130
+                    implicitHeight: 32
+                    border.width: 1
+                    border.color: "#97C4F5"   //"#848484"
+
+                    Text {
+                        text: display
+                        anchors.fill: parent
+                        verticalAlignment: Text.AlignVCenter
+                        leftPadding: 10
+                        font.pixelSize: 14
+                        color: "black"
+                    }
+                }
+            }
+
+
+            DelegateChoice{
+                column: 1
+                delegate: Rectangle{
+                    color: "transparent"   //"#666666"
+                    implicitWidth: 230
+                    implicitHeight: 32
+                    border.width: 1
+                    border.color: "#97C4F5"   //"#848484"
+
+                    UserTristate{
+                         id:utr
+                         state: display
+                         onUsateChanged: {
+                            //console.log("b row:"+row+",utr value :" + utr.value +", result:" + model.display)
+
+                             if("0" === state)
+                                model.display = "0"
+                             if("1" === state)
+                                model.display = "1"
+                             if("2" === state)
+                                model.display = "2"
+
+                            // console.log("a row:"+row +", name:"+tableModel.rows[row].name +", display:" + model.display)
+
+                             var itemJson={}
+
+                             itemJson.table = table_name
+                             itemJson.name = tableModel.rows[row].name
+                             itemJson.value = model.display
+
+                             testService.set_item_result(JSON.stringify(itemJson))
+                         }
+                    }
+
+
+                }
+            }
+        }
+    }
+
+/*
+    Component.onCompleted: {
+        tableModel.appendRow({"name":"小明","value":"0"})
+        tableModel.appendRow({"name":"小刚","value":"1"})
+        tableModel.appendRow({"name":"小李","value":"2"})
+        tableModel.appendRow({"name":"小王","value":"0"})
+        tableModel.appendRow({"name":"小张","value":"0"})
+        tableModel.appendRow({"name":"小林","value":"0"})
+    }
+*/
+
+}
+

+ 88 - 0
UserTristate.qml

@@ -0,0 +1,88 @@
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+
+Item {
+    id:root
+    anchors.fill: parent
+    anchors.margins: 1
+    property  int fontsize:14
+    property  string fontcolor:"black"
+    //property  string text:"0.000"
+    //property  int value:0
+    //property  int value_tmp:0
+    property  string text_state1:"合格"
+    property  string text_state2:"不合格"
+    property  string text_state3:"无此项"
+    signal usateChanged
+
+    state: "0"
+
+    states:[
+        State {
+            name: "0"
+            PropertyChanges {target:rb1; checked:true}
+            PropertyChanges {target:rb2; checked:false}
+            PropertyChanges {target:rb3; checked:false}
+        },
+        State {
+            name: "1"
+            PropertyChanges {target:rb1; checked:false}
+            PropertyChanges {target:rb2; checked:true}
+            PropertyChanges {target:rb3; checked:false}
+        },
+        State {
+            name: "2"
+            PropertyChanges {target:rb1; checked:false}
+            PropertyChanges {target:rb2; checked:false}
+            PropertyChanges {target:rb3; checked:true}
+        }
+    ]
+
+
+    ButtonGroup{
+        id:group
+        buttons: row.children
+        onClicked:{
+            //console.log("tristate clicked:", button.text)
+            var old_state = state
+
+            if(text_state1 === button.text){
+                state = "0"
+            }else if(text_state2 === button.text){
+                state = "1"
+            }else if(text_state3 === button.text){
+                state = "2"
+            }
+
+            if(old_state !== state){
+                //value = value_tmp
+                root.usateChanged()
+            }
+        }
+    }
+
+    Row{
+        id: row
+        UserRadioButton{
+            id:rb1
+            checked: true
+            text: text_state1
+            font.pixelSize: fontsize
+
+        }
+
+        UserRadioButton{
+            id:rb2
+            checked: false
+            text: text_state2
+            font.pixelSize: fontsize
+        }
+
+        UserRadioButton{
+            id:rb3
+            checked: false
+            text: text_state3
+            font.pixelSize: fontsize
+        }
+    }
+}

+ 54 - 0
ValveTest.pro

@@ -0,0 +1,54 @@
+QT += quick charts
+QT   += serialport
+QT += testlib
+QT += widgets
+QT += virtualkeyboard axcontainer
+
+
+
+# You can make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        DLog.cpp \
+        Modbus.cpp \
+        Msgbox.cpp \
+        Standard.cpp \
+        TestService.cpp \
+        main.cpp \
+        pid.cpp \
+        report.cpp \
+        serialport.cpp \
+        serialui.cpp \
+        tank.cpp
+
+RESOURCES += qml.qrc
+RC_ICONS += $$PWD/valve.ico
+
+DEFINES += QT_MESSAGELOGCONTEXT
+
+# Additional import path used to resolve QML modules in Qt Creator's code model
+QML_IMPORT_PATH =
+
+# Additional import path used to resolve QML modules just for Qt Quick Designer
+QML_DESIGNER_IMPORT_PATH =
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+HEADERS += \
+    DLog.h \
+    Modbus.h \
+    Msgbox.h \
+    Standard.h \
+    TestService.h \
+    pid.h \
+    report.h \
+    serialport.h \
+    serialui.h \
+    tank.h
+
+DISTFILES +=

+ 265 - 0
ValveTest.pro.user

@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 8.0.0, 2023-03-20T14:00:05. -->
+<qtcreator>
+ <data>
+  <variable>EnvironmentId</variable>
+  <value type="QByteArray">{696f416c-364e-44fe-b1a5-f34ece895f51}</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.ActiveTarget</variable>
+  <value type="qlonglong">0</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.EditorSettings</variable>
+  <valuemap type="QVariantMap">
+   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+    <value type="QString" key="language">Cpp</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+    </valuemap>
+   </valuemap>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+    <value type="QString" key="language">QmlJS</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+    </valuemap>
+   </valuemap>
+   <value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
+   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+   <value type="bool" key="EditorConfiguration.ConstrainTooltips">true</value>
+   <value type="int" key="EditorConfiguration.IndentSize">4</value>
+   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+   <value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
+   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+   <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
+   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+   <value type="int" key="EditorConfiguration.TabSize">8</value>
+   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+   <value type="bool" key="EditorConfiguration.UseIndenter">false</value>
+   <value type="int" key="EditorConfiguration.Utf8BomBehavior">0</value>
+   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+   <value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
+   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+   <value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.PluginSettings</variable>
+  <valuemap type="QVariantMap">
+   <valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
+    <value type="bool" key="AutoTest.Framework.Boost">true</value>
+    <value type="bool" key="AutoTest.Framework.CTest">false</value>
+    <value type="bool" key="AutoTest.Framework.Catch">true</value>
+    <value type="bool" key="AutoTest.Framework.GTest">true</value>
+    <value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
+    <value type="bool" key="AutoTest.Framework.QtTest">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
+   <value type="int" key="AutoTest.RunAfterBuild">0</value>
+   <value type="bool" key="AutoTest.UseGlobal">true</value>
+   <valuemap type="QVariantMap" key="ClangTools">
+    <value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
+    <value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
+    <value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
+    <value type="int" key="ClangTools.ParallelJobs">4</value>
+    <valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
+    <valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
+    <valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
+    <value type="bool" key="ClangTools.UseGlobalSettings">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="CppEditor.QuickFix">
+    <value type="bool" key="UseGlobalSettings">true</value>
+   </valuemap>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.0</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="DeviceType">Desktop</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.15.2 MinGW 32-bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.15.2 MinGW 32-bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5152.win32_mingw81_kit</value>
+   <value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
+   <value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="int" key="EnableQmlDebugging">0</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:\Code\QTapps\build-ValveTest-Desktop_Qt_5_15_2_MinGW_32_bit-Debug</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">D:/Code/QTapps/build-ValveTest-Desktop_Qt_5_15_2_MinGW_32_bit-Debug</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:\Code\QTapps\build-ValveTest-Desktop_Qt_5_15_2_MinGW_32_bit-Release</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">D:/Code/QTapps/build-ValveTest-Desktop_Qt_5_15_2_MinGW_32_bit-Release</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="int" key="QtQuickCompiler">0</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+    <value type="int" key="EnableQmlDebugging">0</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">D:\Code\QTapps\build-ValveTest-Desktop_Qt_5_15_2_MinGW_32_bit-Profile</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">D:/Code/QTapps/build-ValveTest-Desktop_Qt_5_15_2_MinGW_32_bit-Profile</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+      <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+     </valuemap>
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="int" key="QtQuickCompiler">0</value>
+    <value type="int" key="SeparateDebugInfo">0</value>
+   </valuemap>
+   <value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
+    <value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <valuelist type="QVariantList" key="CustomOutputParsers"/>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:D:/Code/QTapps/ValveTest/ValveTest.pro</value>
+    <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">D:/Code/QTapps/ValveTest/ValveTest.pro</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+    <value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/Code/QTapps/build-ValveTest-Desktop_Qt_5_15_2_MinGW_32_bit-Release</value>
+   </valuemap>
+   <value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.TargetCount</variable>
+  <value type="qlonglong">1</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+  <value type="int">22</value>
+ </data>
+ <data>
+  <variable>Version</variable>
+  <value type="int">22</value>
+ </data>
+</qtcreator>

+ 750 - 0
breatheTest.js

@@ -0,0 +1,750 @@
+.import "modbus.js" as ModbusJs
+
+
+var running = false
+var runningBackup = false
+var openPressureTimeMax = 30
+var sealPressureTimemax = 15
+var exit = false
+
+var capsizeOpenPresure = 10
+var capsizeSetPressure = 32
+
+function positiveTestStop(controlSerial,pressureDisplaySigFun,spy,log){
+
+    ModbusJs.pressureSensorCtrl(controlSerial,"高压")
+    console.log("打开高压传感器阀门")
+    //关闭正压罐进气阀门
+    ModbusJs.positivePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭正压罐进气阀门")
+    //打开正压罐头泄气阀门
+    ModbusJs.positivePressureTankOutputCtrl(controlSerial,true)
+    console.log("打开正压罐头泄气阀门")
+    //查看高压传感器值 等待正压罐头压力降到最低值
+    var timeout = 0
+    do{
+        //重新开始时 停止测试
+        if(runningBackup === false && running === true){
+            console.log("停止测试")
+            ModbusJs.closeAllValve(controlSerial)
+            return
+        }
+        if(exit === true)
+            return
+
+
+        var obj = ModbusJs.highPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("高压传感器通讯错误")
+            return false
+        }
+        // signal 压力显示函数
+        pressureDisplaySigFun(obj.pressureNumber)
+        //延时
+        spy.wait(900)
+        timeout++
+
+    }while(obj.pressureNumber > 0.1 && timeout < 180)
+    ModbusJs.closeAllValve(controlSerial)
+    console.log("关闭 关闭所有阀门")
+}
+
+function negativeTestStop(controlSerial,pressureDisplaySigFun,spy,log){
+
+    //打开负压呼吸阀测试口阀门 逻辑有改变 从一开始就打开 不然无法泄压
+    ModbusJs.nbreathValveTestIo(controlSerial,true)
+    console.log("打开负压呼吸阀测试口阀门")
+    //关闭负压罐进气阀门
+    ModbusJs.negativePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭负压罐进气阀门")
+    //关闭 负压泵
+    ModbusJs.negativePumpPowerCtrl(controlSerial,false)
+    console.log("关闭 负压泵")
+    //打开负压罐头泄气阀门
+    ModbusJs.negativePressureTankOutputCtrl(controlSerial,true)
+    console.log("打开负压罐头泄气阀门")
+    //查看负压传感器值 等待负压罐头压力降到最低值
+    var timeout = 0
+    do{
+        //重新开始时 停止测试
+        if(runningBackup === false && running === true){
+            console.log("停止测试")
+            ModbusJs.closeAllValve(controlSerial)
+            return
+        }
+        if(exit === true)
+            return
+
+        //var obj = ModbusJs.negativePressureSensorReadReq(sensorSerial)
+        var obj =ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("低压传感器通讯错误")
+            return false
+        }
+        // signal 压力显示函数
+        pressureDisplaySigFun(obj.pressureNumber)
+        //延时
+        spy.wait(900)
+        timeout++
+    }while(obj.pressureNumber < -0.1 && timeout < 180)
+    ModbusJs.closeAllValve(controlSerial)
+    console.log("关闭 关闭所有阀门")
+}
+
+
+
+//正压开启压力和密封试验
+/*  openPressureModel       测试开启压力过程表模型
+ *  sealPressureModel       测试密封压力过程表模型
+ *  pressureDisplaySigFun   压力显示信号函数
+ *  resultSigFun            结果显示信号函数
+ */
+function positiveTestStart(currentIndex,tabView,processWindow,controlSerial,sensorSerial,openPressureModel,sealPressureModel,pressureDisplaySigFun,resultSigFun,spy,log){
+
+    var setPressure = 20
+    //自检
+    runningBackup = running
+    var openPressureNumber
+    var sealPressureNumber
+
+    //setp 1
+    // 关闭所有测试口
+    ModbusJs.turnOffAllTestIO(controlSerial)
+    console.log("关闭所有测试口")
+    ModbusJs.pressureSensorCtrl(controlSerial,"高压")
+    console.log("打开高压传感器阀门")
+    //关闭正压罐进气阀门
+    ModbusJs.positivePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭正压罐进气阀门")
+    //setp 2
+    //查看低压传感器值 等待正压罐头压力降到最低值
+    processWindow.show("等待压力降到0")
+    //打开正压罐头泄气阀门
+    ModbusJs.positivePressureTankOutputCtrl(controlSerial,true)
+    console.log("打开正压罐头泄气阀门")
+    var timeout = 0
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+        var obj = ModbusJs.highPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("高压传感器通讯错误")
+            return false
+        }
+        // signal 压力显示函数
+        pressureDisplaySigFun(obj.pressureNumber)
+        //延时
+        spy.wait(900)
+        timeout++
+    }while(obj.pressureNumber > 0.1 && timeout < 180)
+    if(timeout === 180){
+        log.show("泄压超时")
+        ModbusJs.closeAllValve(controlSerial)
+        console.log("关闭所有阀门")
+        return false
+    }
+    console.log("压力降压到 0 kPa")
+
+    //setp 3
+    /*********测试开启压力*************/
+    ModbusJs.pressureSensorCtrl(controlSerial,"低压")
+    console.log("打开低压传感器阀门")
+    obj = ModbusJs.testFixedPressure(controlSerial,setPressure)
+    ModbusJs.proportionalControlWrite(controlSerial,obj.voltage)
+    console.log("比例调压阀压力值:",obj.voltage)
+
+    var bigAcive = true
+    ModbusJs.bigTuningValveControl(controlSerial,true)
+    console.log("打开 粗调开关")
+
+    processWindow.show("开启压力试验开始")
+    console.log("开启压力测试开始")
+//    //打开正压呼吸阀测试口阀门
+//    ModbusJs.pbreathValveTestIo(controlSerial,true)
+//    console.log("打开正压呼吸阀测试口阀门")
+    //关闭正压罐头泄气阀门
+    ModbusJs.positivePressureTankOutputCtrl(controlSerial,false)
+    console.log("关闭正压罐头泄气阀门")
+    //打开进气阀门
+    ModbusJs.positivePressureTankInputCtrl(controlSerial,true)
+    console.log("打开进气阀门")
+    tabView.currentIndex = currentIndex
+    var openCnt = 0
+    var min = 0
+    var max = 100  //低压最大范围
+    var prevTime  = Date.now()
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+        //obj = ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        obj = ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("低压传感器通讯错误")
+            return false
+        }
+
+        //粗调压力值
+        var bigLevel = setPressure-1
+        //达到压力值时打开测试口
+        if(obj.pressureNumber > bigLevel && bigAcive === true){
+            bigAcive = false
+            ModbusJs.bigTuningValveControl(controlSerial,false)
+            ModbusJs.bigTuningValveControl(controlSerial,false)
+            console.log("关闭 粗调开关")
+            //打开正压呼吸阀测试口阀门
+            ModbusJs.pbreathValveTestIo(controlSerial,true)
+            console.log("打开正压呼吸阀测试口阀门")
+        }
+
+        spy.wait(10)
+        var curTime  = Date.now()
+        var deltaTime = curTime - prevTime
+        if(deltaTime > 900){
+            prevTime = curTime
+            openCnt++
+            pressureDisplaySigFun(obj.pressureNumber)
+            // add  pressure table
+            var table={}
+            table.pressure=obj.pressureNumber
+            //开启压力模型赋值
+            openPressureModel.append(table)
+           // console.log("openPressureTimeMax:",openPressureTimeMax)
+            processWindow.text("开启压力试验时间"+(openPressureTimeMax-openCnt)+"s")
+        }
+
+    }while(obj.pressureNumber <=max && openCnt < openPressureTimeMax)
+
+    //正压:6~12kPa  得到开启压力
+    if(obj.pressureNumber >=min &&  obj.pressureNumber <= max && openCnt ===openPressureTimeMax){
+        openPressureNumber = obj.pressureNumber.toString()
+        var result={}
+        result.openPressureNumber = openPressureNumber
+        result.sealPressureNumber = ""
+        resultSigFun(result)
+        console.log("开启压力:",openPressureNumber)
+    }
+    else{
+        if(obj.pressureNumber < min){
+            openPressureNumber=obj.pressureNumber+"<"+min+"kPa"
+        }
+        else if(obj.pressureNumber > max){
+            openPressureNumber=obj.pressureNumber+">"+max+"kPa"
+        }
+
+        result={}
+        result.openPressureNumber = openPressureNumber
+        result.sealPressureNumber = ""
+        resultSigFun(result)
+
+        //关闭正压罐进气阀门
+        ModbusJs.positivePressureTankInputCtrl(controlSerial,false)
+        console.log("关闭正压罐进气阀门")
+        console.log("开启压力:",openPressureNumber)
+        console.log("开启压力测试结束")
+
+        return false
+    }
+    console.log("开启压力测试结束")
+
+    //setp 4
+    /*********测试密封压力*************/
+    console.log("密封压力开始")
+    processWindow.show("密封压力试验开始")
+    //关闭正压罐进气阀门
+    ModbusJs.positivePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭正压罐进气阀门")
+    //保持600s
+    var holdTimeCnt=0
+    tabView.currentIndex = currentIndex+3
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+        //obj = ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        obj = ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("低压传感器通讯错误")
+            return false
+        }
+        //密封压力模型赋值
+        table={}
+        table.pressure=obj.pressureNumber
+        sealPressureModel.append(table)
+        //压力实时显示
+        pressureDisplaySigFun(obj.pressureNumber)
+        spy.wait(900)
+        holdTimeCnt++
+        processWindow.text("密封压力试验时间"+(sealPressureTimemax-holdTimeCnt)+"s")
+    }while(holdTimeCnt < sealPressureTimemax ) //传感器值是否能一直稳定住??????
+
+    sealPressureNumber = obj.pressureNumber.toString()
+    result={}
+    result.openPressureNumber = openPressureNumber
+    result.sealPressureNumber = sealPressureNumber
+    resultSigFun(result)
+    console.log("密封压力结束")
+
+
+    //setp 5
+    ModbusJs.pressureSensorCtrl(controlSerial,"高压")
+    console.log("打开高压传感器阀门")
+    //打开正压罐头泄气阀门
+    ModbusJs.positivePressureTankOutputCtrl(controlSerial,true)
+    console.log("打开正压罐头泄气阀门")
+    console.log("等待压力 0kPa")
+    //查看低压传感器值 等待正压罐头压力降到最低值
+    processWindow.show("试验结束,泄气中")
+    timeout = 0
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+
+        obj = ModbusJs.highPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("高压传感器通讯错误")
+            return false
+        }
+        // signal 压力显示函数
+        pressureDisplaySigFun(obj.pressureNumber)
+        //延时
+        spy.wait(900)
+        timeout++
+    }while(obj.pressureNumber > 0.1 && timeout < 180)
+
+    //关闭正压罐头泄气阀门
+
+    //setp 6
+    console.log("压力 0kPa")
+    ModbusJs.closeAllValve(controlSerial)
+    console.log("关闭所有阀门")
+
+    return true
+
+}
+//负压开启压力和密封试验
+/*  openPressureModel       测试开启压力过程表模型
+ *  sealPressureModel       测试密封压力过程表模型
+ *  pressureDisplaySigFun   压力显示信号函数
+ *  resultSigFun            结果显示信号函数
+ */
+
+function negativeTestStart(currentIndex,tabView,processWindow,controlSerial,sensorSerial,
+                           openPressureModel,sealPressureModel,
+                           pressureDisplaySigFun,resultSigFun,spy,log)
+{
+
+    runningBackup = running
+    //自检
+    var openPressureNumber
+    var sealPressureNumber
+    //setp 1
+    // 关闭所有测试口
+    ModbusJs.negativePumpPowerCtrl(controlSerial,false)
+    console.log("关闭 负压泵")
+    ModbusJs.turnOffAllTestIO(controlSerial)
+    console.log("关闭所有测试口")
+    //打开负压呼吸阀测试口阀门 逻辑有改变 从一开始就打开 不然无法泄压
+    ModbusJs.nbreathValveTestIo(controlSerial,true)
+    console.log("打开负压呼吸阀测试口阀门")
+    ModbusJs.pressureSensorCtrl(controlSerial,"负压")
+    console.log("打开负压传感器阀门")
+    //关闭负压罐进气阀门
+    ModbusJs.negativePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭负压罐进气阀门 微调")
+    processWindow.show("等待压力到0kPa")
+    //打开负压罐头泄气阀门
+    ModbusJs.negativePressureTankOutputCtrl(controlSerial,true)
+    console.log("打开负压罐头泄气阀门")
+    //setp 2
+    //查看负压传感器值 等待负压压罐头压力至0kPa
+    var timeout = 0
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+        //var obj = ModbusJs.negativePressureSensorReadReq(sensorSerial)
+        var obj =ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("低压传感器通讯错误")
+            return false
+        }
+        //signal 压力显示函数
+        console.log(obj.pressureNumber)
+        pressureDisplaySigFun(obj.pressureNumber)
+        //延时
+        spy.wait(900)
+        timeout++
+    }while(obj.pressureNumber < 0 && timeout < 180)
+    if(timeout === 180){
+        log.show("泄压超时")
+        ModbusJs.closeAllValve(controlSerial)
+        console.log("关闭所有阀门")
+        return false
+    }
+    console.log("压力到 0 kPa")
+
+    //setp 3
+    /*********测试开启压力*************/
+    ModbusJs.negativePumpPowerCtrl(controlSerial,true)
+    console.log("打开 负压泵")
+    processWindow.show("开启压力试验开始")
+    console.log("开启压力测试开始")
+    //打开负压呼吸阀测试口阀门 全称微调 不需要打开 逻辑有改变
+//    ModbusJs.nbreathValveTestIo(controlSerial,true)
+//    console.log("打开负压呼吸阀测试口阀门")
+    //关闭负压罐泄气阀门
+    ModbusJs.negativePressureTankOutputCtrl(controlSerial,false)
+    console.log("关闭负压罐泄气阀门")
+    //关闭 负压罐进气阀门
+    ModbusJs.negativePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭负压罐进气阀门 微调")
+    tabView.currentIndex = currentIndex
+    var openCnt = 0
+    //    var min = -4
+    //    var max = -2
+    var min = -10
+    var max = 5
+
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+
+        //obj = ModbusJs.negativePressureSensorReadReq(sensorSerial)
+        obj =ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("负压传感器通讯错误")
+            return false
+        }
+        pressureDisplaySigFun(obj.pressureNumber)
+        // add  pressure table
+        var table={}
+        table.pressure=obj.pressureNumber
+        //开启压力模型赋值
+        openPressureModel.append(table)
+        spy.wait(900)
+        openCnt++
+        //console.log("openCnt:",openCnt)
+        processWindow.text("开启压力试验时间"+(openPressureTimeMax-openCnt)+"s")
+    }while(obj.pressureNumber >= min && openCnt < openPressureTimeMax)
+
+    //得到开启压力
+    if(obj.pressureNumber >=min &&  obj.pressureNumber <= max && openCnt ===openPressureTimeMax){
+        openPressureNumber = obj.pressureNumber.toString()
+        var result={}
+        result.openPressureNumber = openPressureNumber
+        result.sealPressureNumber = ""
+        resultSigFun(result)
+        console.log("开启压力:",openPressureNumber)
+    }
+    else{
+        if(obj.pressureNumber < min){
+            openPressureNumber=obj.pressureNumber+"<"+min
+        }
+        else if(obj.pressureNumber > max){
+            openPressureNumber=obj.pressureNumber+">"+max
+        }
+
+        result={}
+        result.openPressureNumber = openPressureNumber
+        result.sealPressureNumber = ""
+        resultSigFun(result)
+
+        //关闭负压罐进气阀门
+        ModbusJs.negativePressureTankInputCtrl(controlSerial,false)
+        console.log("关闭负压罐进气阀门 微调")
+        console.log("开启压力:",openPressureNumber)
+        console.log("开启压力测试结束")
+        return false
+    }
+    console.log("开启压力测试结束")
+
+    //setp 4
+    /*********测试密封压力*************/
+    console.log("密封压力开始")
+    processWindow.show("密封压力试验开始")
+    //关闭负压罐进气阀门
+    ModbusJs.negativePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭负压罐进气阀门 微调")
+    ModbusJs.negativePumpPowerCtrl(controlSerial,false)
+    console.log("关闭 负压泵")
+
+    var holdTimeCnt=0
+    tabView.currentIndex =currentIndex+3
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+        obj =ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        //obj = ModbusJs.negativePressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("负压传感器通讯错误")
+            return false
+        }
+        //密封压力模型赋值
+        table={}
+        table.pressure=obj.pressureNumber
+        sealPressureModel.append(table)
+        //压力实时显示
+        pressureDisplaySigFun(obj.pressureNumber)
+        spy.wait(900)
+        holdTimeCnt++
+        processWindow.text("密封压力试验时间"+(sealPressureTimemax-holdTimeCnt)+"s")
+    }while(holdTimeCnt < sealPressureTimemax )
+
+    sealPressureNumber = obj.pressureNumber.toString()
+    result={}
+    result.openPressureNumber = openPressureNumber
+    result.sealPressureNumber = sealPressureNumber
+    resultSigFun(result)
+    console.log("密封压力结束")
+
+
+    //setp 5
+    //关闭负压罐进气阀门
+    ModbusJs.negativePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭负压罐进气阀门 微调")
+    //打开负压罐头泄气阀门
+    ModbusJs.negativePressureTankOutputCtrl(controlSerial,true)
+    console.log("打开负压罐头泄气阀门")
+    ModbusJs.negativePumpPowerCtrl(controlSerial,false)
+    console.log("关闭 负压泵")
+    console.log("等待压力 0kPa")
+    //查看负压传感器值 等待负压罐到0kPa
+    processWindow.show("试验结束,泄气中")
+    timeout = 0
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return
+        }
+        obj =ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        //obj = ModbusJs.negativePressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("负压传感器通讯错误")
+            return false
+        }
+        // signal 压力显示函数
+        pressureDisplaySigFun(obj.pressureNumber)
+        //延时
+        spy.wait(900)
+        timeout++
+    }while(obj.pressureNumber < 0  && timeout<180)
+    //关闭负压罐头泄气阀门
+
+    //setp 6
+    console.log("压力 0kPa")
+    ModbusJs.closeAllValve(controlSerial)
+    console.log("关闭所有阀门")
+    return true
+
+}
+
+
+
+
+//倾覆性密封试验
+function capsizeTestStart(processWindow,controlSerial,sensorSerial,
+                          sealPressureModel,pressureDisplaySigFun,resultSigFun,spy,log)
+{
+    //setp 1
+    // 关闭所有测试口
+    ModbusJs.turnOffAllTestIO(controlSerial)
+    console.log("关闭所有测试口")
+    ModbusJs.pressureSensorCtrl(controlSerial,"高压")
+    console.log("打开高压传感器阀门")
+    //关闭正压罐进气阀门
+    ModbusJs.positivePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭正压罐进气阀门")
+    //setp 2
+    //查看高压传感器值 等待正压罐头压力降到最低值
+    processWindow.show("等待压力降到0")
+    //打开正压罐头泄气阀门
+    ModbusJs.positivePressureTankOutputCtrl(controlSerial,true)
+    console.log("打开正压罐头泄气阀门")
+    var timeout = 0
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+        var obj = ModbusJs.highPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("高压传感器通讯错误")
+            return false
+        }
+        // signal 压力显示函数
+        pressureDisplaySigFun(obj.pressureNumber)
+        //延时
+        spy.wait(900)
+        timeout++
+    }while(obj.pressureNumber > 0.1 && timeout < 180)
+    console.log("压力降压到 0 kPa")
+    if(timeout === 180){
+        log.show("泄压超时")
+        ModbusJs.closeAllValve(controlSerial)
+        console.log("关闭所有阀门")
+        return false
+    }
+
+    //setp 3
+    /*********调整压力*************/
+    processWindow.show("进气压力"+capsizeSetPressure+"kPa")
+    ModbusJs.pressureSensorCtrl(controlSerial,"低压")
+    console.log("打开低压传感器阀门")
+    obj = ModbusJs.testFixedPressure(controlSerial,capsizeSetPressure+2)
+    ModbusJs.proportionalControlWrite(controlSerial,obj.voltage)
+    console.log("比例调压阀压力值:",obj.voltage)
+    //关闭正压罐头泄气阀门
+    ModbusJs.positivePressureTankOutputCtrl(controlSerial,false)
+    console.log("关闭正压罐头泄气阀门")
+    //打开进气阀门
+    ModbusJs.positivePressureTankInputCtrl(controlSerial,true)
+    console.log("打开进气阀门")
+    var cnt = 0
+    var prevTime  = Date.now()
+    var bigAcive = true
+    var max = 50
+    ModbusJs.bigTuningValveControl(controlSerial,true)
+    console.log("开启 粗调开关")
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+        obj = ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("低压传感器通讯错误")
+            return false
+        }
+
+
+
+        spy.wait(10)
+        var curTime  = Date.now()
+        var deltaTime = curTime - prevTime
+        if(deltaTime > 900){
+            prevTime = curTime
+            pressureDisplaySigFun(obj.pressureNumber)
+            cnt++
+        }
+
+        //粗调压力值
+        var bigLevel = capsizeSetPressure-1
+        if(obj.pressureNumber > bigLevel && bigAcive === true){
+            bigAcive = false
+            ModbusJs.bigTuningValveControl(controlSerial,false)
+            ModbusJs.bigTuningValveControl(controlSerial,false)
+            console.log("关闭 粗调开关")
+            break;
+        }
+
+//        pressureDisplaySigFun(obj.pressureNumber)
+//        spy.wait(900)
+//        cnt++
+//        console.log("obj.pressureNumber:",obj.pressureNumber)
+    }while(obj.pressureNumber <= max && cnt < 180 )
+    if(cnt === 180){
+        log.show("进气时间超时")
+        return false
+    }
+
+    //setp 3
+    /*********密封试验开始*************/
+    processWindow.show("密封压力试验开始")
+    console.log("密封压力试验开始")
+    //关闭进气阀门
+    ModbusJs.positivePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭进气阀门")
+    //打开正压呼吸阀测试口阀门
+    ModbusJs.pbreathValveTestIo(controlSerial,true)
+    console.log("打开正压呼吸阀测试口阀门")
+
+    cnt = 0
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+        obj = ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("低压传感器通讯错误")
+            return false
+        }
+        pressureDisplaySigFun(obj.pressureNumber)
+        // add  pressure table
+        var table={}
+        table.pressure=obj.pressureNumber
+        //密封模型赋值
+        sealPressureModel.append(table)
+        spy.wait(900)
+        cnt++
+        processWindow.text("密封压力试验时间"+(sealPressureTimemax-cnt)+"s")
+    }while( cnt < sealPressureTimemax )
+    var result={}
+    result.sealPressureNumber = obj.pressureNumber
+    resultSigFun(result)
+
+    //setp 5
+    processWindow.show("试验结束,泄气中")
+    ModbusJs.pressureSensorCtrl(controlSerial,"低压")
+    console.log("打开低压传感器阀门")
+    //打开正压罐头泄气阀门
+    ModbusJs.positivePressureTankOutputCtrl(controlSerial,true)
+    console.log("打开正压罐头泄气阀门")
+    //关闭进气阀门
+    ModbusJs.positivePressureTankInputCtrl(controlSerial,false)
+    console.log("关闭进气阀门")
+    console.log("等待压力 0kPa")
+    //查看高压传感器值 等待正压罐头压力降到最低值
+    timeout =0
+    do{
+        if(running === false){
+            console.log("停止测试")
+            return false
+        }
+        obj = ModbusJs.lowPressureSensorReadReq(sensorSerial)
+        if(obj.ret === false){
+            log.show("低压传感器通讯错误")
+            return false
+        }
+        // signal 压力显示函数
+        pressureDisplaySigFun(obj.pressureNumber)
+        //延时
+        spy.wait(900)
+        timeout++
+    }while(obj.pressureNumber > 0.1  && timeout < 180)
+
+    //setp 6
+    console.log("压力 0kPa")
+    ModbusJs.closeAllValve(controlSerial)
+    console.log("关闭所有阀门")
+
+    return true
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+

BIN
font/DS-DIGI.TTF


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1076 - 0
generateword.cpp


+ 28 - 0
generateword.h

@@ -0,0 +1,28 @@
+#ifndef GENERATEWORD_H
+#define GENERATEWORD_H
+
+#include <QObject>
+#include <QVariant>
+#include "qword.h"
+
+class GenerateWord : public QObject
+{
+    Q_OBJECT
+public:
+    explicit GenerateWord(QObject *parent = nullptr);
+
+private:
+    void breatheValveRecordWrite(QWord &word,QString testType, QVariant &obj);
+signals:
+    void sendWordReportProgress(QString text);
+public slots:
+   // void receiveMsg(QString savePath,QString valve,QString manufacture,QString type,QString serialNumber,QString user,QString carplate,QList<QPointF> points);
+    void receiveMsg(QString savePath, QString valve, QString manufacture, QString type, QString serialNumber, QString user, QString carplate, QString state, QString setPressure, QList<QPointF> points0,
+                    QList<QPointF> points1, QList<QPointF> points2, QList<QPointF> points3, QList<QPointF> points4, QList<QPointF> points5);
+
+
+    void receiveGenerateWord(QString savePath, QVariant obj);
+    void receiveGenerateBreatheValveWord(QString savePath,QVariant para,QVariant obj1,QVariant obj2,QVariant obj3);
+};
+
+#endif // GENERATEWORD_H

BIN
img/blue_button.png


BIN
img/close.png


BIN
img/crystal_button.png


BIN
img/main_zjtj_bj.jpg


BIN
img/pink_button.png


BIN
img/reports-icon.png


BIN
img/shutdown_blue.png


BIN
img/shutdown_red.png


BIN
img/start1.png


BIN
img/stop1.png


BIN
img/tj_icon.png


BIN
img/zjtj_logo.png


+ 52 - 0
main.cpp

@@ -0,0 +1,52 @@
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+#include <QApplication>
+#include<QMessageBox>
+
+#include "TestService.h"
+#include "Standard.h"
+
+#include "DLog.h"
+
+QObject *standardmananger_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+    Q_UNUSED(engine)
+    Q_UNUSED(scriptEngine)
+    return StandardManager::instance();
+}
+
+
+int main(int argc, char *argv[])
+{
+    qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+#endif
+    QApplication app(argc, argv);
+
+    //qInstallMessageHandler(myMsgOutput);
+    DLog_Init();
+
+    //QMessageBox::critical(NULL, "critical", "Content", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+
+
+    qmlRegisterSingletonType<StandardManager>("TService", 1, 0, "StandardManager",standardmananger_provider);
+
+    qmlRegisterType<TestService>("TService",1,0,"TestService");
+
+    StandardManager::instance();
+
+    QQmlApplicationEngine engine;
+    //engine.rootContext()->setContextProperty("TService",new TestService);
+    const QUrl url(QStringLiteral("qrc:/main.qml"));
+    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
+                     &app, [url](QObject *obj, const QUrl &objUrl) {
+        if (!obj && url == objUrl)
+            QCoreApplication::exit(-1);
+    }, Qt::QueuedConnection);
+    engine.load(url);
+
+    return app.exec();
+}

+ 158 - 0
main.qml

@@ -0,0 +1,158 @@
+import QtQuick 2.15
+import QtQuick.Window 2.15
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+import QtQuick.Dialogs 1.3
+import QtQuick.Controls.Styles 1.4
+import QtQuick.VirtualKeyboard 2.15
+
+import TService 1.0
+
+Window {
+    id:main_window
+    width: 1280
+    height: 760
+    visible: true
+    title: qsTr("油气回收测试装备")
+
+    flags:Qt.FramelessWindowHint
+
+
+    Image {
+        id: bg
+        anchors.horizontalCenter: parent.horizontalCenter
+        fillMode: Image.PreserveAspectFit
+        source: "img/main_zjtj_bj.jpg"
+    }
+
+    Rectangle{
+        id: logo
+        x: 20
+        y: 20
+
+        width:300
+        height:100
+        color:"transparent"
+
+        Image {
+            anchors.fill:parent
+            fillMode: Image.PreserveAspectFit
+            source:"img/zjtj_logo.png"
+        }
+
+    }
+
+    Button {
+        text: "点击进入"
+        font.bold: true
+        font.pixelSize: 24
+        width:240
+        height:120
+        anchors.centerIn: parent
+
+        background: Image {
+            anchors.fill:parent
+            fillMode: Image.PreserveAspectFit
+            source:"img/blue_button.png"
+        }
+        //icon.source: "img/blue_button.png"
+        //icon.color: "transparent"
+
+
+        onClicked: myLoder.sourceComponent = mainpage // 切换显示主页面
+    }
+
+    Button {
+        //text: "点击进入"
+        width:80
+        height:80
+        anchors.right: parent.right
+        anchors.rightMargin: 40;
+        anchors.bottom: parent.bottom
+        anchors.bottomMargin: 40;
+        //color:"transparent"
+        background:Image {
+            anchors.fill:parent
+            fillMode: Image.PreserveAspectFit
+            source:"img/shutdown_red.png"
+        }
+
+        onClicked: {
+            Qt.quit()
+        }
+    }
+
+
+/*
+    Item {
+        id: cornerItem
+        x: 0
+        y: 0
+    }
+
+    property int activeFocusItemBottom : activeFocusItem == null ? 0 : Math.min(height, cornerItem.mapFromItem(activeFocusItem, 0, activeFocusItem.height).y + 50)
+
+*/
+
+    Loader{
+        id:myLoder
+        anchors.centerIn: parent
+    }
+
+    //Component.onCompleted: myLoder.sourceComponent = firstpage
+
+    Component{
+        id:firstpage
+        PageFirst{
+            width:300
+            height: 200
+            anchors.centerIn: parent
+        }
+    }
+
+    Component{
+        id:mainpage
+        PageMain{
+            width: 1280
+            height: 760
+            anchors.centerIn: parent
+        }
+    }
+
+
+    InputPanel {
+        id: inputPanel
+        z: 99
+        x: 0
+        y: main_window.height
+        width: main_window.width
+
+
+        states: State {
+            name: "visible"
+            when: inputPanel.active
+            PropertyChanges {
+                target: inputPanel
+                y: main_window.height - inputPanel.height
+            }
+        }
+        transitions: Transition {
+            from: ""
+            to: "visible"
+            reversible: true
+            ParallelAnimation {
+                NumberAnimation {
+                    properties: "y"
+                    duration: 250
+                    easing.type: Easing.InOutQuad
+                }
+            }
+        }
+    }
+
+
+
+}
+
+
+

+ 113 - 0
pid.cpp

@@ -0,0 +1,113 @@
+#ifndef _PID_SOURCE_
+#define _PID_SOURCE_
+
+#include <iostream>
+#include <cmath>
+#include <QDebug>
+#include "pid.h"
+
+using namespace std;
+
+class PIDImpl
+{
+    public:
+        PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki );
+        ~PIDImpl();
+        double calculate( double setpoint, double pv );
+
+    private:
+        double _dt;
+        double _max;
+        double _min;
+        double _Kp;
+        double _Kd;
+        double _Ki;
+        double _pre_error;
+        double _integral;
+};
+
+PID::PID( double dt, double max, double min, double Kp, double Kd, double Ki )
+{
+    pimpl = new PIDImpl(dt,max,min,Kp,Kd,Ki);
+}
+double PID::calculate( double setpoint, double pv )
+{
+    return pimpl->calculate(setpoint,pv);
+}
+PID::~PID()
+{
+    delete pimpl;
+}
+
+
+/**
+ * Implementation
+ */
+PIDImpl::PIDImpl( double dt, double max, double min, double Kp, double Kd, double Ki ) :
+    _dt(dt),
+    _max(max),
+    _min(min),
+    _Kp(Kp),
+    _Kd(Kd),
+    _Ki(Ki),
+    _pre_error(0),
+    _integral(0)
+{
+}
+
+double PIDImpl::calculate( double setpoint, double pv )
+{
+
+    // Calculate error
+    double error = setpoint - pv;
+
+    // Proportional term
+    double Pout = _Kp * error;
+
+    // Integral term
+    if(abs(error) > 3.0){
+        _integral = 0;
+    }else{
+        double _error = 0;
+        if(_integral > 30){
+            if(error >=0 )
+                _error = 0;
+            else
+                _error = error;
+        }else{
+            _error = error;
+        }
+
+        _error = error;
+
+        _integral += _error * _dt;
+    }
+
+    double Iout = _Ki * _integral;
+
+    // Derivative term
+    double derivative = (error - _pre_error) / _dt;
+    double Dout = _Kd * derivative;
+
+     //qDebug("calculate : pOut : %f, Iout: %f, Dout: %f ", Pout, Iout, Dout);
+    // Calculate total output
+    double output = Pout + Iout + Dout;
+
+    // Restrict to max/min
+    if( output > _max )
+        output = _max;
+    else if( output < _min )
+        output = _min;
+
+    // Save error to previous error
+    _pre_error = error;
+
+    return output;
+}
+
+PIDImpl::~PIDImpl()
+{
+}
+
+#endif
+

+ 25 - 0
pid.h

@@ -0,0 +1,25 @@
+#ifndef PID_H
+#define PID_H
+
+
+class PIDImpl;
+class PID
+{
+    public:
+        // Kp -  proportional gain
+        // Ki -  Integral gain
+        // Kd -  derivative gain
+        // dt -  loop interval time
+        // max - maximum value of manipulated variable
+        // min - minimum value of manipulated variable
+        PID( double dt, double max, double min, double Kp, double Kd, double Ki );
+
+        // Returns the manipulated variable given a setpoint and current process value
+        double calculate( double setpoint, double pv );
+        ~PID();
+
+    private:
+        PIDImpl *pimpl;
+};
+
+#endif // PID_H

+ 45 - 0
qml.qrc

@@ -0,0 +1,45 @@
+<RCC>
+    <qresource prefix="/">
+        <file>main.qml</file>
+        <file>UserButton.qml</file>
+        <file>InputLine.qml</file>
+        <file>UserComboBox.qml</file>
+        <file>RecoveryValve.qml</file>
+        <file>CurveDisplay.qml</file>
+        <file>Page1.qml</file>
+        <file>Page2.qml</file>
+        <file>PageDefault.qml</file>
+        <file>PageSetting.qml</file>
+        <file>RecordTable.qml</file>
+        <file>img/reports-icon.png</file>
+        <file>img/start1.png</file>
+        <file>img/stop1.png</file>
+        <file>StartStopButton.qml</file>
+        <file>ReportButton.qml</file>
+        <file>LCDNumber.qml</file>
+        <file>font/DS-DIGI.TTF</file>
+        <file>ResultDisplayText.qml</file>
+        <file>ResultTable.qml</file>
+        <file>DynamicGroupBox.qml</file>
+        <file>PageTest.qml</file>
+        <file>UserSwitch.qml</file>
+        <file>Log.qml</file>
+        <file>img/close.png</file>
+        <file>StateTable.qml</file>
+        <file>ReportPicture.qml</file>
+        <file>PageStandard.qml</file>
+        <file>UserTristate.qml</file>
+        <file>UserRadioButton.qml</file>
+        <file>UserTableView.qml</file>
+        <file>PageMain.qml</file>
+        <file>PageFirst.qml</file>
+        <file>img/main_zjtj_bj.jpg</file>
+        <file>img/zjtj_logo.png</file>
+        <file>img/blue_button.png</file>
+        <file>img/crystal_button.png</file>
+        <file>img/pink_button.png</file>
+        <file>img/shutdown_blue.png</file>
+        <file>img/shutdown_red.png</file>
+        <file>img/tj_icon.png</file>
+    </qresource>
+</RCC>

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1271 - 0
qword.cpp


+ 165 - 0
qword.h

@@ -0,0 +1,165 @@
+#ifndef QWORD_H
+#define QWORD_H
+
+#define _WIN32_DCOM
+
+#include <QMainWindow>
+#include <qmainwindow.h>
+#include <QString>
+#include <QVariant>
+#include <ActiveQt/QAxObject>
+#include <ActiveQt/QAxWidget>
+#include <objbase.h>
+//#include "GlobalAppData.h"
+
+//http://www.cxyzjd.com/article/chyuanrufeng/98778379
+
+class QWord : public QObject
+{
+    Q_OBJECT
+
+public:
+    QWord(QObject *parent = 0);
+    ~QWord();
+
+
+public:
+#define  ALIGNMENT_MIDDLE   0
+#define  ALIGNMENT_LEFT     1
+#define  ALIGNMENT_RIGHT    2
+#define  wdAutoFitFixed         0
+#define  wdAutoFitContent       1
+#define  wdAutoFitWindow        2
+#define  TABLE_BG_COLOR          0xffffffcc  //ABGR
+
+    enum TITLE_NUMBER
+    {
+        TITLE_ONE = 0,
+        TITLE_TWO,
+        TITLE_THREE,
+        NORMAL
+    };
+
+
+    //MOVEEND_INDEX来自于https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.office.interop.word.wdunits?view=word-pia
+    enum MOVEEND_INDEX
+    {
+        wdParagraph = 4, //段落。
+        wdStory = 6 , 	//部分。
+        wdRow = 10, //行
+        wdParagraphFormatting = 14, //段落格式。
+        wdTable = 15 //表格
+
+    };
+
+    //文本对齐方式
+    enum WdParagraphAlignment
+    {
+        AlignParLeft = 0, //左对齐
+        AlignParCenter = 1, //居中对齐。
+        AlignParRight = 2, //右对齐。
+        AlignParJustify = 3, //完全两端对齐。
+    };
+
+    QAxObject* getDocuments(){return m_documents;}
+    QAxObject* getDocument(){return m_document;}
+    QAxObject* getWordApp(){return m_word;}
+public:
+    /**************************************************************************/
+    /* 文件   操作                                                            */
+    /**************************************************************************/
+    void save();				//保存操作内容
+    void close();				//关闭 退出 析构时候也会自动调用一次
+    void saveAs();				//新建word另存为
+    bool createWord(QString reportname );		//创建一个新的word文档
+    void openWord();			//打开一个现有的word文档
+    bool createNewWord(const QString& filePath );		//创建一个新的word文档
+
+    void setTableAutoFitBehavior(int flag);//表格自动拉伸列: 0 固定  1根据内容调整  2 根据窗口调整
+    void setPageOrientation(int flag);	//设置页面0为纵向wdOrientPortrait  1为横向wdOrientLandscape
+    void setWordPageView(int flag);	//设置页面视图,是web视图wdWebView 6还是页面视图wdPrintView 3 或者阅读视图wdReadingView 7
+    void setFontSize(int fontsize);						//设置字体大小
+    void setFontName(QString& fontName);				//设置字体	比如 “宋体”
+    void setFontBold(bool flag);						//字体加粗
+    void setParagraphAlignment(int flag);				//设置选中位置文字居左 0 ,居中 1 ,居右 2
+    void setRowAlignment(int tableIndex,int row,int flag);
+    void setRowAlignment(int row,int flag);
+    //同时设置列宽和列高可以固定图片的大小
+    void setColumnWidth(int column, int width);			//设置列宽
+    void setColumnHeight(int column, int height);		//设置列高
+    void setRowHeight(int nTable,int Row, int height);
+    void setCellString(int row, int column, const QString& text);
+    void setCellFontBold(int row, int column, bool isBold);			//设置内容粗体  isBold控制是否粗体
+    void setCellFontSize(int row, int column, int size);			//设置文字大小
+    void setOptionCheckSpell(bool flags);		//设置审阅的拼写检查  true开启检查  false 取消检查
+
+    QString GetText();												//获取内容
+    void getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn);
+    void setSelectionRange(int start,int end);	//"SetRange(1, 9)"第1个字符后开始,到第9个字符结束范围
+    QVariant getCellValue(int row, int column);						//获取单元格内容
+    int getTableCount();											//获取word中表格总数
+
+
+    QString getStrErrorInfo(){return m_strError;}					//获取代码中出现的错误信息可以用QMessageBox::information打印 在cpp不用QMessageBox 是怕你们在线程中调导出报表
+    void deleteSelectColumn(int column);							//删除指定的列
+    void moveForEnd();												//移动选定对象到文档末尾
+    void insertCellPic(int row,int column,const QString& picPath);	//单元格插入图片
+    void intsertTable(int row,int column);							//插入一个几行几列表格
+    void insertMoveDown();											//插入回车
+    void insertText(const QString& text);							//插入文字
+    void insertTable(int tableIndex,int row,int column);
+    //插入巡检单位  巡检计划 巡检时间 巡 检 人  顺序传参
+    //void insertTitle(const QString& str1,const QString& str2,const QString& str3,const QString& str4);
+    void MergeCells(int tableIndex, int nStartRow,int nStartCol,int nEndRow,int nEndCol);//合并单元格
+    bool open(const QString& strFilePath,bool bVisable);
+    bool openword(bool bVisable);
+    bool isOpen();
+
+
+    void setColumnWidth(int nTable,int column,int width);
+    void setCellString(int nTable,int row,int column,const QString& text);
+    void insertCellPic(int nTable,int row,int column,const QString& picPath);
+    void setCellFontBold(int nTable,int row,int column,bool isBold);
+    void setCellFontSize(int nTable,int row,int column,int size);
+    //void addTableRow(int nTable ,int nRow,int rowCount);
+    void addTableRow(int tableIndex ,int nRow,int rowCount);
+    void setColumnHeight(int nTable,int column, int height);
+    void intsertTable(int tableIndex, int row,int column);
+
+    void AddPicture(QString file);
+    void insertEnter(void);
+    QAxObject* createTable(int row, int column);
+    QAxObject* createTableWithColor(int row, int column);
+    void setCellText(QAxObject *table, int row, int column, QString text,bool bold);
+    void autoFitBehavior(QAxObject *table, int flag);
+    void insertNewPage(void);
+    void setColor( QAxObject *obj,QColor color );
+    void setBgColor( QAxObject *obj,QColor color );
+    int colorToInt( QColor color );
+    void addTableRow(QAxObject *table, int nRow, int rowCount);
+    void appendTableRow( QAxObject *table,int rowCount );
+    void setColumnWidth(QAxObject *table, int column, int width);
+    void MergeCells(QAxObject *table, int nStartRow,int nStartCol,int nEndRow,int nEndCol);
+    QString getTitleStr( TITLE_NUMBER number );
+    bool addText1( QString titlestr,TITLE_NUMBER number /*= NORMAL*/,WdParagraphAlignment alignment /*= AlignParLeft*/ );
+    bool addText( QString titlestr,QFont font,QColor fontcolor );
+    QAxObject* addText2( QString titlestr );
+    void setTableBgColor( QAxObject *table,uint32_t color );
+    void setParagraphFormatOutlineLevel(QString level);
+
+public:
+    void setVisible(bool isVisible);
+
+private:
+    QAxObject* m_word;
+    QAxObject* m_documents;
+    QAxObject* m_document;
+    QString  m_fileName;
+    QString  m_saveName;
+    QString  m_strError;
+    QString  m_strFilePath;
+    bool m_bOpened;
+
+};
+
+#endif // QWORD_H

+ 799 - 0
report.cpp

@@ -0,0 +1,799 @@
+#include "report.h"
+#include <QDebug>
+#include <QAxObject>
+#include <QAxWidget>
+#include <QTextCodec>
+#include <QThread>
+#include <QFile>
+#include <QDir>
+
+QString g_bookmark_volume[MAX_COMPARTMENT_NUM] = {BOOKMARK_VOLUME_1,BOOKMARK_VOLUME_2,BOOKMARK_VOLUME_3, BOOKMARK_VOLUME_4};
+
+QString g_bookmark_systest_startpressure[MAX_COMPARTMENT_NUM] = {BOOKMARK_SYSTEST_STARTPRESSURE_1,BOOKMARK_SYSTEST_STARTPRESSURE_2,BOOKMARK_SYSTEST_STARTPRESSURE_3, BOOKMARK_SYSTEST_STARTPRESSURE_4};
+QString g_bookmark_systest_endpressure[MAX_COMPARTMENT_NUM] = {BOOKMARK_SYSTEST_ENDPRESSURE_1,BOOKMARK_SYSTEST_ENDPRESSURE_2,BOOKMARK_SYSTEST_ENDPRESSURE_3, BOOKMARK_SYSTEST_ENDPRESSURE_4};
+QString g_bookmark_systest_deltapressure[MAX_COMPARTMENT_NUM] = {BOOKMARK_SYSTEST_DELTAPRESSURE_1,BOOKMARK_SYSTEST_DELTAPRESSURE_2,BOOKMARK_SYSTEST_DELTAPRESSURE_3, BOOKMARK_SYSTEST_DELTAPRESSURE_4};
+QString g_bookmark_systest_threshold[MAX_COMPARTMENT_NUM] = {BOOKMARK_SYSTEST_THRESHOLD_1,BOOKMARK_SYSTEST_THRESHOLD_2,BOOKMARK_SYSTEST_THRESHOLD_3, BOOKMARK_SYSTEST_THRESHOLD_4};
+
+QString g_bookmark_valvetest_startpressure[MAX_COMPARTMENT_NUM] = {BOOKMARK_VALVETEST_STARTPRESSURE_1,BOOKMARK_VALVETEST_STARTPRESSURE_2,BOOKMARK_VALVETEST_STARTPRESSURE_3, BOOKMARK_VALVETEST_STARTPRESSURE_4};
+QString g_bookmark_valvetest_endpressure[MAX_COMPARTMENT_NUM] = {BOOKMARK_VALVETEST_ENDPRESSURE_1,BOOKMARK_VALVETEST_ENDPRESSURE_2,BOOKMARK_VALVETEST_ENDPRESSURE_3, BOOKMARK_VALVETEST_ENDPRESSURE_4};
+QString g_bookmark_valvetest_deltapressure[MAX_COMPARTMENT_NUM] = {BOOKMARK_VALVETEST_DELTAPRESSURE_1,BOOKMARK_VALVETEST_DELTAPRESSURE_2,BOOKMARK_VALVETEST_DELTAPRESSURE_3, BOOKMARK_VALVETEST_DELTAPRESSURE_4};
+QString g_bookmark_valvetest_threshold[MAX_COMPARTMENT_NUM] = {BOOKMARK_VALVETEST_THRESHOLD_1,BOOKMARK_VALVETEST_THRESHOLD_2,BOOKMARK_VALVETEST_THRESHOLD_3, BOOKMARK_VALVETEST_THRESHOLD_4};
+
+QString g_bookmark_test_picture[MAX_COMPARTMENT_NUM] = {BOOKMARK_TEST_PICTURE_1,BOOKMARK_TEST_PICTURE_2,BOOKMARK_TEST_PICTURE_3, BOOKMARK_TEST_PICTURE_4};
+QString g_bookmark_systest_picture[MAX_COMPARTMENT_NUM] = {BOOKMARK_SYSTEST_PICTURE_1,BOOKMARK_SYSTEST_PICTURE_2,BOOKMARK_SYSTEST_PICTURE_3, BOOKMARK_SYSTEST_PICTURE_4};
+QString g_bookmark_valvetest_picture[MAX_COMPARTMENT_NUM] = {BOOKMARK_VALVETEST_PICTURE_1,BOOKMARK_VALVETEST_PICTURE_2,BOOKMARK_VALVETEST_PICTURE_3, BOOKMARK_VALVETEST_PICTURE_4};
+
+
+
+#define REPORT_TEMPLATES_PATH  "D:/VaporRecoverySystemTest/Templates/"
+#define REPORT_TEMPLATES_NAME  "report.dotx"
+
+Report::Report()
+{
+
+}
+
+Report::~Report()
+{
+
+}
+
+bool Report::make_Word(Tanker& tanker, QString word_path, QString pic_dir)
+{
+
+    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
+
+    QString text_progress1 = codec->toUnicode("正在生成Word报告,请耐心等待");
+    QString text_progress2 = codec->toUnicode("正在保存中...");
+    QString text_progress3 = codec->toUnicode("报告已完成");
+    QString text_progress4 = codec->toUnicode("打开word失败");
+
+    //新建一个word应用程序
+    QAxWidget *word = new QAxWidget("Word.Application",0,Qt::MSWindowsOwnDC);
+    //并设置为不可见
+    word->setProperty("Visible",false);
+    //获取所有的工作文档
+    QAxObject *documents = word->querySubObject("Documents");
+    //以test2.dot为模板新建一个文档
+    documents->dynamicCall("Add(QString)",QString(REPORT_TEMPLATES_PATH)+QString(REPORT_TEMPLATES_NAME));
+    //documents->dynamicCall("Add(QString)",QString::fromLocal8Bit("D:\Code\QTapps\build-valve_testing-Desktop_Qt_5_15_2_MinGW_32_bit-Debug\debug\test1.dotx"));
+    //获取当前激活的文档
+    QAxObject *document = word->querySubObject("ActiveDocument");
+
+    emit onProgress(text_progress1);
+
+    //填写全局信息
+    //使用单位
+    QAxObject *bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_COMPANYNAME);
+    if(!bookmark->isNull())
+    {
+        //QChar cc = 0x2611;
+        QString str = tanker.companyname_str;
+        //str.insert(0, cc);
+        QString sText=codec->toUnicode(str.toStdString().c_str());                          //此处为替换内容
+        qDebug()<<sText;
+        bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+        bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+    }
+
+    //车牌
+    bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_CARPLATE);
+    if(!bookmark->isNull())
+    {
+        QString sText=codec->toUnicode(tanker.licenseplate_str.toStdString().c_str());                          //此处为替换内容
+        qDebug()<<sText;
+        bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+        bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+    }
+
+    //仓数
+    bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_COMPARTMENT_NUM);
+    if(!bookmark->isNull())
+    {
+        QString sText=codec->toUnicode(QString::number(tanker.compartment_num).toStdString().c_str());                          //此处为替换内容
+        qDebug()<<sText;
+        bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+        bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+    }
+
+    //填写每仓容量
+   for(int i=0; i< tanker.compartment_num; i++){
+
+       Compartment& comp = tanker.get_compartment(i);
+       bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_volume[i]);
+       if(!bookmark->isNull())
+       {
+           //int volume = m_tank.m_comparts[i].m_volume;
+           QString sText=codec->toUnicode(QString::number(comp.m_volume).toStdString().c_str());                          //此处为替换内容
+           qDebug()<<sText;
+           bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+           bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+       }
+
+       if(comp.m_result.sys_test_ok){  //完成了系统密闭性检测
+
+           //密闭性检测的初始表压
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_startpressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.sysstart_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //5 min之后的表压
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_endpressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.sysend_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //压力变化值
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_deltapressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.delta_sys_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //压力变化限值
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_threshold[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_standarditem.system_threshold, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+       }
+
+       if(comp.m_result.valve_test_ok){  //完成了阀门密闭性检测
+
+           //密闭性检测的初始表压
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_startpressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.valvestart_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //5 min之后的表压
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_endpressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.valveend_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //压力变化值
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_deltapressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.delta_valve_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //压力变化限值
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_threshold[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_standarditem.valve_threshold, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+       }
+
+
+       if(comp.m_bpicReady){
+
+           // 获取文档中名字为pic的标签
+           QAxObject*bookmark_pic=document->querySubObject("Bookmarks(QVariant)",g_bookmark_test_picture[i]);
+            // 选中标签,将图片插入到标签位置
+           if(!bookmark_pic->isNull())
+           {
+               QString pic_path_str = pic_dir+tanker.licenseplate_str+"_"+QString::number(i+1)+"_all.jpg";
+               qDebug()<<pic_path_str;
+
+               QFile file(pic_path_str);
+
+               if(file.exists()){
+
+                   bookmark_pic->dynamicCall("Select(void)");
+                   QAxObject *range;
+                   range = bookmark_pic->querySubObject("Range");
+                   QVariant tmp = range->asVariant();
+
+                   QList<QVariant>qList;
+                   qList<<QVariant(pic_path_str);
+                   qList<<QVariant(false);
+                   qList<<QVariant(true);
+                   qList<<tmp;
+
+                   QAxObject *Inlineshapes = document->querySubObject("InlineShapes");
+                   Inlineshapes->dynamicCall("AddPicture(const QString&, QVariant, QVariant ,QVariant)",qList);
+               }
+
+
+           }
+
+           bookmark_pic=document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_picture[i]);
+            // 选中标签,将图片插入到标签位置
+           if(!bookmark_pic->isNull())
+           {
+               QString pic_path_str = pic_dir+tanker.licenseplate_str+"_"+QString::number(i+1)+"_sys.jpg";
+               qDebug()<<pic_path_str;
+
+               QFile file(pic_path_str);
+               if(file.exists()){
+                   bookmark_pic->dynamicCall("Select(void)");
+                   QAxObject *range;
+                   range = bookmark_pic->querySubObject("Range");
+                   QVariant tmp = range->asVariant();
+
+                   QList<QVariant>qList;
+                   qList<<QVariant(pic_path_str);
+                   qList<<QVariant(false);
+                   qList<<QVariant(true);
+                   qList<<tmp;
+
+                   QAxObject *Inlineshapes = document->querySubObject("InlineShapes");
+                   Inlineshapes->dynamicCall("AddPicture(const QString&, QVariant, QVariant ,QVariant)",qList);
+               }
+
+           }
+
+           bookmark_pic=document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_picture[i]);
+            // 选中标签,将图片插入到标签位置
+           if(!bookmark_pic->isNull())
+           {
+               QString pic_path_str = pic_dir+tanker.licenseplate_str+"_"+QString::number(i+1)+"_valve.jpg";
+               qDebug()<<pic_path_str;
+
+               QFile file(pic_path_str);
+               if(file.exists()){
+
+                   bookmark_pic->dynamicCall("Select(void)");
+                   QAxObject *range;
+                   range = bookmark_pic->querySubObject("Range");
+                   QVariant tmp = range->asVariant();
+
+                   QList<QVariant>qList;
+                   qList<<QVariant(pic_path_str);
+                   qList<<QVariant(false);
+                   qList<<QVariant(true);
+                   qList<<tmp;
+
+                   QAxObject *Inlineshapes = document->querySubObject("InlineShapes");
+                   Inlineshapes->dynamicCall("AddPicture(const QString&, QVariant, QVariant ,QVariant)",qList);
+               }
+
+           }
+
+       }
+   }
+
+
+   //检测结果
+   bool systest_pass = true;
+   bool valvetest_pass = true;
+   int  nosys_testcount = 0;
+   int  novalve_testcount =0;
+   for(int i=0; i<tanker.compartment_num; i++){
+
+       Compartment& comp = tanker.get_compartment(i);
+       if(comp.m_result.sys_test_ok){
+           if(!comp.m_result.pass_sys_pressure){
+               systest_pass = false;
+           }
+       }else{
+           nosys_testcount++;
+       }
+
+       if(comp.m_result.valve_test_ok){
+           if(!comp.m_result.pass_valve_pressure){
+               valvetest_pass = false;
+           }
+       }else{
+           novalve_testcount++;
+       }
+   }
+
+   if(nosys_testcount != tanker.compartment_num){
+       //系统检测结果
+       bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_SYSTEST_RESULT);
+       if(!bookmark->isNull())
+       {
+           QString sText;
+           if(systest_pass){
+               sText=codec->toUnicode("合格");
+           }else{
+               sText=codec->toUnicode("超标");
+           }
+           qDebug()<<sText;
+           bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+           bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+       }
+   }
+
+
+   if(novalve_testcount != tanker.compartment_num){
+       //阀门检测结果
+       bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_VALVETEST_RESULT);
+       if(!bookmark->isNull())
+       {
+           QString sText;
+           if(valvetest_pass){
+               sText=codec->toUnicode("合格");
+           }else{
+               sText=codec->toUnicode("超标");
+           }
+
+           bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+           bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+       }
+   }
+
+
+   //检测日期
+   QDate date(QDate::currentDate());
+
+   bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_DATE_YEAR);
+   if(!bookmark->isNull())
+   {
+       QString sText=codec->toUnicode(QString::number(date.year()).toStdString().c_str());                          //此处为替换内容
+       qDebug()<<sText;
+       bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+       bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+   }
+
+   bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_DATE_MONTH);
+   if(!bookmark->isNull())
+   {
+       QString sText=codec->toUnicode(QString::number(date.month()).toStdString().c_str());                          //此处为替换内容
+       qDebug()<<sText;
+       bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+       bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+   }
+
+   bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_DATE_DAY);
+   if(!bookmark->isNull())
+   {
+       QString sText=codec->toUnicode(QString::number(date.day()).toStdString().c_str());                          //此处为替换内容
+       qDebug()<<sText;
+       bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+       bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+   }
+
+   //将文件保存为PDF,
+   qDebug()<<"start save Word file ";
+   emit onProgress(text_progress2);
+
+   document->dynamicCall("SaveAs(const QString&))",QDir::toNativeSeparators(word_path));
+
+   document->dynamicCall("Close (boolean)",false);
+   word->dynamicCall("Quit()");
+
+   emit onProgress(text_progress3);
+   QThread::msleep(300);
+   emit onProgress("close");
+
+   return true;
+
+
+}
+
+bool Report::make_PDF(Tanker& tanker, QString word_path, QString pic_dir)
+{
+    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
+
+    QString text_progress1 = codec->toUnicode("正在生成PDF报告,请耐心等待");
+    QString text_progress2 = codec->toUnicode("正在保存中...");
+    QString text_progress3 = codec->toUnicode("报告已完成");
+    QString text_progress4 = codec->toUnicode("打开word失败");
+
+    //新建一个word应用程序
+    QAxWidget *word = new QAxWidget("Word.Application",0,Qt::MSWindowsOwnDC);
+    //并设置为不可见
+    word->setProperty("Visible",false);
+    //获取所有的工作文档
+    QAxObject *documents = word->querySubObject("Documents");
+    //以test2.dot为模板新建一个文档
+    documents->dynamicCall("Add(QString)",QString(REPORT_TEMPLATES_PATH)+QString(REPORT_TEMPLATES_NAME));
+    //documents->dynamicCall("Add(QString)",QString::fromLocal8Bit("D:\Code\QTapps\build-valve_testing-Desktop_Qt_5_15_2_MinGW_32_bit-Debug\debug\test1.dotx"));
+    //获取当前激活的文档
+    QAxObject *document = word->querySubObject("ActiveDocument");
+
+    emit onProgress(text_progress1);
+
+    //填写全局信息
+    //使用单位
+    QAxObject *bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_COMPANYNAME);
+    if(!bookmark->isNull())
+    {
+        //QChar cc = 0x2611;
+        QString str = tanker.companyname_str;
+        //str.insert(0, cc);
+        QString sText=codec->toUnicode(str.toStdString().c_str());                          //此处为替换内容
+        qDebug()<<sText;
+        bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+        bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+    }
+
+    //车牌
+    bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_CARPLATE);
+    if(!bookmark->isNull())
+    {
+        QString sText=codec->toUnicode(tanker.licenseplate_str.toStdString().c_str());                          //此处为替换内容
+        qDebug()<<sText;
+        bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+        bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+    }
+
+    //仓数
+    bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_COMPARTMENT_NUM);
+    if(!bookmark->isNull())
+    {
+        QString sText=codec->toUnicode(QString::number(tanker.compartment_num).toStdString().c_str());                          //此处为替换内容
+        qDebug()<<sText;
+        bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+        bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+    }
+
+    //填写每仓容量
+   for(int i=0; i< tanker.compartment_num; i++){
+
+       Compartment& comp = tanker.get_compartment(i);
+       bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_volume[i]);
+       if(!bookmark->isNull())
+       {
+           //int volume = m_tank.m_comparts[i].m_volume;
+           QString sText=codec->toUnicode(QString::number(comp.m_volume).toStdString().c_str());                          //此处为替换内容
+           qDebug()<<sText;
+           bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+           bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+       }
+
+       if(comp.m_result.sys_test_ok){  //完成了系统密闭性检测
+
+           //密闭性检测的初始表压
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_startpressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.sysstart_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //5 min之后的表压
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_endpressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.sysend_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //压力变化值
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_deltapressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.delta_sys_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //压力变化限值
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_threshold[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_standarditem.system_threshold, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+       }
+
+       if(comp.m_result.valve_test_ok){  //完成了阀门密闭性检测
+
+           //密闭性检测的初始表压
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_startpressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.valvestart_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //5 min之后的表压
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_endpressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.valveend_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //压力变化值
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_deltapressure[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_result.delta_valve_pressure, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+           //压力变化限值
+           bookmark = document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_threshold[i]);
+           if(!bookmark->isNull())
+           {
+               //int volume = m_tank.m_comparts[i].m_volume;
+               QString pressure_str = QString("%1").arg(comp.m_standarditem.valve_threshold, 4,'f',2,QLatin1Char('0'));
+               QString sText=codec->toUnicode(pressure_str.toStdString().c_str());                          //此处为替换内容
+               qDebug()<<sText;
+               bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+               bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+           }
+
+       }
+
+
+       if(comp.m_bpicReady){
+
+           // 获取文档中名字为pic的标签
+           QAxObject*bookmark_pic=document->querySubObject("Bookmarks(QVariant)",g_bookmark_test_picture[i]);
+            // 选中标签,将图片插入到标签位置
+           if(!bookmark_pic->isNull())
+           {
+               QString pic_path_str = pic_dir+tanker.licenseplate_str+"_"+QString::number(i+1)+"_all.jpg";
+               qDebug()<<pic_path_str;
+
+               QFile file(pic_path_str);
+
+               if(file.exists()){
+
+                   bookmark_pic->dynamicCall("Select(void)");
+                   QAxObject *range;
+                   range = bookmark_pic->querySubObject("Range");
+                   QVariant tmp = range->asVariant();
+
+                   QList<QVariant>qList;
+                   qList<<QVariant(pic_path_str);
+                   qList<<QVariant(false);
+                   qList<<QVariant(true);
+                   qList<<tmp;
+
+                   QAxObject *Inlineshapes = document->querySubObject("InlineShapes");
+                   Inlineshapes->dynamicCall("AddPicture(const QString&, QVariant, QVariant ,QVariant)",qList);
+               }
+
+
+           }
+
+           bookmark_pic=document->querySubObject("Bookmarks(QVariant)",g_bookmark_systest_picture[i]);
+            // 选中标签,将图片插入到标签位置
+           if(!bookmark_pic->isNull())
+           {
+               QString pic_path_str = pic_dir+tanker.licenseplate_str+"_"+QString::number(i+1)+"_sys.jpg";
+               qDebug()<<pic_path_str;
+
+               QFile file(pic_path_str);
+               if(file.exists()){
+                   bookmark_pic->dynamicCall("Select(void)");
+                   QAxObject *range;
+                   range = bookmark_pic->querySubObject("Range");
+                   QVariant tmp = range->asVariant();
+
+                   QList<QVariant>qList;
+                   qList<<QVariant(pic_path_str);
+                   qList<<QVariant(false);
+                   qList<<QVariant(true);
+                   qList<<tmp;
+
+                   QAxObject *Inlineshapes = document->querySubObject("InlineShapes");
+                   Inlineshapes->dynamicCall("AddPicture(const QString&, QVariant, QVariant ,QVariant)",qList);
+               }
+
+           }
+
+           bookmark_pic=document->querySubObject("Bookmarks(QVariant)",g_bookmark_valvetest_picture[i]);
+            // 选中标签,将图片插入到标签位置
+           if(!bookmark_pic->isNull())
+           {
+               QString pic_path_str = pic_dir+tanker.licenseplate_str+"_"+QString::number(i+1)+"_valve.jpg";
+               qDebug()<<pic_path_str;
+
+               QFile file(pic_path_str);
+               if(file.exists()){
+
+                   bookmark_pic->dynamicCall("Select(void)");
+                   QAxObject *range;
+                   range = bookmark_pic->querySubObject("Range");
+                   QVariant tmp = range->asVariant();
+
+                   QList<QVariant>qList;
+                   qList<<QVariant(pic_path_str);
+                   qList<<QVariant(false);
+                   qList<<QVariant(true);
+                   qList<<tmp;
+
+                   QAxObject *Inlineshapes = document->querySubObject("InlineShapes");
+                   Inlineshapes->dynamicCall("AddPicture(const QString&, QVariant, QVariant ,QVariant)",qList);
+               }
+
+           }
+
+       }
+   }
+
+
+   //检测结果
+   bool systest_pass = true;
+   bool valvetest_pass = true;
+   int  nosys_testcount = 0;
+   int  novalve_testcount =0;
+   for(int i=0; i<tanker.compartment_num; i++){
+
+       Compartment& comp = tanker.get_compartment(i);
+       if(comp.m_result.sys_test_ok){
+           if(!comp.m_result.pass_sys_pressure){
+               systest_pass = false;
+           }
+       }else{
+           nosys_testcount++;
+       }
+
+       if(comp.m_result.valve_test_ok){
+           if(!comp.m_result.pass_valve_pressure){
+               valvetest_pass = false;
+           }
+       }else{
+           novalve_testcount++;
+       }
+   }
+
+   if(nosys_testcount != tanker.compartment_num){
+       //系统检测结果
+       bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_SYSTEST_RESULT);
+       if(!bookmark->isNull())
+       {
+           QString sText;
+           if(systest_pass){
+               sText=codec->toUnicode("合格");
+           }else{
+               sText=codec->toUnicode("超标");
+           }
+           qDebug()<<sText;
+           bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+           bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+       }
+   }
+
+
+   if(novalve_testcount != tanker.compartment_num){
+       //阀门检测结果
+       bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_VALVETEST_RESULT);
+       if(!bookmark->isNull())
+       {
+           QString sText;
+           if(valvetest_pass){
+               sText=codec->toUnicode("合格");
+           }else{
+               sText=codec->toUnicode("超标");
+           }
+
+           bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+           bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+       }
+   }
+
+
+   //检测日期
+   QDate date(QDate::currentDate());
+
+   bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_DATE_YEAR);
+   if(!bookmark->isNull())
+   {
+       QString sText=codec->toUnicode(QString::number(date.year()).toStdString().c_str());                          //此处为替换内容
+       qDebug()<<sText;
+       bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+       bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+   }
+
+   bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_DATE_MONTH);
+   if(!bookmark->isNull())
+   {
+       QString sText=codec->toUnicode(QString::number(date.month()).toStdString().c_str());                          //此处为替换内容
+       qDebug()<<sText;
+       bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+       bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+   }
+
+   bookmark = document->querySubObject("Bookmarks(QVariant)",BOOKMARK_DATE_DAY);
+   if(!bookmark->isNull())
+   {
+       QString sText=codec->toUnicode(QString::number(date.day()).toStdString().c_str());                          //此处为替换内容
+       qDebug()<<sText;
+       bookmark->dynamicCall("Select(void)");                             //选中要选中的区域
+       bookmark->querySubObject("Range")->setProperty("Text",sText);      //进行替换操作
+   }
+
+   //将文件保存为PDF,
+   qDebug()<<"start save PDF file ";
+   emit onProgress(text_progress2);
+
+   //document->dynamicCall("SaveAs(const QString&))",QDir::toNativeSeparators(word_path));
+
+   QVariant OutputFileName(word_path);
+   QVariant ExportFormat(17);      //17是pdf
+   QVariant OpenAfterExport(false); //保存后是否自动打开
+
+
+   document->querySubObject("ExportAsFixedFormat(const QVariant&,const QVariant&,const QVariant&)",
+                            OutputFileName,
+                            ExportFormat,
+                            OpenAfterExport);
+
+   document->dynamicCall("Close (boolean)",false);
+   word->dynamicCall("Quit()");
+
+   emit onProgress(text_progress3);
+   QThread::msleep(300);
+   emit onProgress("close");
+
+   return true;
+
+
+}
+

+ 98 - 0
report.h

@@ -0,0 +1,98 @@
+#ifndef REPORT_H
+#define REPORT_H
+
+#include "tank.h"
+
+
+#define BOOKMARK_COMPANYNAME        "bm_companyname"
+#define BOOKMARK_CARPLATE           "bm_carplate"
+#define BOOKMARK_COMPARTMENT_NUM    "bm_compartment_num"
+
+#define BOOKMARK_VOLUME_1    "bm_volume_1"
+#define BOOKMARK_VOLUME_2    "bm_volume_2"
+#define BOOKMARK_VOLUME_3    "bm_volume_3"
+#define BOOKMARK_VOLUME_4    "bm_volume_4"
+
+#define BOOKMARK_SYSTEST_STARTPRESSURE_1    "bm_sysPS_1"
+#define BOOKMARK_SYSTEST_STARTPRESSURE_2    "bm_sysPS_2"
+#define BOOKMARK_SYSTEST_STARTPRESSURE_3    "bm_sysPS_3"
+#define BOOKMARK_SYSTEST_STARTPRESSURE_4    "bm_sysPS_4"
+
+#define BOOKMARK_SYSTEST_ENDPRESSURE_1    "bm_sysPE_1"
+#define BOOKMARK_SYSTEST_ENDPRESSURE_2    "bm_sysPE_2"
+#define BOOKMARK_SYSTEST_ENDPRESSURE_3    "bm_sysPE_3"
+#define BOOKMARK_SYSTEST_ENDPRESSURE_4    "bm_sysPE_4"
+
+#define BOOKMARK_SYSTEST_DELTAPRESSURE_1    "bm_sysPD_1"
+#define BOOKMARK_SYSTEST_DELTAPRESSURE_2    "bm_sysPD_2"
+#define BOOKMARK_SYSTEST_DELTAPRESSURE_3    "bm_sysPD_3"
+#define BOOKMARK_SYSTEST_DELTAPRESSURE_4    "bm_sysPD_4"
+
+#define BOOKMARK_SYSTEST_THRESHOLD_1    "bm_sysPT_1"
+#define BOOKMARK_SYSTEST_THRESHOLD_2    "bm_sysPT_2"
+#define BOOKMARK_SYSTEST_THRESHOLD_3    "bm_sysPT_3"
+#define BOOKMARK_SYSTEST_THRESHOLD_4    "bm_sysPT_4"
+
+#define BOOKMARK_SYSTEST_RESULT  "bm_sys_result"
+
+
+#define BOOKMARK_VALVETEST_STARTPRESSURE_1    "bm_valvePS_1"
+#define BOOKMARK_VALVETEST_STARTPRESSURE_2    "bm_valvePS_2"
+#define BOOKMARK_VALVETEST_STARTPRESSURE_3    "bm_valvePS_3"
+#define BOOKMARK_VALVETEST_STARTPRESSURE_4    "bm_valvePS_4"
+
+#define BOOKMARK_VALVETEST_ENDPRESSURE_1    "bm_valvePE_1"
+#define BOOKMARK_VALVETEST_ENDPRESSURE_2    "bm_valvePE_2"
+#define BOOKMARK_VALVETEST_ENDPRESSURE_3    "bm_valvePE_3"
+#define BOOKMARK_VALVETEST_ENDPRESSURE_4    "bm_valvePE_4"
+
+#define BOOKMARK_VALVETEST_DELTAPRESSURE_1    "bm_valvePD_1"
+#define BOOKMARK_VALVETEST_DELTAPRESSURE_2    "bm_valvePD_2"
+#define BOOKMARK_VALVETEST_DELTAPRESSURE_3    "bm_valvePD_3"
+#define BOOKMARK_VALVETEST_DELTAPRESSURE_4    "bm_valvePD_4"
+
+#define BOOKMARK_VALVETEST_THRESHOLD_1    "bm_valvePT_1"
+#define BOOKMARK_VALVETEST_THRESHOLD_2    "bm_valvePT_2"
+#define BOOKMARK_VALVETEST_THRESHOLD_3    "bm_valvePT_3"
+#define BOOKMARK_VALVETEST_THRESHOLD_4    "bm_valvePT_4"
+
+#define BOOKMARK_VALVETEST_RESULT  "bm_valve_result"
+
+#define BOOKMARK_DATE_YEAR   "bm_year"
+#define BOOKMARK_DATE_MONTH  "bm_month"
+#define BOOKMARK_DATE_DAY    "bm_day"
+
+#define BOOKMARK_TEST_PICTURE_1         "bm_picAll_1"
+#define BOOKMARK_SYSTEST_PICTURE_1      "bm_picSys_1"
+#define BOOKMARK_VALVETEST_PICTURE_1    "bm_picValve_1"
+
+#define BOOKMARK_TEST_PICTURE_2         "bm_picAll_2"
+#define BOOKMARK_SYSTEST_PICTURE_2      "bm_picSys_2"
+#define BOOKMARK_VALVETEST_PICTURE_2    "bm_picValve_2"
+
+#define BOOKMARK_TEST_PICTURE_3         "bm_picAll_3"
+#define BOOKMARK_SYSTEST_PICTURE_3      "bm_picSys_3"
+#define BOOKMARK_VALVETEST_PICTURE_3    "bm_picValve_3"
+
+#define BOOKMARK_TEST_PICTURE_4         "bm_picAll_4"
+#define BOOKMARK_SYSTEST_PICTURE_4      "bm_picSys_4"
+#define BOOKMARK_VALVETEST_PICTURE_4    "bm_picValve_4"
+
+
+
+class Report:public QObject
+{
+    Q_OBJECT
+public:
+    Report();
+    ~Report();
+
+    bool make_Word(Tanker& tanker, QString word_path, QString pic_dir);
+    bool make_PDF(Tanker& tanker, QString word_path, QString pic_dir);
+signals:
+    void onProgress(QString qstr);
+
+};
+
+
+#endif // REPORT_H

+ 347 - 0
serialport.cpp

@@ -0,0 +1,347 @@
+#include "serialport.h"
+#include  <QtDebug>
+#include <QSignalSpy>
+
+SerialPort::SerialPort(QObject *parent) : QObject(parent)
+{
+    //m_serial = new QSerialPort;
+
+    //connect(this,&SerialUi::sendConnect,mSerialPort,&SerialPort::receiveConnect);
+
+    //  connect(this,&SerialPort::sendOk,this,&SerialPort::recieveData);
+    // connect(m_serial,&QSerialPort::readyRead,this,&SerialPort::recieveData);
+
+}
+
+void SerialPort::receiveInit()
+{
+    m_serial = new QSerialPort;
+    //connect(m_serial,&QSerialPort::readyRead,this,&SerialPort::recieveData);
+}
+
+#if 0
+
+void SerialPort::recieveData()
+{
+    mData.clear();
+
+    //QSignalSpy spy(m_serial, SIGNAL(readyRead()));
+    //bool ret = spy.wait(600);
+    //if(ret == true){
+        mData = m_serial->readAll();
+        //while (1){
+        QThread::msleep(30);
+        mData += m_serial->readAll();
+
+        qDebug()<<"modbus received data length is : "<< mData.length();
+
+        //}
+   // }
+   // else{
+   //     qDebug()<<"modbus time out";
+   //     emit sendTimeout();
+   // }
+
+    sendReceiveData();
+
+}
+
+
+void SerialPort::crcCheck(uint8_t *data, int length, uint8_t *crc_h, uint8_t *crc_l)
+{
+    int j;
+    uint16_t reg_crc=0xFFFF;
+
+    while(length--)
+    {
+        reg_crc ^= *data++;
+        for(j=0;j<8;j++)
+        {
+            if(reg_crc & 0x01) /* LSB(b0)=1 */
+                reg_crc=(reg_crc>>1) ^ 0xA001;
+            else
+                reg_crc=reg_crc >>1;
+        }
+    }
+    *crc_h = (reg_crc>>8)&0x00ff;
+    *crc_l = reg_crc&0x00ff;
+}
+#endif
+
+
+SerialPort::~SerialPort()
+{
+    if(m_serial->isOpen())
+    {
+        m_serial->clear();
+        m_serial->close();
+    }
+    m_serial->deleteLater();
+}
+
+bool SerialPort::serialConnect(QString port, QString baudrate, QString databits, QString parity, QString stopbits)
+{
+    m_serial->setPortName(port);
+    if(!m_serial->open(QIODevice::ReadWrite))
+    {
+        qDebug()<<"Open" +port+" Error";
+        return false;
+    }
+
+    switch (baudrate.toInt()) {
+    case 4800:
+        m_serial->setBaudRate(QSerialPort::Baud4800);
+        break;
+    case 9600:
+        m_serial->setBaudRate(QSerialPort::Baud9600);
+        break;
+    case 115200:
+        m_serial->setBaudRate(QSerialPort::Baud115200);
+        break;
+    default:
+        qDebug("BaudRate Error");
+        return false;
+    }
+
+    switch (databits.toInt()) {
+    case 6:
+        m_serial->setDataBits(QSerialPort::Data6);
+        break;
+    case 7:
+        m_serial->setDataBits(QSerialPort::Data7);
+        break;
+    case 8:
+        m_serial->setDataBits(QSerialPort::Data8);
+        break;
+    default:
+        qDebug("DataBits Error");
+        return 0;
+    }
+    //model: ["NONE","ODD","EVEN"]  0  1  2
+    switch (parity.toInt()) {
+    case 0:
+        m_serial->setParity(QSerialPort::NoParity); //Check digit is set to 0
+        qDebug("parity = NONE");
+        break;
+    case 2:
+        m_serial->setParity(QSerialPort::EvenParity);
+        qDebug("parity = EVEN");
+        break;
+    case 1:
+        m_serial->setParity(QSerialPort::OddParity);
+        qDebug("parity = ODD");
+        break;
+    default:
+        qDebug("Parity Error");
+        return 0;
+    }
+
+    switch (stopbits.toInt()) {
+    case 1:
+        m_serial->setStopBits(QSerialPort::OneStop); //Stop bit is set to 1
+        break;
+    case 2:
+        m_serial->setStopBits(QSerialPort::TwoStop);
+        break;
+    case 3:
+        m_serial->setStopBits(QSerialPort::OneAndHalfStop);
+        break;
+    default:
+        printf("StopBits Error");
+        return 0;
+    }
+
+    m_serial->setFlowControl(QSerialPort::NoFlowControl);//Set to no flow control
+
+    return  true;
+}
+
+void SerialPort::closeConnect()
+{
+    if(m_serial->isOpen())
+    {
+        m_serial->clear();
+        m_serial->close();
+    }
+    // m_serial->deleteLater();
+}
+
+/*
+bool SerialPort::serialWriteReponse(QString sendStr)
+{
+
+//    if(m_serial->isOpen() == false)
+//        return false;
+
+//    QByteArray responseData;
+//    responseData.clear();
+
+//    m_serial->readAll(); //clear buffer
+
+//    QStringList strList = sendStr.split(" ");
+//    strList.removeAll("");
+
+//    if(strList.length() == 0)
+//        return 0;
+
+//    char *sendData  = (char *) malloc(128);
+
+//    int cnt=0;
+//    QStringListIterator strIterator(strList);
+//    while (strIterator.hasNext()){
+//        QString str = strIterator.next();
+//        char value = str.toInt(nullptr, 16);
+//        sendData[cnt++] = value;
+//    }
+//    uint8_t crc_h;
+//    uint8_t crc_l;
+//    crcCheck((uint8_t *)sendData, cnt, &crc_h, &crc_l);
+//    sendData[cnt++] = crc_l;
+//    sendData[cnt++] = crc_h;
+
+//    m_serial->write(sendData,cnt);
+
+//    QSignalSpy spy(m_serial, SIGNAL(readyRead()));
+//    bool ret = spy.wait(500);
+//    if(ret == true){
+//        QByteArray responseData = m_serial->readAll();
+//        while (spy.wait(10) == true){
+//            responseData += m_serial->readAll();
+//        }
+
+//        if(responseData.length() > 2){
+//            for(int i=0 ;i<responseData.length(); i++){
+//                uint8_t value = responseData.at(i);
+//                sendData[i] = value;
+//            }
+//            crcCheck((uint8_t *)sendData, responseData.length(), &crc_h, &crc_l);
+//            if(crc_h !=0 || crc_l !=0  ){
+//                qDebug()<<"crc  error";
+//            }
+//            else{
+//                emit sendReceiveData(responseData);
+//            }
+//        }
+
+//       // emit sendReceiveData(responseData);
+//    }
+//    else{
+//        qDebug()<<"time out";
+//    }
+
+//    free(sendData);
+    return 1;
+
+}
+*/
+QByteArray SerialPort::serialRead()
+{
+    return mData;
+}
+
+bool SerialPort::getOpenStatus()
+{
+    return m_serial->isOpen();
+}
+
+/*
+bool SerialPort::serialWrite(QString sendStr)
+{
+
+    m_serial->write(sendStr.toLatin1().data(),strlen(sendStr.toLatin1().data()));
+    return 1;
+}
+*/
+
+
+void SerialPort::receiveConnect(QString port, QString baudrate, QString databits, QString parity, QString stopbits)
+{
+    bool  status =  serialConnect( port,  baudrate,  databits,  parity,  stopbits);
+    emit sendPortStatus(status);
+}
+
+void SerialPort::receiveOnlyWrite(QByteArray sendData)
+{
+    //延时用 没其他意义 把队列内容 依次发出
+    QSignalSpy spy(m_serial, SIGNAL(readChannelFinished()));
+    spy.wait(300);
+    if(m_serial->isOpen() == false){
+        return  ;
+    }
+
+    int retryCnt=0;
+ retry:
+     m_serial->readAll();
+     m_serial->write(sendData);
+     m_serial->waitForBytesWritten(1000);
+
+     QSignalSpy spy1(m_serial, SIGNAL(readyRead()));
+     bool ret = spy1.wait(300);
+     if(ret == true){
+            qDebug()<<"get response";
+            QByteArray responseData = m_serial->readAll();
+            qDebug()<<responseData;
+     }
+     else{
+         qDebug()<<"get timeout";
+         QByteArray responseData = m_serial->readAll();
+         qDebug()<<responseData;
+         retryCnt++;
+         if(retryCnt > 2)
+             return;
+         goto retry;
+     }
+
+}
+void SerialPort::receiveWrite(QByteArray sendData)
+{
+
+   // qDebug() << QThread::currentThreadId() << "SerialPort";
+   // QList<int> data;
+    //qDebug()<<sendStr;
+
+    mData.clear();
+    //QByteArray responseData;
+    //responseData.clear();
+
+    if(m_serial->isOpen() == false){
+        sendReceiveData();
+        return  ;
+    }
+
+
+    QByteArray response = m_serial->readAll(); //clear buffer
+    if(response.length() > 0){
+        qDebug()<< "may be lost data";
+    }
+
+    m_serial->write(sendData);
+    m_serial->waitForBytesWritten(200);
+
+#if 1
+
+    QSignalSpy spy(m_serial, SIGNAL(readyRead()));
+    bool ret = spy.wait(300);
+    if(ret == true){
+        mData = m_serial->readAll();
+        while (spy.wait(30) == true){
+            mData += m_serial->readAll();
+        }
+    }
+    else{
+        qDebug()<<"modbus time out";
+        emit sendTimeout();
+    }
+
+    sendReceiveData();
+
+#endif
+
+}
+
+void SerialPort::reveiveClose()
+{
+    closeConnect();
+}
+
+

+ 54 - 0
serialport.h

@@ -0,0 +1,54 @@
+#ifndef SERIALPORT_H
+#define SERIALPORT_H
+
+#include <QObject>
+#include <QSerialPort>
+#include <QMutex>
+
+class SerialPort : public QObject
+{
+    Q_OBJECT
+public:
+    explicit SerialPort(QObject *parent = nullptr);
+    ~SerialPort();
+
+    //    Q_INVOKABLE bool serialConnect(QString port,QString baudrate,QString databits,QString parity,QString stopbits);
+    //    Q_INVOKABLE void closeConnect();
+    //    Q_INVOKABLE bool serialWrite(QString sendStr);
+    //    Q_INVOKABLE bool serialWriteReponse(QString sendStr);
+    //    Q_INVOKABLE QString serialRead();
+
+    bool serialConnect(QString port,QString baudrate,QString databits,QString parity,QString stopbits);
+    void closeConnect();
+    //bool serialWrite(QString sendStr);
+    //bool serialWriteReponse(QString sendStr);
+    QByteArray serialRead();
+    bool getOpenStatus();
+
+signals:
+    void sendPortStatus(bool status);
+    void sendReceiveData();
+    void sendCrcError();
+    void sendTimeout();
+
+
+
+public slots:
+    void receiveConnect(QString port,QString baudrate,QString databits,QString parity,QString stopbits);
+    void receiveWrite(QByteArray sendData);
+    void receiveOnlyWrite(QByteArray sendData);
+    void reveiveClose();
+    void receiveInit();
+    //void recieveData();
+
+private:
+    QSerialPort *m_serial;
+    QByteArray mData;
+    QMutex mutex;
+
+    void crcCheck(uint8_t *data, int length,uint8_t *crc_h,uint8_t *crc_l);
+
+
+};
+
+#endif // SERIALPORT_H

+ 130 - 0
serialui.cpp

@@ -0,0 +1,130 @@
+
+#include <QThread>
+#include <QtDebug>
+#include <QSignalSpy>
+#include <QMutexLocker>
+#include "serialui.h"
+
+SerialUi::SerialUi(QObject *parent) : QObject(parent)
+{
+    static QThread* thread = new QThread;
+    mSerialPort = new SerialPort();
+    mSerialPort->moveToThread(thread);
+
+    //connect(this,&SerialUi::sendConnect,mSerialPort,&SerialPort::receiveConnect);
+    connect(this,&SerialUi::sendWrite,mSerialPort,&SerialPort::receiveWrite);
+    connect(this,&SerialUi::sendOnlyWrite,mSerialPort,&SerialPort::receiveOnlyWrite);
+
+
+    connect(this,&SerialUi::sendClose,mSerialPort,&SerialPort::reveiveClose);
+    connect(this,&SerialUi::sendInit,mSerialPort,&SerialPort::receiveInit);
+
+
+    connect(mSerialPort,&SerialPort::sendPortStatus,this,&SerialUi::receivePortStatus);
+    connect(mSerialPort,&SerialPort::sendCrcError,this,&SerialUi::receiveCrcError);
+    connect(mSerialPort,&SerialPort::sendTimeout,this,&SerialUi::receiveTimeout);
+
+    thread->start();
+    emit sendInit();
+
+}
+
+void SerialUi::serialWrite(QByteArray sendData)
+{
+    //qDebug() << QThread::currentThreadId() << "SerialUi";
+    if(mSerialPort->getOpenStatus() == true)
+        emit sendWrite(sendData);
+
+    //    QString s;
+
+    //    s += QString::number(0x10,16)+" ";
+    //    s += QString::number(0x11,16)+" ";
+    //    s += QString::number(0x12,16)+" ";
+    //    qDebug()<<s;
+    //QByteArray::toHex ()
+}
+
+void SerialUi::onlyWrite(QByteArray sendData)
+{
+    emit sendOnlyWrite(sendData);
+}
+
+void SerialUi::closeConnect()
+{
+    emit sendClose();
+
+    //mSerialPort->closeConnect();
+}
+
+QByteArray SerialUi::serialWriteReponse(QByteArray sendData)
+{
+   // QMutexLocker locker(&mutex);
+
+    //qDebug() << QThread::currentThreadId() << "SerialUi";
+    QByteArray data;
+    if(mSerialPort->getOpenStatus() == false)
+        return  data;
+
+    emit sendWrite(sendData);
+    QSignalSpy spy(mSerialPort, SIGNAL(sendReceiveData()));
+    bool ret = spy.wait(500);
+    if(ret == true)
+        data = mSerialPort->serialRead();
+
+    //    emit sendWrite(sendStr);
+    //    //void sendReponse(QList<int> data);
+    //    QSignalSpy spy(mSerialWrite, SIGNAL(sendReponse()));
+    //    bool ret = spy.wait(800);
+    //    if(ret == true)
+    //        QList<int> data = mSerialWrite->readAll();
+
+    return  data;
+}
+
+void SerialUi::receivePortStatus(bool status)
+{
+    emit portStatusChange(status);
+}
+
+void SerialUi::receiveData(QByteArray data)
+{
+    QList<int> rawData;
+    rawData.clear();
+    for(int i=0; i<data.length();i++){
+        uint8_t value =data.at(i);
+        rawData.append(value);
+    }
+    emit receiveRawDataChange(rawData);
+
+    QString s;
+    s.clear();
+    for(int i=0; i<data.length();i++){
+        uint8_t value =data.at(i);
+        if(value < 0x10){
+            s += "0"+QString::number(data.at(i),16)+" ";
+        }
+        else{
+            s += QString::number(value,16)+" ";
+        }
+    }
+    s.remove(s.length()-1,1);
+    emit receiveDataChange(s);
+}
+
+void SerialUi::receiveCrcError()
+{
+    emit checkError();
+}
+
+void SerialUi::receiveTimeout()
+{
+    emit timeout();
+}
+
+bool SerialUi::serialConnect(QString port, QString baudrate, QString databits, QString parity, QString stopbits)
+{
+    // emit sendConnect( port,  baudrate,  databits,  parity,  stopbits);
+    bool ret =  mSerialPort->serialConnect(port,  baudrate,  databits,  parity,  stopbits);
+    // qDebug()<<ret;
+    return  ret;
+}

+ 48 - 0
serialui.h

@@ -0,0 +1,48 @@
+#ifndef SERIALUI_H
+#define SERIALUI_H
+
+#include <QObject>
+#include <QMutex>
+#include "serialport.h"
+
+class SerialUi : public QObject
+{
+    Q_OBJECT
+    //Q_PROPERTY(QString portStatus  NOTIFY portStatusChange)
+public:
+    explicit SerialUi(QObject *parent = nullptr);
+     bool serialConnect(QString port,QString baudrate,QString databits,QString parity,QString stopbits);
+     void serialWrite(QByteArray sendData);
+     void onlyWrite(QByteArray sendData);
+     void closeConnect();
+     QByteArray  serialWriteReponse(QByteArray sendData);
+
+
+public slots:
+    void receivePortStatus(bool status);
+    void receiveData(QByteArray data);
+    void receiveCrcError();
+    void receiveTimeout();
+
+
+signals:
+    void spy();
+    void receiveRawDataChange(QList<int> data);
+    void portStatusChange(bool status);
+    void receiveDataChange(QString data);
+    void sendConnect(QString port,QString baudrate,QString databits,QString parity,QString stopbits);
+    void sendWrite(QByteArray sendData);
+    void sendOnlyWrite(QByteArray sendData);
+    void sendClose();
+    void sendInit();
+    void timeout();
+    void checkError();
+
+
+
+private:
+    SerialPort *mSerialPort;
+    QMutex mutex;
+};
+
+#endif // SERIALUI_H

+ 234 - 0
tank.cpp

@@ -0,0 +1,234 @@
+#include "tank.h"
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QByteArray>
+
+
+//油气回收系统 外观检查项
+static QString vrs_visual_inspection_items[VRS_VISUAL_INSPECTION_ITEMS_NUM] ={
+        "油气回收耦合阀",
+        "通气阀",
+        "油气回收阀",
+        "密封盖",
+        "气动联锁阀",
+        "连接管路",
+        "控制管路",
+        "多仓油气管路并联"
+};
+
+
+//底部装油系统 外观检查项
+static QString bls_visual_inspection_items[BLS_VISUAL_INSPECTION_ITEMS_NUM] ={
+        "卸油阀",
+        "呼吸阀",
+        "紧急切断阀",
+        "连接管线",
+        "防溢流系统"
+};
+
+
+
+Compartment::Compartment()
+{
+    m_result.delta_sys_pressure= 0.0;
+    m_result.pass_sys_pressure = false;
+    m_result.delta_valve_pressure = 0.0;
+    m_result.pass_valve_pressure = false;
+    m_bpicReady=false;
+
+}
+Compartment::~Compartment()
+{
+
+}
+
+int Compartment::get_Roughadjust_timeout()
+{
+    int timeout = 0;
+
+    if(m_volume > 30000){
+        timeout = 60*60;
+    }else if(m_volume > 15000){
+        timeout = 45*60;
+    }else if(m_volume > 10000){
+        timeout = 30*60;
+    }else if(m_volume > 5000){
+        timeout = 15*60;
+    }else if(m_volume > 1000){
+        timeout = 5*60;
+    }else{
+        timeout = 3*60;
+    }
+
+    timeout = 30*60;
+
+    return timeout;
+}
+
+int Compartment::get_adjust_timeout()
+{
+    int timeout = 0;
+
+    if(m_volume > 9000){
+        timeout = 5*60;
+    }else if(m_volume > 7000){
+        timeout = 5*60;
+    }else if(m_volume > 5000){
+        timeout = 5*60;
+    }else if(m_volume > 3000){
+        timeout = 5*60;
+    }else if(m_volume > 1000){
+        timeout = 5*60;
+    }else{
+        timeout = 5*60;
+    }
+
+    timeout = 15*60;
+
+    return timeout;
+}
+
+void Compartment::clear_result()
+{
+    m_result.pass_sys_pressure = false;
+    m_result.pass_valve_pressure = false;
+    m_result.sys_test_ok = false;
+    m_result.valve_test_ok = false;
+    m_bpicReady = false;
+}
+
+
+Tanker::Tanker()
+{
+    for(int i =0; i< VRS_VISUAL_INSPECTION_ITEMS_NUM; i++){
+        vrs_results[i] = RESULT_QUALIFIED;
+    }
+
+    for(int i=0; i< BLS_VISUAL_INSPECTION_ITEMS_NUM; i++){
+        bls_results[i] = RESULT_QUALIFIED;
+    }
+
+
+
+}
+
+Tanker::~Tanker()
+{
+
+}
+
+Compartment& Tanker::get_compartment(int id)
+{
+
+   return m_comparts[id];
+}
+
+QJsonObject Tanker::get_vrs_items()
+{
+    QJsonObject jsonObj;
+    jsonObj.insert("count", VRS_VISUAL_INSPECTION_ITEMS_NUM);
+
+    QJsonArray itemsArray;
+
+    for(int i=0; i < VRS_VISUAL_INSPECTION_ITEMS_NUM; i++){
+
+        QJsonObject itemObj;
+        //itemObj.insert("index", i);
+        itemObj.insert("name", vrs_visual_inspection_items[i]);
+        itemObj.insert("value", QString::number(vrs_results[i]));
+
+        itemsArray.append(itemObj);
+    }
+
+    jsonObj.insert("item", itemsArray);
+
+    return jsonObj;
+}
+
+QJsonObject Tanker::get_bls_items()
+{
+    QJsonObject jsonObj;
+    jsonObj.insert("count", BLS_VISUAL_INSPECTION_ITEMS_NUM);
+
+    QJsonArray itemsArray;
+
+    for(int i=0; i < BLS_VISUAL_INSPECTION_ITEMS_NUM; i++){
+
+        QJsonObject itemObj;
+        //jsonObj.insert("index", i);
+        itemObj.insert("name", bls_visual_inspection_items[i]);
+        itemObj.insert("value", QString::number(bls_results[i]));
+
+        itemsArray.append(itemObj);
+    }
+
+    jsonObj.insert("item", itemsArray);
+
+    return jsonObj;
+}
+
+bool Tanker::set_item_result(const QString& jsonStr )
+{
+    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8());
+    QJsonObject jsonObj = jsonDoc.object();
+
+    QString table_str;
+    QString item_name_str;
+    int value = RESULT_QUALIFIED;
+
+    if(jsonObj.contains("table") && jsonObj.value("table").isString()){
+        table_str = jsonObj.value("table").toString();
+    }else{
+        qDebug() << "set_item_result no table";
+        return false;
+    }
+
+    if(jsonObj.contains("name") && jsonObj.value("name").isString()){
+        item_name_str = jsonObj.value("name").toString();
+    }else{
+        qDebug() << "set_item_result no name";
+        return false;
+    }
+
+    if(jsonObj.contains("value") && jsonObj.value("value").isString()){
+        value = jsonObj.value("value").toString().toInt();
+    }else{
+        qDebug() << "set_item_result no value";
+        return false;
+    }
+
+    qDebug() << "table:" << table_str;
+
+    if(table_str == "vrs"){
+        for(int i=0; i<VRS_VISUAL_INSPECTION_ITEMS_NUM; i++){
+           if(item_name_str == vrs_visual_inspection_items[i]){
+               if(value >= RESULT_QUALIFIED && value <= RESULT_NOITEM){
+                   vrs_results[i] = value;
+                   qDebug() << "item_name:" << item_name_str;
+                   qDebug() << "value:" << value;
+               }
+           }
+        }
+
+    }else if(table_str == "bls"){
+        for(int i=0; i<BLS_VISUAL_INSPECTION_ITEMS_NUM; i++){
+           if(item_name_str == bls_visual_inspection_items[i]){
+               if(value >= RESULT_QUALIFIED && value <= RESULT_NOITEM){
+                   vrs_results[i] = value;
+                   qDebug() << "item_name:" << item_name_str;
+                   qDebug() << "value:" << value;
+               }
+           }
+        }
+    }else{
+        qDebug() << "set_item_result table_str invalid";
+        return false;
+    }
+
+
+    return true;
+}
+
+
+

+ 84 - 0
tank.h

@@ -0,0 +1,84 @@
+#ifndef TANK_H
+#define TANK_H
+
+#include"Standard.h"
+#define MAX_COMPARTMENT_NUM  (4)
+
+#define VRS_VISUAL_INSPECTION_ITEMS_NUM (8)  //油气回收系统 外观检查项个数
+#define BLS_VISUAL_INSPECTION_ITEMS_NUM (5)  //底部装油系统 外观检查项个数
+
+#define   RESULT_QUALIFIED (0)
+#define   RESULT_NONCONFORM (1)
+#define   RESULT_NOITEM (2)
+
+
+class PressureItem{
+public:
+    QDateTime m_datetime;
+    int m_testDirection;
+    int m_testStage;
+    int m_testStep;
+    double m_pressure;
+};
+
+class TestResult{
+public:
+    double sysstart_pressure;
+    double sysend_pressure;
+    double delta_sys_pressure;
+    bool  pass_sys_pressure;
+    bool  sys_test_ok;
+
+    double valvestart_pressure;
+    double valveend_pressure;
+    double delta_valve_pressure;
+    bool  pass_valve_pressure;
+    bool  valve_test_ok;
+};
+
+class Compartment{
+public:
+    Compartment();
+    ~Compartment();
+
+
+    int get_Roughadjust_timeout();
+    int get_adjust_timeout();
+    void clear_result();
+
+    int m_id;
+    int m_volume;
+
+    double m_currentpressure;
+
+    TestResult  m_result;
+    bool m_bpicReady;
+
+    StandardItem m_standarditem;
+
+    QVector<PressureItem> m_pressuredata;
+
+};
+
+class Tanker{
+public:
+    Tanker();
+    ~Tanker();
+    Compartment& get_compartment(int id);
+
+    QString  licenseplate_str;
+    QString  companyname_str;
+    int compartment_num;
+    int total_volume;
+    Compartment m_comparts[MAX_COMPARTMENT_NUM];
+
+    int vrs_results[VRS_VISUAL_INSPECTION_ITEMS_NUM];
+    int bls_results[BLS_VISUAL_INSPECTION_ITEMS_NUM];
+
+    QJsonObject get_vrs_items();
+    QJsonObject get_bls_items();
+    bool set_item_result(const QString& jsonStr );
+};
+
+
+#endif // TANK_H

BIN
valve.ico