sgtlib 3.3.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. StructuralGT/__init__.py +31 -0
  2. StructuralGT/apps/__init__.py +0 -0
  3. StructuralGT/apps/cli_main.py +258 -0
  4. StructuralGT/apps/gui_main.py +69 -0
  5. StructuralGT/apps/gui_mcw/__init__.py +0 -0
  6. StructuralGT/apps/gui_mcw/checkbox_model.py +91 -0
  7. StructuralGT/apps/gui_mcw/controller.py +1073 -0
  8. StructuralGT/apps/gui_mcw/image_provider.py +74 -0
  9. StructuralGT/apps/gui_mcw/imagegrid_model.py +75 -0
  10. StructuralGT/apps/gui_mcw/qthread_worker.py +102 -0
  11. StructuralGT/apps/gui_mcw/table_model.py +79 -0
  12. StructuralGT/apps/gui_mcw/tree_model.py +154 -0
  13. StructuralGT/apps/sgt_qml/CenterMainContent.qml +19 -0
  14. StructuralGT/apps/sgt_qml/LeftContent.qml +48 -0
  15. StructuralGT/apps/sgt_qml/MainWindow.qml +762 -0
  16. StructuralGT/apps/sgt_qml/RightLoggingPanel.qml +125 -0
  17. StructuralGT/apps/sgt_qml/assets/icons/.DS_Store +0 -0
  18. StructuralGT/apps/sgt_qml/assets/icons/back_icon.png +0 -0
  19. StructuralGT/apps/sgt_qml/assets/icons/brightness_icon.png +0 -0
  20. StructuralGT/apps/sgt_qml/assets/icons/cancel_icon.png +0 -0
  21. StructuralGT/apps/sgt_qml/assets/icons/crop_icon.png +0 -0
  22. StructuralGT/apps/sgt_qml/assets/icons/edit_icon.png +0 -0
  23. StructuralGT/apps/sgt_qml/assets/icons/graph_icon.png +0 -0
  24. StructuralGT/apps/sgt_qml/assets/icons/hide_panel.png +0 -0
  25. StructuralGT/apps/sgt_qml/assets/icons/next_icon.png +0 -0
  26. StructuralGT/apps/sgt_qml/assets/icons/notify_icon.png +0 -0
  27. StructuralGT/apps/sgt_qml/assets/icons/rescale_icon.png +0 -0
  28. StructuralGT/apps/sgt_qml/assets/icons/show_panel.png +0 -0
  29. StructuralGT/apps/sgt_qml/assets/icons/square_icon.png +0 -0
  30. StructuralGT/apps/sgt_qml/assets/icons/undo_icon.png +0 -0
  31. StructuralGT/apps/sgt_qml/components/ImageFilters.qml +82 -0
  32. StructuralGT/apps/sgt_qml/components/ImageProperties.qml +112 -0
  33. StructuralGT/apps/sgt_qml/components/ProjectNav.qml +127 -0
  34. StructuralGT/apps/sgt_qml/widgets/BinaryFilterWidget.qml +151 -0
  35. StructuralGT/apps/sgt_qml/widgets/BrightnessControlWidget.qml +103 -0
  36. StructuralGT/apps/sgt_qml/widgets/CreateProjectWidget.qml +112 -0
  37. StructuralGT/apps/sgt_qml/widgets/GTWidget.qml +94 -0
  38. StructuralGT/apps/sgt_qml/widgets/GraphComputeWidget.qml +77 -0
  39. StructuralGT/apps/sgt_qml/widgets/GraphExtractWidget.qml +175 -0
  40. StructuralGT/apps/sgt_qml/widgets/GraphPropertyWidget.qml +77 -0
  41. StructuralGT/apps/sgt_qml/widgets/ImageFilterWidget.qml +137 -0
  42. StructuralGT/apps/sgt_qml/widgets/ImagePropertyWidget.qml +78 -0
  43. StructuralGT/apps/sgt_qml/widgets/ImageViewWidget.qml +585 -0
  44. StructuralGT/apps/sgt_qml/widgets/MenuBarWidget.qml +137 -0
  45. StructuralGT/apps/sgt_qml/widgets/MicroscopyPropertyWidget.qml +80 -0
  46. StructuralGT/apps/sgt_qml/widgets/ProjectWidget.qml +141 -0
  47. StructuralGT/apps/sgt_qml/widgets/RescaleControlWidget.qml +83 -0
  48. StructuralGT/apps/sgt_qml/widgets/RibbonWidget.qml +406 -0
  49. StructuralGT/apps/sgt_qml/widgets/StatusBarWidget.qml +173 -0
  50. StructuralGT/compute/__init__.py +0 -0
  51. StructuralGT/compute/c_lang/include/sgt_base.h +21 -0
  52. StructuralGT/compute/graph_analyzer.py +1499 -0
  53. StructuralGT/entrypoints.py +49 -0
  54. StructuralGT/imaging/__init__.py +0 -0
  55. StructuralGT/imaging/base_image.py +403 -0
  56. StructuralGT/imaging/image_processor.py +780 -0
  57. StructuralGT/modules.py +29 -0
  58. StructuralGT/networks/__init__.py +0 -0
  59. StructuralGT/networks/fiber_network.py +490 -0
  60. StructuralGT/networks/graph_skeleton.py +425 -0
  61. StructuralGT/networks/sknw_mod.py +199 -0
  62. StructuralGT/utils/__init__.py +0 -0
  63. StructuralGT/utils/config_loader.py +244 -0
  64. StructuralGT/utils/configs.ini +97 -0
  65. StructuralGT/utils/progress_update.py +67 -0
  66. StructuralGT/utils/sgt_utils.py +291 -0
  67. sgtlib-3.3.9.dist-info/METADATA +789 -0
  68. sgtlib-3.3.9.dist-info/RECORD +72 -0
  69. sgtlib-3.3.9.dist-info/WHEEL +5 -0
  70. sgtlib-3.3.9.dist-info/entry_points.txt +3 -0
  71. sgtlib-3.3.9.dist-info/licenses/LICENSE +674 -0
  72. sgtlib-3.3.9.dist-info/top_level.txt +1 -0
@@ -0,0 +1,103 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Layouts
4
+
5
+
6
+ Item {
7
+ id: brightnessControl // used for external access
8
+ Layout.preferredHeight: 75
9
+ Layout.preferredWidth: parent.width
10
+
11
+ property int spbWidthSize: 75
12
+ property int lblWidthSize: 75
13
+ property int valueRole: Qt.UserRole + 4
14
+ property alias clBrightnessCtrl: brightnessCtrlLayout
15
+
16
+ ColumnLayout {
17
+ id: brightnessCtrlLayout
18
+ spacing: 10
19
+
20
+ Repeater {
21
+ id: brightnessCtrlRepeater
22
+ model: imgControlModel
23
+ delegate: RowLayout {
24
+ objectName: "ctrlRowLayout"
25
+ Layout.fillWidth: true
26
+ Layout.leftMargin: 10
27
+ Layout.alignment: Qt.AlignLeft
28
+
29
+ Label {
30
+ id: label
31
+ Layout.preferredWidth: lblWidthSize
32
+ text: model.text
33
+ }
34
+
35
+ SpinBox {
36
+ id: spinBox
37
+ objectName: model.id
38
+ Layout.minimumWidth: spbWidthSize
39
+ Layout.fillWidth: false
40
+ editable: true
41
+ from: -100
42
+ to: 100
43
+ stepSize: 1
44
+ property var currVal: model.value
45
+ value: currVal
46
+ onValueChanged: updateValue(currVal, value)
47
+ onFocusChanged: {
48
+ if (focus) {
49
+ btnOK.visible = true;
50
+ }
51
+ }
52
+ }
53
+
54
+ Button {
55
+ id: btnOK
56
+ text: ""
57
+ Layout.preferredWidth: 36
58
+ Layout.preferredHeight: 30
59
+ Layout.rightMargin: 10
60
+ visible: false
61
+ onClicked: {
62
+ btnOK.visible = false;
63
+
64
+ //let textValue = spinBox.text;
65
+ //let val = spinBox.valueFromText(textValue);
66
+ //console.log(textValue);
67
+ let val = spinBox.value;
68
+
69
+ var index = imgControlModel.index(model.index, 0);
70
+ imgControlModel.setData(index, val, valueRole);
71
+ mainController.apply_img_ctrl_changes();
72
+ }
73
+
74
+ Rectangle {
75
+ anchors.fill: parent
76
+ radius: 5
77
+ color: "#22bc55"
78
+
79
+ Label {
80
+ text: "OK"
81
+ color: "#ffffff"
82
+ //font.bold: true
83
+ //font.pixelSize: 10
84
+ anchors.centerIn: parent
85
+ }
86
+ }
87
+ }
88
+
89
+ function updateValue(curr_val, val) {
90
+ if (curr_val !== val){
91
+ curr_val = val;
92
+ var index = imgControlModel.index(model.index, 0);
93
+ imgControlModel.setData(index, val, valueRole);
94
+ mainController.apply_img_ctrl_changes();
95
+ }
96
+ }
97
+
98
+
99
+ }
100
+
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,112 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Layouts
4
+ import Qt.labs.platform as Platform
5
+
6
+
7
+ Item {
8
+ //height: 75//parent.height
9
+ //width: parent.width
10
+ Layout.preferredHeight: 100
11
+ Layout.preferredWidth: parent.width
12
+
13
+ // Expose TextFields as properties to make them accessible
14
+ property alias lblName: lblProjectName
15
+ property alias lblLocation: lblProjectLocation
16
+
17
+ property alias txtName: txtProjectName
18
+ property alias txtLocation: txtProjectLocation
19
+
20
+ property int txtWidthSize: 200
21
+ property int lblWidthSize: 64
22
+
23
+
24
+ ColumnLayout {
25
+ spacing: 10
26
+
27
+ RowLayout {
28
+ Layout.fillWidth: true
29
+ Layout.leftMargin: 10
30
+ Layout.alignment: Qt.AlignLeft
31
+
32
+ Label {
33
+ id: lblProjectName
34
+ Layout.preferredWidth: lblWidthSize
35
+ text: "Name:"
36
+ //font.bold: true
37
+ }
38
+
39
+ TextField {
40
+ id: txtProjectName
41
+ Layout.minimumWidth: txtWidthSize
42
+ Layout.fillWidth: true
43
+ text: ""
44
+ onEditingFinished: {
45
+ lblProjectName.text = "Name:"
46
+ lblProjectName.color = "black";
47
+ txtProjectName.placeholderText = "";
48
+ }
49
+ }
50
+ }
51
+
52
+ RowLayout {
53
+ Layout.fillWidth: true
54
+ Layout.leftMargin: 10
55
+ Layout.alignment: Qt.AlignLeft
56
+
57
+ Label {
58
+ id: lblProjectLocation
59
+ Layout.preferredWidth: lblWidthSize
60
+ text: "Location:"
61
+ //font.bold: true
62
+ }
63
+
64
+ TextField {
65
+ id: txtProjectLocation
66
+ Layout.minimumWidth: txtWidthSize
67
+ Layout.fillWidth: true
68
+ readOnly: true
69
+ text: ""
70
+ placeholderText: "click here to select folder..."
71
+
72
+ MouseArea {
73
+ anchors.fill: parent
74
+ onClicked: {
75
+ onClicked: projectFolderDialog.open()
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ /*RowLayout {
82
+ Layout.fillWidth: true
83
+
84
+ Button {
85
+ text: "Create Project"
86
+ onClicked: {
87
+ if (txtProjectName.text === "" || txtProjectLocation.text === "") {
88
+ // Alert user - empty fields
89
+ } else {
90
+ mainController.create_sgt_project(txtProjectName.text, txtProjectLocation.text)
91
+ }
92
+ }
93
+ }
94
+
95
+ }*/
96
+
97
+ }
98
+
99
+
100
+ Platform.FolderDialog {
101
+ id: projectFolderDialog
102
+ title: "Select a project location"
103
+ onAccepted: {
104
+ lblLocation.text = "Location:"
105
+ lblLocation.color = "black";
106
+
107
+ txtProjectLocation.text = projectFolderDialog.folder;
108
+ }
109
+ //onRejected: {console.log("Canceled")}
110
+ }
111
+
112
+ }
@@ -0,0 +1,94 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Layouts
4
+
5
+ Item {
6
+ id: graphComputationCtrl
7
+ width: parent.width
8
+ implicitHeight: gtComputationLayout.implicitHeight
9
+
10
+ property int valueRole: Qt.UserRole + 4
11
+
12
+ ColumnLayout {
13
+ id: gtComputationLayout
14
+ width: parent.width
15
+ spacing: 10
16
+
17
+ Repeater {
18
+ model: gtcListModel
19
+ delegate: ColumnLayout {
20
+ Layout.fillWidth: true
21
+ spacing: 5
22
+
23
+ CheckBox {
24
+ id: parentCheckBox
25
+ Layout.leftMargin: 10
26
+ objectName: model.id
27
+ text: model.text
28
+ property bool isChecked: model.value === 1
29
+ checked: isChecked
30
+ onCheckedChanged: updateValue(isChecked, checked)
31
+
32
+ function updateValue(isChecked, checked) {
33
+ if (isChecked !== checked) { // Only update if there is a change
34
+ isChecked = checked
35
+ let val = checked ? 1 : 0;
36
+ let index = gtcListModel.index(model.index, 0);
37
+ gtcListModel.setData(index, val, valueRole);
38
+ }
39
+ }
40
+ }
41
+
42
+ // Dynamically load additional child content for specific IDs
43
+ Loader {
44
+ id: childContentLoader
45
+ active: parentCheckBox.checked
46
+ visible: active && item !== null
47
+ Layout.leftMargin: 20
48
+ sourceComponent: {
49
+ switch (model.id) {
50
+ case "display_ohms_histogram":
51
+ return ohmsComponent
52
+ case "compute_avg_node_connectivity":
53
+ return avgComponent
54
+ default:
55
+ return null
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+
62
+ Label {
63
+ wrapMode: Text.Wrap
64
+ Layout.leftMargin: 15
65
+ color: "#229922"
66
+ font.pixelSize: 10
67
+ Layout.preferredWidth: 200
68
+ text: "**Note**: all these computations are applied on the giant graph ONLY."
69
+ }
70
+ }
71
+
72
+ // Custom Component for 'display_ohms_histogram'
73
+ Component {
74
+ id: ohmsComponent
75
+ ColumnLayout {
76
+ MicroscopyPropertyWidget {
77
+ }
78
+ }
79
+ }
80
+
81
+ // Custom Component for 'compute_avg_node_connectivity'
82
+ Component {
83
+ id: avgComponent
84
+ ColumnLayout {
85
+ Label {
86
+ wrapMode: Text.Wrap
87
+ color: "#bc2222"
88
+ font.pixelSize: 10
89
+ Layout.preferredWidth: 200
90
+ text: "**Warning**: this calculation takes long (esp. when node-count > 2000)"
91
+ }
92
+ }
93
+ }
94
+ }
@@ -0,0 +1,77 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Layouts
4
+
5
+
6
+ Item {
7
+ id: graphComputeTbl
8
+ Layout.preferredHeight: (numRows * tblRowHeight) + 5
9
+ Layout.preferredWidth: parent.width - 10
10
+ Layout.leftMargin: 5
11
+ //Layout.rightMargin: 5
12
+
13
+ property int numRows: graphComputeModel.rowCount()
14
+ property int tblRowHeight: 30
15
+
16
+ TableView {
17
+ id: tblViewGraphParams
18
+ height: numRows * tblRowHeight
19
+ width: parent.width - 10
20
+ model: graphComputeModel
21
+
22
+ delegate: Rectangle {
23
+ implicitWidth: column === 0 ? (tblViewGraphParams.width * 0.6) : (tblViewGraphParams.width * 0.4)
24
+ implicitHeight: tblRowHeight
25
+ color: row % 2 === 0 ? "#f5f5f5" : "#ffffff" // Alternating colors
26
+
27
+ Text {
28
+ text: model.text
29
+ wrapMode: Text.Wrap
30
+ font.pixelSize: 10
31
+ color: "#303030"
32
+ anchors.fill: parent
33
+ anchors.topMargin: 5
34
+ anchors.leftMargin: 10
35
+ }
36
+
37
+ Loader {
38
+ sourceComponent: column === 1 ? lineBorder : noBorder
39
+ }
40
+ }
41
+
42
+ Component {
43
+ id: lineBorder
44
+ Rectangle {
45
+ width: 1 // Border width
46
+ height: tblRowHeight
47
+ color: "#e0e0e0" // Border color
48
+ anchors.left: parent.left
49
+ }
50
+ }
51
+
52
+ Component {
53
+ id: noBorder
54
+ Rectangle {
55
+ width: 5 // Border width
56
+ height: parent.height
57
+ color: transientParent
58
+ anchors.left: parent.left
59
+ }
60
+ }
61
+ }
62
+
63
+
64
+ Connections {
65
+ target: mainController
66
+
67
+ function onImageChangedSignal(){
68
+ numRows = graphComputeModel.rowCount();
69
+ }
70
+
71
+ function onTaskTerminatedSignal(success_val, msg_data){
72
+ numRows = graphComputeModel.rowCount();
73
+ }
74
+
75
+ }
76
+
77
+ }
@@ -0,0 +1,175 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Controls.Basic as Basic
4
+ import QtQuick.Layouts
5
+
6
+
7
+ Item {
8
+ id: gteTreeControl
9
+ width: parent.width
10
+ enabled: mainController.display_image()
11
+
12
+ property int treeViewHeight: 320
13
+ property int treeViewWidth: 240
14
+ property int idRole: (Qt.UserRole + 1)
15
+
16
+ ColumnLayout {
17
+ anchors.fill: parent
18
+
19
+ TreeView {
20
+ id: gteTreeView
21
+ width: treeViewWidth
22
+ height: treeViewHeight
23
+ model: gteTreeModel
24
+
25
+ ButtonGroup {
26
+ id: btnGrpWeights
27
+ exclusive: true
28
+ }
29
+
30
+ delegate: Item {
31
+ required property TreeView treeView
32
+ required property int row
33
+ required property string id // Ensure the id is passed for selection
34
+ required property int depth
35
+ required property bool hasChildren
36
+ required property bool expanded
37
+
38
+ implicitWidth: gteTreeView.width
39
+ implicitHeight: 24
40
+
41
+ RowLayout {
42
+ spacing: 5
43
+ anchors.fill: parent
44
+
45
+ // Expand/Collapse Button
46
+ Basic.Button {
47
+ Layout.leftMargin: 10
48
+ visible: hasChildren
49
+ text: expanded ? "▼" : "▶"
50
+ //text: expanded ? "∨" : ">"
51
+ background: Rectangle { color: "transparent" }
52
+ onClicked: gteTreeView.toggleExpanded(row)
53
+ }
54
+
55
+ Loader {
56
+ Layout.fillWidth: (model.id !== "merge_node_radius_size" || model.id !== "prune_max_iteration_count" || model.id !== "remove_object_size")
57
+ Layout.preferredWidth: 75
58
+ Layout.leftMargin: hasChildren ? 0 : depth > 0 ? 50 : 10
59
+ sourceComponent: (model.id === "merge_node_radius_size" || model.id === "prune_max_iteration_count" || model.id === "remove_object_size")
60
+ ? txtFldComponent : model.text.startsWith("by")
61
+ ? rdoComponent : cbxComponent
62
+ }
63
+
64
+ Component {
65
+ id: cbxComponent
66
+
67
+ CheckBox {
68
+ id: checkBox
69
+ objectName: model.id
70
+ text: model.text
71
+ property bool isChecked: model.value === 1
72
+ checked: isChecked
73
+ onCheckedChanged: {
74
+ if (isChecked !== checked) { // Only update if there is a change
75
+ isChecked = checked
76
+ let val = checked ? 1 : 0;
77
+ var index = gteTreeModel.index(model.index, 0);
78
+ gteTreeModel.setData(index, val, Qt.EditRole);
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ Component {
85
+ id: rdoComponent
86
+
87
+ RadioButton {
88
+ id: rdoButton
89
+ objectName: model.id
90
+ text: model.text
91
+ ButtonGroup.group: btnGrpWeights
92
+ checked: model.value
93
+ onClicked: btnGrpWeights.checkedButton = this
94
+ onCheckedChanged: {
95
+ var val = checked ? 1 : 0;
96
+ updateChild(model.id, val);
97
+ }
98
+ }
99
+ }
100
+
101
+ Component {
102
+ id: txtFldComponent
103
+
104
+ RowLayout {
105
+
106
+ TextField {
107
+ id: txtField
108
+ objectName: model.id
109
+ width: 80
110
+ property int txtVal: model.value
111
+ text: txtVal
112
+ }
113
+
114
+ Button {
115
+ id: btnRemoveOk
116
+ text: ""
117
+ Layout.preferredWidth: 36
118
+ Layout.preferredHeight: 30
119
+ Layout.rightMargin: 10
120
+ onFocusChanged: {btnRemoveOk.visible = true;}
121
+ onClicked: {
122
+ updateChild(model.id, txtField.text);
123
+ btnRemoveOk.visible = false;
124
+ }
125
+
126
+ Rectangle {
127
+ anchors.fill: parent
128
+ radius: 5
129
+ color: "#22bc55"
130
+
131
+ Label {
132
+ text: "OK"
133
+ color: "#ffffff"
134
+ //font.bold: true
135
+ //font.pixelSize: 10
136
+ anchors.centerIn: parent
137
+ }
138
+ }
139
+ }
140
+
141
+ }
142
+ }
143
+
144
+ }
145
+
146
+ function updateChild(child_id, val) {
147
+ let row_count = gteTreeModel.rowCount();
148
+ for (let row = 0; row < row_count; row++) {
149
+ let parentIndex = gteTreeModel.index(row, 0);
150
+ let rows = gteTreeModel.rowCount(parentIndex);
151
+ for (let r = 0; r < rows; r++) {
152
+ let childIndex = gteTreeModel.index(r, 0, parentIndex);
153
+ let item_id = gteTreeModel.data(childIndex, idRole);
154
+ if (child_id === item_id) {
155
+ gteTreeModel.setData(childIndex, val, Qt.EditRole);
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
161
+
162
+ }
163
+ }
164
+
165
+
166
+ Connections {
167
+ target: mainController
168
+
169
+ function onImageChangedSignal() {
170
+ // Force refresh
171
+ gteTreeControl.enabled = mainController.display_image();
172
+ }
173
+
174
+ }
175
+ }
@@ -0,0 +1,77 @@
1
+ import QtQuick
2
+ import QtQuick.Controls
3
+ import QtQuick.Layouts
4
+
5
+
6
+ Item {
7
+ id: graphPropsTbl
8
+ Layout.preferredHeight: (numRows * tblRowHeight) + 5
9
+ Layout.preferredWidth: parent.width - 10
10
+ Layout.leftMargin: 5
11
+ //Layout.rightMargin: 5
12
+
13
+ property int numRows: graphPropsModel.rowCount()
14
+ property int tblRowHeight: 25
15
+
16
+ TableView {
17
+ id: tblViewGraphProps
18
+ height: numRows * tblRowHeight
19
+ width: parent.width - 10
20
+ model: graphPropsModel
21
+
22
+ delegate: Rectangle {
23
+ implicitWidth: column === 0 ? (tblViewGraphProps.width * 0.4) : (tblViewGraphProps.width * 0.6)
24
+ implicitHeight: tblRowHeight
25
+ color: row % 2 === 0 ? "#f5f5f5" : "#ffffff" // Alternating colors
26
+
27
+ Text {
28
+ text: model.text
29
+ wrapMode: Text.Wrap
30
+ font.pixelSize: 10
31
+ color: "#303030"
32
+ anchors.fill: parent
33
+ anchors.topMargin: 5
34
+ anchors.leftMargin: 10
35
+ }
36
+
37
+ Loader {
38
+ sourceComponent: column === 1 ? lineBorder : noBorder
39
+ }
40
+ }
41
+
42
+ Component {
43
+ id: lineBorder
44
+ Rectangle {
45
+ width: 1 // Border width
46
+ height: tblRowHeight
47
+ color: "#e0e0e0" // Border color
48
+ anchors.left: parent.left
49
+ }
50
+ }
51
+
52
+ Component {
53
+ id: noBorder
54
+ Rectangle {
55
+ width: 5 // Border width
56
+ height: parent.height
57
+ color: transientParent
58
+ anchors.left: parent.left
59
+ }
60
+ }
61
+ }
62
+
63
+ Connections {
64
+ target: mainController
65
+
66
+ function onImageChangedSignal(){
67
+ numRows = graphPropsModel.rowCount();
68
+ }
69
+
70
+ function onTaskTerminatedSignal(success_val, msg_data){
71
+ numRows = graphPropsModel.rowCount();
72
+ }
73
+
74
+ }
75
+ }
76
+
77
+