PaIRS-UniNa 0.2.5__cp312-cp312-win_amd64.whl → 0.2.8__cp312-cp312-win_amd64.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 (54) hide show
  1. PaIRS_UniNa/Changes.txt +45 -2
  2. PaIRS_UniNa/Explorer.py +3126 -3059
  3. PaIRS_UniNa/FolderLoop.py +561 -371
  4. PaIRS_UniNa/Input_Tab.py +826 -714
  5. PaIRS_UniNa/Input_Tab_CalVi.py +15 -17
  6. PaIRS_UniNa/Input_Tab_tools.py +3019 -3017
  7. PaIRS_UniNa/Output_Tab.py +2 -4
  8. PaIRS_UniNa/PaIRS.py +17 -17
  9. PaIRS_UniNa/PaIRS_pypacks.py +227 -56
  10. PaIRS_UniNa/Process_Tab.py +2 -2
  11. PaIRS_UniNa/Process_Tab_Disp.py +1 -1
  12. PaIRS_UniNa/Saving_tools.py +277 -277
  13. PaIRS_UniNa/TabTools.py +7 -4
  14. PaIRS_UniNa/Vis_Tab.py +129 -60
  15. PaIRS_UniNa/Whatsnew.py +15 -3
  16. PaIRS_UniNa/_PaIRS_PIV.pyd +0 -0
  17. PaIRS_UniNa/__init__.py +4 -4
  18. PaIRS_UniNa/addwidgets_ps.py +28 -20
  19. PaIRS_UniNa/calibView.py +7 -0
  20. PaIRS_UniNa/gPaIRS.py +3889 -3745
  21. PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
  22. PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
  23. PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
  24. PaIRS_UniNa/icons/pencil_bw.png +0 -0
  25. PaIRS_UniNa/icons/scan_path_loop.png +0 -0
  26. PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
  27. PaIRS_UniNa/listLib.py +301 -301
  28. PaIRS_UniNa/parForMulti.py +433 -433
  29. PaIRS_UniNa/pivParFor.py +1 -1
  30. PaIRS_UniNa/procTools.py +51 -3
  31. PaIRS_UniNa/rqrdpckgs.txt +6 -5
  32. PaIRS_UniNa/stereoPivParFor.py +1 -1
  33. PaIRS_UniNa/tabSplitter.py +606 -606
  34. PaIRS_UniNa/ui_Calibration_Tab.py +542 -542
  35. PaIRS_UniNa/ui_Custom_Top.py +294 -294
  36. PaIRS_UniNa/ui_Input_Tab.py +1098 -1098
  37. PaIRS_UniNa/ui_Input_Tab_CalVi.py +1280 -1280
  38. PaIRS_UniNa/ui_Log_Tab.py +261 -261
  39. PaIRS_UniNa/ui_Output_Tab.py +2360 -2360
  40. PaIRS_UniNa/ui_Process_Tab.py +3808 -3808
  41. PaIRS_UniNa/ui_Process_Tab_CalVi.py +1547 -1547
  42. PaIRS_UniNa/ui_Process_Tab_Disp.py +1139 -1139
  43. PaIRS_UniNa/ui_Process_Tab_Min.py +435 -435
  44. PaIRS_UniNa/ui_ResizePopup.py +203 -203
  45. PaIRS_UniNa/ui_Vis_Tab.py +1626 -1626
  46. PaIRS_UniNa/ui_Vis_Tab_CalVi.py +1249 -1249
  47. PaIRS_UniNa/ui_Whatsnew.py +131 -131
  48. PaIRS_UniNa/ui_gPairs.py +873 -867
  49. PaIRS_UniNa/ui_infoPaIRS.py +550 -550
  50. PaIRS_UniNa/whatsnew.txt +4 -4
  51. {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.8.dist-info}/METADATA +31 -17
  52. {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.8.dist-info}/RECORD +54 -48
  53. {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.8.dist-info}/WHEEL +0 -0
  54. {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.8.dist-info}/top_level.txt +0 -0
PaIRS_UniNa/Input_Tab.py CHANGED
@@ -1,719 +1,831 @@
1
1
  from .ui_Input_Tab import*
2
2
  from .Input_Tab_tools import*
3
3
  from .TabTools import*
4
-
5
- spin_tips={
6
- 'inp_cam': 'Current camera number (import tool)',
7
- 'inp_ncam': 'Number of cameras (import tool)',
8
- 'ind_in': 'First image number',
9
- 'npairs': 'Number of image pairs',
10
- 'step': 'Step of image pairs',
11
- 'img': 'Current image pair number',
12
- 'cam': 'Current camera number',
13
- 'ncam': 'Number of cameras',
14
- 'frame': 'Current frame number',
15
- }
16
- check_tips={
17
- 'TR_Import': 'Time-resolved sequence',
18
- }
19
- radio_tips={}
20
- line_edit_tips={
21
- 'path': 'Input folder path',
22
- }
23
- button_tips={
24
- 'data': 'Input data set',
25
- 'path': 'Input folder path',
26
- 'scan_path': 'Re-scan path',
27
- 'automatic_list': 'Automatic list setting',
28
- 'tool_CollapBox_ImSet': 'Open/Close image import tool',
29
- 'CollapBox_ImSet': 'Image import tool',
30
- 'automatic_frame': 'Automatic frame setting',
31
- 'example_list': 'Example list setting',
32
- 'import': 'Image set import',
33
- 'scan_list': 'Re-scan list',
34
- 'warning': 'Warning',
35
- 'cut_warnings': 'Cut items with warning',
36
- 'edit_list': 'Edit list',
37
- 'read_list': 'Read list image file',
38
- 'write_list': 'Write list image file',
39
- 'read': 'Read images from disk',
40
- 'sort': 'Sort images',
41
- 'sort_reversed': 'Reversly sort images',
42
- 'wrap_items': 'Expand items',
43
- 'unwrap_items': 'Collapse items',
44
- 'copy': 'Copy items',
45
- 'cut': 'Cut items',
46
- 'paste_below': 'Paste items below',
47
- 'paste_above': 'Paste items above',
48
- 'clean': 'Clean list',
49
- 'discard_changes': 'Discard changes',
50
- 'confirm_changes': 'Accept changes',
51
- 'up': 'Move to the top of the list',
52
- 'down': 'Move to the bottom of the list',
53
- }
54
- combo_tips={
55
- 'process': 'Type of process',
56
- 'frame_a': 'Pattern of pattern 1',
57
- 'frame_b': 'Pattern of pattern 2',
58
- }
59
-
60
- class INPpar(TABpar):
61
- class ImportPar(TABpar):
62
- def __init__(self,ncam=1):
63
- self.setup(ncam)
64
- self.OptionDone=0
65
- super().__init__('INPpar','Input')
66
-
67
- def setup(self,ncam=1):
68
- self.frame_1 = [-1]*ncam
69
- self.frame_2 = [-1]*ncam
70
- self.inp_ncam = ncam
71
- self.inp_cam = 1
72
- self.ind_in = 0
73
- self.npairs = 0
74
- self.step = 0
75
- self.FlagTR_Import = False
76
- self.FlagImport = True
77
-
78
- FlagAutoList = True
79
- FlagAutoFrame = True
80
- FlagExample = True
81
-
82
- def __init__(self,Process=ProcessTypes.null,Step=StepTypes.null):
83
- self.setup(Process,Step)
84
- super().__init__('INPpar','Input')
85
- self.importPar.copyfrom(self,exceptions=['name','surname'])
86
- self.unchecked_fields+=['FlagCam','OptionValidPath','FlagAutoList','FlagAutoFrame','FlagExample',
87
- 'inp_cam','nExImTree','exImTreeExp','FlagImport','importPar',
88
- 'selection','FlagDone','pathCompleter'] #'FlagCollapBox'
89
-
90
- def setup(self,Process,Step):
91
- self.Process = Process
92
- self.Step = Step
93
- self.FlagCam = False
94
-
95
- self.path = './'
96
- self.OptionValidPath = 1
97
-
98
- self.imSet = ImageSet()
99
-
100
- #self.FlagCollapBox = True
101
- self.frame_1 = [-1]
102
- self.frame_2 = [-1]
103
- self.inp_ncam = 3 if Process==ProcessTypes.tpiv else 2 if Process==ProcessTypes.spiv else 1
104
- self.inp_cam = 1
105
- self.ind_in = -1
106
- self.npairs = 0
107
- self.step = 1
108
- self.FlagTR_Import = False
109
-
110
- self.nExImTree = 3
111
- self.exImTreeExp = [False]*self.nExImTree
112
- self.exImList = [[[],[]]*self.inp_cam]
113
- self.exImEx = [[[],[]]*self.inp_cam]
114
-
115
- self.FlagImport = False
116
- self.importPar = self.ImportPar(self.inp_ncam)
117
-
118
- self.ncam = self.inp_ncam
119
- self.imList = [[[],[]] for _ in range(self.ncam)]
120
- self.imEx = [[[],[]] for _ in range(self.ncam)]
121
- self.nimg = 0
122
- self.selection = [0,0,0]
123
-
124
- self.FlagMIN = Step==StepTypes.min
125
- self.FlagTR = False
126
- self.LaserType = 0
127
- self.imListMin = [[[],[]] for _ in range(self.ncam)]
128
-
129
- self.FlagCAL = Process in ProcessTypes.threeCameras
130
- self.calList = []
131
- self.calEx = []
132
-
133
- #self.FlagDISP = Step==StepTypes.disp
134
- #self.dispFile = ''
135
-
136
- self.pathCompleter=basefold_DEBUGOptions
137
-
138
- class Input_Tab(gPaIRS_Tab):
139
- class Import_Tab_Signals(gPaIRS_Tab.Tab_Signals):
140
- pass
141
-
142
- def __init__(self,parent: QWidget =None, flagInit= __name__ == "__main__"):
143
- pri.Time.yellow('Input: init')
144
- super().__init__(parent,Ui_InputTab,INPpar)
145
- self.signals=self.Import_Tab_Signals(self)
146
- pri.Time.yellow('Input: ui')
147
-
148
- #------------------------------------- Graphical interface: widgets
149
- self.TABname='Input'
150
- self.ui: Ui_InputTab
151
- self.exImTree=self.ui.exImTree=GlobalImageTree(self,FlagNum=True)
152
- self.ui.g_ImSet_layout.insertWidget(2,self.exImTree)
153
- self.exImTree.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
154
- self.exImTree.setSelectionBehavior(QTreeWidget.SelectionBehavior.SelectRows)
155
- self.exImTree.setHeaderHidden(True)
156
-
157
- #necessary to change the name and the order of the items
158
- for g in list(globals()):
159
- if '_items' in g or '_ord' in g or '_tips' in g:
160
- #pri.Info.blue(f'Adding {g} to {self.name_tab}')
161
- setattr(self,g,eval(g))
162
-
163
- if __name__ == "__main__":
164
- self.app=app
165
- setAppGuiPalette(self)
166
-
167
- #------------------------------------- Graphical interface: miscellanea
168
- self.pixmap_x = QPixmap(''+ icons_path +'redx.png')
169
- self.pixmap_v = QPixmap(''+ icons_path +'greenv.png')
170
- self.pixmap_wait = QPixmap(''+ icons_path +'sandglass.png')
171
- self.pixmap_warn = QPixmap(u""+ icons_path +"warning.png")
172
-
173
- #------------------------------------- Declaration of parameters
174
- self.INPpar_base=INPpar()
175
- self.INPpar:INPpar=self.TABpar
176
- self.INPpar_old:INPpar=self.TABpar_old
177
-
178
- pri.Time.yellow('Input: setupWid and par')
179
-
180
- #------------------------------------- Callbacks
181
- self.defineWidgets()
182
- self.setupWid() #---------------- IMPORTANT
183
-
184
- self.defineCallbacks()
185
- self.connectCallbacks()
186
- self.defineFurtherCallbacks()
187
-
188
- self.defineSettings()
189
- self.TABsettings.append(self.image_list_set)
190
- #self.TABsettings.append(self.button_box_set)
191
-
192
- self.adjustTABpar=self.adjustINPpar
193
- self.setTABlayout=self.setINPlayout
194
- self.checkTABpar=lambda ind: self.checkINPpar(ind,FlagRescan=True)
195
- self.setTABwarn=self.setINPwarn
196
- self.disableTab=self.disableInputTab
197
-
198
- self.ImTreeInd=[]
199
- self.ui.imTreeWidget.imTree.signals.stopWorker.connect(self.emptyImTreeInd)
200
-
201
- self.FlagScanPath=False
202
- pri.Time.yellow('Input: define callbacks')
203
-
204
- #------------------------------------- Initializing
205
- if flagInit:
206
- self.initialize()
207
- #else:
208
- # self.setTABpar(FlagBridge=False)
209
-
210
- def defineFurtherCallbacks(self):
211
- self.ui.button_data.clicked.connect(lambda: downloadExampleData(self,'https://www.pairs.unina.it/web/PIV_data.zip'))
212
-
213
- #self.button_box_callback=self.wrappedCallback('Open/close Image import tool box',self.button_box_action)
214
- #self.ui.CollapBox_ImSet.toggle_button.clicked.connect(self.button_box_callback)
215
- self.ui.spin_inp_cam.valueChanged.connect(self.spin_inp_cam_callback)
216
- self.ui.spin_inp_cam.addfuncout={}
217
- itemExpansion_callback=self.wrappedCallback('Item expanded/collapsed',self.itemExpandedCollapsed)
218
- self.exImTree.itemExpanded.connect(itemExpansion_callback)
219
- self.exImTree.itemCollapsed.connect(itemExpansion_callback)
220
-
221
- self.image_list_callback=self.wrappedCallback('Image list change',self.image_list_action)
222
- self.ui.imTreeWidget.imTrees[0].signals.updateLists.connect(self.image_list_callback)
223
- #self.selection_callback=self.wrappedCallback('Image list change',self.selection_action)
224
- self.selection_callback=self.selection_action
225
- self.ui.imTreeWidget.spin_img.valueChanged.connect(self.selection_callback)
226
- self.ui.imTreeWidget.spin_cam.valueChanged.connect(self.selection_callback)
227
- self.ui.imTreeWidget.spin_frame.valueChanged.connect(self.selection_callback)
228
- self.ui.imTreeWidget.signals.selection.connect(self.selection_callback)
229
-
230
- def initialize(self):
231
- pri.Info.yellow(f'{"*"*20} INPUT initialization {"*"*20}')
4
+
5
+ spin_tips={
6
+ 'inp_cam': 'Current camera number (import tool)',
7
+ 'inp_ncam': 'Number of cameras (import tool)',
8
+ 'ind_in': 'First image number',
9
+ 'npairs': 'Number of image pairs',
10
+ 'step': 'Step of image pairs',
11
+ 'img': 'Current image pair number',
12
+ 'cam': 'Current camera number',
13
+ 'ncam': 'Number of cameras',
14
+ 'frame': 'Current frame number',
15
+ }
16
+ check_tips={
17
+ 'TR_Import': 'Time-resolved sequence',
18
+ }
19
+ radio_tips={}
20
+ line_edit_tips={
21
+ 'path': 'Input folder path',
22
+ }
23
+ button_tips={
24
+ 'data': 'Input data set',
25
+ 'path': 'Input folder path',
26
+ 'scan_path': 'Re-scan path',
27
+ 'automatic_list': 'Automatic list setting',
28
+ 'tool_CollapBox_ImSet': 'Open/Close image import tool',
29
+ 'CollapBox_ImSet': 'Image import tool',
30
+ 'automatic_frame': 'Automatic frame setting',
31
+ 'example_list': 'Example list setting',
32
+ 'import': 'Image set import',
33
+ 'scan_list': 'Re-scan list',
34
+ 'warning': 'Warning',
35
+ 'cut_warnings': 'Cut items with warning',
36
+ 'edit_list': 'Edit list',
37
+ 'read_list': 'Read list image file',
38
+ 'write_list': 'Write list image file',
39
+ 'read': 'Read images from disk',
40
+ 'sort': 'Sort images',
41
+ 'sort_reversed': 'Reversly sort images',
42
+ 'wrap_items': 'Expand items',
43
+ 'unwrap_items': 'Collapse items',
44
+ 'copy': 'Copy items',
45
+ 'cut': 'Cut items',
46
+ 'paste_below': 'Paste items below',
47
+ 'paste_above': 'Paste items above',
48
+ 'clean': 'Clean list',
49
+ 'discard_changes': 'Discard changes',
50
+ 'confirm_changes': 'Accept changes',
51
+ 'up': 'Move to the top of the list',
52
+ 'down': 'Move to the bottom of the list',
53
+ }
54
+ combo_tips={
55
+ 'process': 'Type of process',
56
+ 'frame_a': 'Pattern of pattern 1',
57
+ 'frame_b': 'Pattern of pattern 2',
58
+ }
59
+
60
+ class INPpar(TABpar):
61
+ class ImportPar(TABpar):
62
+ def __init__(self,ncam=1):
63
+ self.setup(ncam)
64
+ self.OptionDone=0
65
+ super().__init__('INPpar','Input')
66
+
67
+ def setup(self,ncam=1):
68
+ self.frame_1 = [-1]*ncam
69
+ self.frame_2 = [-1]*ncam
70
+ self.inp_ncam = ncam
71
+ self.inp_cam = 1
72
+ self.ind_in = 0
73
+ self.npairs = 0
74
+ self.step = 1
75
+ self.FlagTR_Import = False
76
+ self.FlagImport = True
77
+
78
+ FlagAutoList = True
79
+ FlagAutoFrame = True
80
+ FlagExample = True
81
+ pathCompleter = basefold_DEBUGOptions
82
+
83
+ def __init__(self,Process=ProcessTypes.null,Step=StepTypes.null):
84
+ self.setup(Process,Step)
85
+ super().__init__('INPpar','Input')
86
+ self.importPar.copyfrom(self,exceptions=['name','surname'])
87
+ self.unchecked_fields+=['FlagCam','OptionValidPath','FlagAutoList','FlagAutoFrame','FlagExample',
88
+ 'inp_cam','nExImTree','exImTreeExp','FlagImport','importPar',
89
+ 'selection','FlagDone','pathCompleter'] #'FlagCollapBox'
90
+
91
+ def setup(self,Process,Step):
92
+ self.Process = Process
93
+ self.Step = Step
94
+ self.FlagCam = False
95
+
96
+ self.path = './'
97
+ self.OptionValidPath = 1
98
+
99
+ self.imSet = ImageSet()
100
+
101
+ #self.FlagCollapBox = True
102
+ self.frame_1 = [-1]
103
+ self.frame_2 = [-1]
104
+ self.inp_ncam = 3 if Process==ProcessTypes.tpiv else 2 if Process==ProcessTypes.spiv else 1
105
+ self.inp_cam = 1
106
+ self.ind_in = 0
107
+ self.npairs = 0
108
+ self.step = 1
109
+ self.FlagTR_Import = False
110
+
111
+ self.nExImTree = 3
112
+ self.exImTreeExp = [False]*self.nExImTree
113
+ self.exImList = [[[],[]]*self.inp_cam]
114
+ self.exImEx = [[[],[]]*self.inp_cam]
115
+
116
+ self.FlagImport = False
117
+ self.importPar = self.ImportPar(self.inp_ncam)
118
+
119
+ self.ncam = self.inp_ncam
120
+ self.imList = [[[],[]] for _ in range(self.ncam)]
121
+ self.imEx = [[[],[]] for _ in range(self.ncam)]
122
+ self.nimg = 0
123
+ self.selection = [0,0,0]
124
+
125
+ self.FlagMIN = Step==StepTypes.min
126
+ self.FlagTR = False
127
+ self.LaserType = 0
128
+ self.imListMin = [[[],[]] for _ in range(self.ncam)]
129
+
130
+ self.FlagCAL = Process in ProcessTypes.threeCameras
131
+ self.calList = []
132
+ self.calEx = []
133
+
134
+ #self.FlagDISP = Step==StepTypes.disp
135
+ #self.dispFile = ''
136
+
137
+ class Input_Tab(gPaIRS_Tab):
138
+ class Import_Tab_Signals(gPaIRS_Tab.Tab_Signals):
139
+ tooltipRequested = Signal(str)
140
+ pass
141
+
142
+ def __init__(self,parent: QWidget =None, flagInit= __name__ == "__main__"):
143
+ pri.Time.yellow('Input: init')
144
+ super().__init__(parent,Ui_InputTab,INPpar)
145
+ self.signals=self.Import_Tab_Signals(self)
146
+ pri.Time.yellow('Input: ui')
147
+
148
+ #------------------------------------- Graphical interface: widgets
149
+ self.TABname='Input'
150
+ self.ui: Ui_InputTab
151
+ self.exImTree=self.ui.exImTree=GlobalImageTree(self,FlagNum=True)
152
+ self.exImTree.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
153
+ self.exImTree.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
154
+ self.exImTree.setSelectionBehavior(QTreeWidget.SelectionBehavior.SelectRows)
155
+ #self.exImTree.setHeaderHidden(True)
156
+ self.exImTree.header().setVisible(True)
157
+ self.hbarExImTree = QScrollBar(Qt.Horizontal)
158
+ self.hbarExImTree.setStyleSheet("""
159
+ QScrollBar::handle:horizontal {
160
+ min-width: 40px;
161
+ }
162
+ """)
163
+ self.exImTree.setVisible(True)
164
+ self.hbarExImTree.setVisible(True)
165
+ # Sync ranges and values
166
+ origHbar = self.exImTree.horizontalScrollBar()
167
+ origHbar.rangeChanged.connect(self.hbarExImTree.setRange)
168
+ origHbar.valueChanged.connect(self.hbarExImTree.setValue)
169
+ self.hbarExImTree.valueChanged.connect(origHbar.setValue)
170
+ # Layout
171
+ self.containerExImTree = QWidget()
172
+ layoutExImTree = QVBoxLayout(self.containerExImTree)
173
+ layoutExImTree.setContentsMargins(0,0,0,0)
174
+ layoutExImTree.setSpacing(0)
175
+ layoutExImTree.addWidget(self.exImTree)
176
+ layoutExImTree.addWidget(self.hbarExImTree)
177
+ self.ui.g_ImSet_layout.insertWidget(2,self.containerExImTree)
178
+
179
+ #necessary to change the name and the order of the items
180
+ for g in list(globals()):
181
+ if '_items' in g or '_ord' in g or '_tips' in g:
182
+ #pri.Info.blue(f'Adding {g} to {self.name_tab}')
183
+ setattr(self,g,eval(g))
184
+
185
+ if __name__ == "__main__":
186
+ self.app=app
187
+ setAppGuiPalette(self)
188
+
189
+ #------------------------------------- Graphical interface: miscellanea
190
+ self.pixmap_x = QPixmap(''+ icons_path +'redx.png')
191
+ self.pixmap_v = QPixmap(''+ icons_path +'greenv.png')
192
+ self.pixmap_wait = QPixmap(''+ icons_path +'sandglass.png')
193
+ self.pixmap_warn = QPixmap(u""+ icons_path +"warning.png")
194
+
195
+ self.signals.tooltipRequested.connect(self.show_import_tooltip)
196
+
197
+ #------------------------------------- Declaration of parameters
198
+ self.INPpar_base=INPpar()
199
+ self.INPpar:INPpar=self.TABpar
200
+ self.INPpar_old:INPpar=self.TABpar_old
201
+
202
+ pri.Time.yellow('Input: setupWid and par')
203
+
204
+ #------------------------------------- Callbacks
205
+ self.defineWidgets()
206
+ self.setupWid() #---------------- IMPORTANT
207
+
208
+ self.defineCallbacks()
209
+ self.connectCallbacks()
210
+ self.defineFurtherCallbacks()
211
+
212
+ self.defineSettings()
213
+ self.TABsettings.append(self.image_list_set)
214
+ #self.TABsettings.append(self.button_box_set)
215
+
216
+ self.adjustTABpar=self.adjustINPpar
217
+ self.setTABlayout=self.setINPlayout
218
+ self.checkTABpar=lambda ind: self.checkINPpar(ind,FlagRescan=True)
219
+ self.setTABwarn=self.setINPwarn
220
+ self.disableTab=self.disableInputTab
221
+
222
+ self.ImTreeInd=[]
223
+ self.ui.imTreeWidget.imTree.signals.stopWorker.connect(self.emptyImTreeInd)
224
+ self.ui.imTreeWidget.FlagInGui=True
225
+
226
+ self.FlagScanPath=False
227
+ pri.Time.yellow('Input: define callbacks')
228
+
229
+ #------------------------------------- Initializing
230
+ if flagInit:
231
+ self.initialize()
232
+ #else:
233
+ # self.setTABpar(FlagBridge=False)
234
+
235
+ def defineFurtherCallbacks(self):
236
+ self.ui.button_data.clicked.connect(lambda: downloadExampleData(self,'https://www.pairs.unina.it/web/PIV_data.zip'))
237
+
238
+ #self.button_box_callback=self.wrappedCallback('Open/close Image import tool box',self.button_box_action)
239
+ #self.ui.CollapBox_ImSet.toggle_button.clicked.connect(self.button_box_callback)
240
+ self.ui.spin_inp_cam.valueChanged.connect(self.spin_inp_cam_callback)
241
+ self.ui.spin_inp_cam.addfuncout={}
242
+ itemExpansion_callback=self.wrappedCallback('Item expanded/collapsed',self.itemExpandedCollapsed)
243
+ self.exImTree.itemExpanded.connect(itemExpansion_callback)
244
+ self.exImTree.itemCollapsed.connect(itemExpansion_callback)
245
+
246
+ self.image_list_callback=self.wrappedCallback('Image list change',self.image_list_action)
247
+ self.ui.imTreeWidget.imTrees[0].signals.updateLists.connect(self.image_list_callback)
248
+ #self.selection_callback=self.wrappedCallback('Image list change',self.selection_action)
249
+ self.selection_callback=self.selection_action
250
+ self.ui.imTreeWidget.spin_img.valueChanged.connect(self.selection_callback)
251
+ self.ui.imTreeWidget.spin_cam.valueChanged.connect(self.selection_callback)
252
+ self.ui.imTreeWidget.spin_frame.valueChanged.connect(self.selection_callback)
253
+ self.ui.imTreeWidget.signals.selection.connect(self.selection_callback)
254
+
255
+ def initialize(self):
256
+ pri.Info.yellow(f'{"*"*20} INPUT initialization {"*"*20}')
232
257
  from .PaIRS_pypacks import basefold
233
- #self.ui.imTreeWidget.nullList()
234
- self.INPpar.Process=ProcessTypes.piv
235
- self.INPpar.path=basefold_DEBUG if __name__ == "__main__" else basefold
236
- self.INPpar.imSet.path=self.INPpar.path
237
- #self.cleanPrevs(self.INPpar.ind,FlagAllPrev=True)
238
- self.ui.line_edit_path.setText(self.INPpar.path)
239
- self.line_edit_path_callback()
240
-
241
- #*************************************************** Adjusting parameters
242
- def adjustINPpar(self):
243
- self.INPpar.FlagCam=self.INPpar.Process in ProcessTypes.threeCameras
244
- if not self.INPpar.FlagCam:
245
- self.INPpar.inp_ncam=self.INPpar.ncam=self.ncamMinimum()
246
- else:
247
- self.INPpar.inp_ncam=self.INPpar.ncam=max([self.INPpar.inp_ncam,self.ncamMinimum()])
248
- self.INPpar.inp_cam=min([self.INPpar.inp_cam,self.INPpar.inp_ncam])
249
- if self.INPpar.inp_ncam<self.INPpar_old.inp_ncam:
250
- del self.INPpar.frame_1[self.INPpar.inp_ncam:]
251
- del self.INPpar.frame_2[self.INPpar.inp_ncam:]
252
- elif self.INPpar.inp_ncam>self.INPpar_old.inp_ncam:
253
- frame_1,frame_2=self.automaticFrames()
254
- self.INPpar.frame_1[self.INPpar_old.inp_ncam:self.INPpar.inp_ncam]=frame_1[self.INPpar_old.inp_ncam:self.INPpar.inp_ncam]
255
- self.INPpar.frame_2[self.INPpar_old.inp_ncam:self.INPpar.inp_ncam]=frame_2[self.INPpar_old.inp_ncam:self.INPpar.inp_ncam]
256
- if len(self.INPpar.frame_1)<self.INPpar.inp_ncam:
257
- self.INPpar.frame_1+=[self.INPpar.frame_1[0]]*(self.INPpar.inp_ncam-len(self.INPpar.frame_1))
258
- self.INPpar.frame_2+=[self.INPpar.frame_2[0]]*(self.INPpar.inp_ncam-len(self.INPpar.frame_2))
259
- #if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['path']):
260
-
261
- self.INPpar.path=myStandardPath(self.INPpar.path)
262
- self.INPpar.nimg=0
263
- if len(self.INPpar.imList[0]):
264
- if len(self.INPpar.imList[0][0]):
265
- self.INPpar.nimg=len(self.INPpar.imList[0][0])
266
- self.checkINPpar(FlagRescan=True)
267
- if not self.INPpar.OptionValidPath or not self.INPpar.imSet.count: INPpar.FlagExample=False
268
- self.adjustExampleImageList()
269
- self.INPpar.FlagImport=self.INPpar.importPar.FlagImport and self.INPpar.importPar.isEqualTo(self.INPpar,exceptions=['name','surname','FlagImport','ind'])
270
-
271
- #self.INPpar.importPar.printDifferences(self.INPpar,exceptions=['name','surname','FlagImport','ind'],FlagStrictDiff=True)
272
- return
273
-
274
- def checkINPpar(self,ind=None,FlagRescan=False): #FlagRescan=False):
275
- if ind is None: INP:INPpar=self.INPpar
276
- else: INP:INPpar=self.TABpar_at(ind)
277
- self.setOptionValidPath(ind)
278
- FlagWarn=INP.OptionValidPath==0
279
- if not INP.FlagInit or FlagRescan:
280
- self.scanImList(ind)
281
- if not FlagWarn:
282
- for imExc in INP.imEx:
283
- for imExf in imExc:
284
- for ex in imExf:
285
- if not ex:
286
- FlagWarn=True
287
- break
288
- INP.OptionDone=1 if (len(INP.imList[0][0])>0 and not FlagWarn) else 0 #-1 if len(INP.imList[0][0])>0 else 0
289
-
290
- def scanImList(self,ind=None):
291
- if ind: INP:INPpar=self.TABpar_at(ind)
292
- else: INP:INPpar=self.INPpar
293
- for c in range(len(INP.imList)): #INP.ncam
294
- for f in range(2):
295
- for k in range(len(INP.imList[0][0])): #INP.nimg
296
- #ex=INP.imEx[c][f][k]
297
- INP.imEx[c][f][k]=os.path.exists(INP.path+INP.imList[c][f][k]) if INP.imList[c][f][k] else False
298
-
299
- #*************************************************** Layout
300
- def setINPlayout(self):
301
- self.ui.label_process.setVisible(__name__ == "__main__")
302
- self.ui.combo_process.setVisible(__name__ == "__main__")
303
- self.setPathLabel()
304
- self.setPathCompleter()
305
-
306
- self.ui.g_ImSet.setEnabled(self.INPpar.OptionValidPath and self.INPpar.imSet.count)
307
- #if self.INPpar.imSet.isDifferentFrom(self.INPpar_old.imSet,fields=['pattern']):
308
- self.ui.combo_frame_a.clear()
309
- self.ui.combo_frame_a.addItems(self.INPpar.imSet.pattern)
310
- self.ui.combo_frame_b.clear()
311
- self.ui.combo_frame_b.addItems(['-']+self.INPpar.imSet.pattern)
312
-
313
- self.ui.spin_inp_ncam.setEnabled(self.INPpar.FlagCam)
314
- self.ui.spin_inp_ncam.setMinimum(self.ncamMinimum())
315
- self.ui.imTreeWidget.spin_ncam.setEnabled(self.INPpar.FlagCam)
316
- self.ui.imTreeWidget.FlagCam=self.INPpar.FlagCam
317
- self.ui.imTreeWidget.spin_ncam.setMinimum(self.ncamMinimum())
318
- self.ui.imTreeWidget.spin_ncam.setValue(self.INPpar.ncam)
319
- self.ui.spin_inp_cam.setEnabled(self.INPpar.inp_ncam>1)
320
- self.ui.spin_inp_cam.setMaximum(self.INPpar.inp_ncam)
321
- self.setImageNumberSpinLimits()
322
- self.exImTree.setVisible(INPpar.FlagExample)
323
- self.layoutExampleImageList()
324
- self.ui.button_import.setEnabled(not self.INPpar.FlagImport)
325
-
326
- """
327
- if self.INPpar.ind[-1]<len(self.TABpar_prev_at(self.INPpar.ind))-1:
328
- self.ui.imTreeWidget.w_button.setVisible(False)
329
- else:
330
- self.ui.imTreeWidget.w_button.setVisible(True)
331
- """
332
-
333
- self.checkINPpar(FlagRescan=False)
334
- self.setINPwarn()
335
- self.setTABWarnLabel()
336
- return
337
-
338
- def setINPwarn(self,ind=None):
339
- if ind is None: INP:INPpar=self.INPpar
340
- else: INP:INPpar=self.TABpar_at(ind)
341
- if INP.OptionDone==1:
342
- INP.warningMessage='Input image files correctly identified!'
343
- else:
344
- FlagWarn=False
345
- for imExc in INP.imEx:
346
- for imExf in imExc:
347
- for ex in imExf:
348
- if not ex:
349
- FlagWarn=True
350
- break
351
- if INP.OptionValidPath==0:
352
- INP.warningMessage='Invalid input path!'
353
- elif len(INP.imList[0][0])==0:
354
- INP.warningMessage='Image set empty!'
355
- elif FlagWarn:
356
- INP.warningMessage='Some image files missing!'
357
- else:
358
- INP.warningMessage='Issues with identifying input image files!'
359
-
360
- def ncamMinimum(self):
361
- return 3 if self.INPpar.Process==ProcessTypes.tpiv else 2 if self.INPpar.Process==ProcessTypes.spiv else 1
362
-
363
- def disableInputTab(self,flag):
364
- self.setEnabled(not flag)
365
-
366
- #*************************************************** Mode
367
- #******************** Actions
368
- def combo_process_action(self):
369
- current_ind=self.ui.combo_process.currentIndex()
370
- self.INPpar.Process=list(process)[current_ind]
371
- if self.INPpar.Process in ProcessTypes.threeCameras:
372
- self.INPpar.ncam=self.INPpar.inp_ncam=max([self.INPpar.ncam,self.ncamMinimum()])
373
- else:
374
- self.INPpar.ncam=self.INPpar.inp_ncam=self.ncamMinimum()
375
-
376
- if INPpar.FlagAutoList:
377
- self.button_scan_path_action()
378
- else:
379
- self.ui.imTreeWidget.spin_ncam.setMinimum(self.ncamMinimum())
380
- self.ui.imTreeWidget.spin_ncam.setValue(self.INPpar.ncam)
381
- self.INPpar.imList=self.ui.imTreeWidget.imTree.imList
382
- self.INPpar.imEx=self.ui.imTreeWidget.imTree.imEx
383
- self.ui.imTreeWidget.spin_ncam_action()
384
- return
385
-
386
- #******************** Set
387
- def combo_process_set(self):
388
- current_proc=process[self.INPpar.Process]
389
- self.ui.combo_process.setCurrentIndex(process_items.index(current_proc))
390
-
391
- #*************************************************** Path
392
- #******************** Actions
393
- def line_edit_path_changing(self):
394
- self.ui.label_check_path.setPixmap(QPixmap())
395
-
396
- def line_edit_path_preaction(self):
397
- currpath=myStandardPath(self.ui.line_edit_path.text())
398
- self.FlagScanPath=os.path.normpath(self.INPpar.path)!=currpath
399
- directory_path = myStandardPath(os.getcwd())
400
- if directory_path in currpath:
401
- currpath=currpath.replace(directory_path,'./')
402
- if os.path.exists(currpath):
403
- if currpath in self.INPpar.pathCompleter: self.INPpar.pathCompleter.remove(currpath)
404
- self.INPpar.pathCompleter.insert(0,currpath)
405
- if len(self.INPpar.pathCompleter)>10: self.INPpar.pathCompleter=self.INPpar.pathCompleter[:10]
406
- self.ui.line_edit_path.setText(currpath)
407
-
408
- def line_edit_path_action_future(self):
409
- if self.FlagScanPath:
410
- self.button_scan_path_action()
411
-
412
- def button_path_action(self):
413
- directory = str(QFileDialog.getExistingDirectory(self,\
414
- "Choose an input folder", dir=self.INPpar.path,options=optionNativeDialog))
415
- currpath='{}'.format(directory)
416
- if not currpath=='':
417
- currpath=myStandardPath(currpath)
418
- self.ui.line_edit_path.setText(currpath)
419
- self.INPpar.path=self.ui.line_edit_path.text()
420
- self.line_edit_path_preaction()
421
-
422
- def button_path_action_future(self):
423
- self.line_edit_path_action_future()
424
-
425
- def button_scan_path_action(self):
426
- self.INPpar.imSet.scanPath(self.INPpar.path)
427
- if self.INPpar.imSet.count:
428
- self.INPpar.frame_1[0]=0
429
- self.INPpar.frame_1,self.INPpar.frame_2=self.automaticFrames()
430
- else:
431
- self.INPpar.frame_1=[-1]*self.INPpar.inp_ncam
432
- self.INPpar.frame_2=[-1]*self.INPpar.inp_ncam
433
- self.INPpar.ind_in, _, self.INPpar.npairs, _= self.getIndNpairs()
434
- self.INPpar.step=1 if self.INPpar.npairs else 0
435
- if INPpar.FlagAutoList:
436
- self.button_import_action()
437
- else:
438
- self.ui.imTreeWidget.imTree.path=self.INPpar.path
439
- self.ui.imTreeWidget.imTree.scanLists()
440
- self.INPpar.imEx=self.ui.imTreeWidget.imTree.imEx
441
-
442
- def automaticFrames(self):
443
- cam=self.INPpar.inp_cam-1
444
- if not self.INPpar.imSet.nimg:
445
- return self.INPpar.frame_1,self.INPpar.frame_2
446
- f1=self.INPpar.frame_1[cam]
447
- link1=self.INPpar.imSet.link[f1]
448
- nlink1=len(link1)
449
- frame_1=[f1]*self.INPpar.inp_ncam
450
- frame_2=[f1+1]*self.INPpar.inp_ncam
451
- frame_2[0]=link1[0]+1 if link1[0]!=f1 else 0
452
- for c in range(1,self.INPpar.inp_ncam):
453
- flagValid=c<nlink1-1
454
- frame_1[c]=f1c=link1[c] if flagValid else -1
455
- frame_2[c]=self.INPpar.imSet.link[f1c][0]+1 if flagValid else -1
456
- if cam:
457
- frame_1=frame_1[-cam:]+frame_1[:-cam]
458
- frame_2=frame_2[-cam:]+frame_2[:-cam]
459
- return frame_1, frame_2
460
-
461
- def button_automatic_list_action(self):
462
- INPpar.FlagAutoList=self.ui.button_automatic_list.isChecked()
463
- return True
464
-
465
- #******************** Settings
466
- def setOptionValidPath(self,ind=None):
467
- if ind is None: INP:INPpar=self.INPpar
468
- else: INP:INPpar=self.TABpar_at(ind)
469
- INP.OptionValidPath=int(os.path.exists(INP.path))
470
- return
471
-
472
- def setPathCompleter(self):
473
- self.edit_path_completer=QCompleter(self.INPpar.pathCompleter)
474
- self.edit_path_completer.setCompletionMode(QCompleter.CompletionMode(1))
475
- self.edit_path_completer.setModelSorting(QCompleter.ModelSorting(2))
476
- self.edit_path_completer.setWidget(self.ui.line_edit_path)
477
- if self.INPpar.path in self.INPpar.pathCompleter:
478
- k=self.INPpar.pathCompleter.index(self.INPpar.path)
479
- self.edit_path_completer.setCurrentRow(k)
480
- self.ui.line_edit_path.setCompleter(self.edit_path_completer)
481
- self.ui.line_edit_path.FlagCompleter=True
482
-
483
- def button_automatic_list_set(self):
484
- self.ui.button_automatic_list.setChecked(INPpar.FlagAutoList)
485
-
486
- #******************** Layout
487
- def setPathLabel(self):
488
- #Clickable label: no need for setStatusTip
489
- if self.INPpar.OptionValidPath==1:
490
- self.ui.label_check_path.setPixmap(self.pixmap_v)
491
- self.ui.label_check_path.setToolTip("The specified path of the input folder exists!")
492
- elif self.INPpar.OptionValidPath==0:
493
- self.ui.label_check_path.setPixmap(self.pixmap_x)
494
- self.ui.label_check_path.setToolTip("The specified path of the input folder does not exist!")
495
- elif self.INPpar.OptionValidPath==-10:
496
- self.ui.label_check_path.setPixmap(self.pixmap_wait)
497
- self.ui.label_check_path.setToolTip("The specified path of the input folder is currently under inspection!")
498
-
499
- #*************************************************** Image import tool
500
- #******************** Actions
501
- """
502
- def button_box_action(self):
503
- self.INPpar.FlagCollapBox=self.ui.CollapBox_ImSet.toggle_button.isChecked()
504
- return True
505
- """
506
-
507
- def button_automatic_frame_action(self):
508
- INPpar.FlagAutoFrame=self.ui.button_automatic_frame.isChecked()
509
- return True
510
-
511
- def combo_frame_a_action(self):
512
- self.INPpar.frame_1[self.INPpar.inp_cam-1]=self.ui.combo_frame_a.currentIndex()
513
- if INPpar.FlagAutoFrame:
514
- self.INPpar.frame_1,self.INPpar.frame_2=self.automaticFrames()
515
- self.INPpar.ind_in, _, self.INPpar.npairs, _= self.getIndNpairs()
516
-
517
- def combo_frame_b_action(self):
518
- self.INPpar.frame_2[self.INPpar.inp_cam-1]=self.ui.combo_frame_b.currentIndex()
519
-
520
- def button_example_list_action(self):
521
- INPpar.FlagExample=self.ui.button_example_list.isChecked()
522
- self.exImTree.setVisible(INPpar.FlagExample)
523
- return True
524
-
525
- def spin_inp_cam_action(self):
526
- if INPpar.FlagExample:
527
- items=[self.exImTree.topLevelItem(0)] if not self.exImTree.selectedItems() else self.exImTree.selectedItems()
528
- self.exImTree.clearSelection()
529
- for item in items:
530
- if item.parent(): item=item.parent()
531
- if self.INPpar.inp_cam-1:
532
- if not item.isExpanded():
533
- self.INPpar.exImTreeExp[self.exImTree.indexOfTopLevelItem(item)]=True
534
- item=item.child(self.INPpar.inp_cam-2)
535
- item.setSelected(True)
536
-
537
- def button_import_action(self):
538
- INPpar.FlagExample=False
539
- self.INPpar.imList,self.INPpar.imEx=self.INPpar.imSet.genListsFromFrame(self.INPpar.frame_1,self.INPpar.frame_2,self.INPpar.ind_in,self.INPpar.npairs,self.INPpar.step,self.INPpar.FlagTR_Import)
540
- self.INPpar.selection=[1,1,1]
541
- self.InputAdjustSelection()
542
- if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['imList','imEx']):
543
- self.INPpar.FlagImport=True
544
- self.INPpar.importPar.copyfrom(self.INPpar,exceptions=['name','surname'])
545
- self.ui.CollapBox_ImSet.toggle_button.click()
546
- self.ui.imTreeWidget.setFocus()
547
-
548
- #******************** Settings
549
- """
550
- def button_box_set(self):
551
- if self.INPpar.FlagCollapBox:
552
- self.ui.CollapBox_ImSet.openBox()
553
- else:
554
- self.ui.CollapBox_ImSet.closeBox()
555
- """
556
-
557
- def button_automatic_frame_set(self):
558
- self.ui.button_automatic_frame.setChecked(INPpar.FlagAutoFrame)
559
-
560
- def combo_frame_a_set(self):
561
- i=self.INPpar.frame_1[self.INPpar.inp_cam-1]
562
- self.ui.combo_frame_a.setCurrentIndex(i)
563
-
564
- def combo_frame_b_set(self):
565
- i=self.INPpar.frame_2[self.INPpar.inp_cam-1]
566
- self.ui.combo_frame_b.setCurrentIndex(i)
567
-
568
- def button_example_list_set(self):
569
- self.ui.button_example_list.setChecked(INPpar.FlagExample)
570
-
571
- #******************** Layout & Adjustments
572
- def setImageNumberSpinLimits(self):
573
- if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['imSet','frame_1','frame_2','inp_ncam','FlagTR_Import']):
574
- ind_in, ind_fin, npairs, npairs_max= self.getIndNpairs()
575
- self.INPpar.ind_in=min([max([ind_in,self.INPpar.ind_in]),ind_fin])
576
- self.INPpar.npairs=npairs if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['FlagTR_Import']) else min([self.INPpar.npairs,npairs])
577
- self.INPpar.step=min([self.INPpar.step,npairs])
578
-
579
- self.ui.spin_ind_in.setMinimum(ind_in)
580
- self.ui.spin_ind_in.setMaximum(ind_fin)
581
- s_ind_in=formatNumber(self.ui.spin_ind_in,ind_in)
582
- s_ind_fin=formatNumber(self.ui.spin_ind_in,ind_fin)
583
- self.ui.spin_ind_in.setToolTip(f'Number of the first image in the sequence to process. Min.: {s_ind_in}, max: {s_ind_fin}')
584
- self.ui.spin_ind_in.setStatusTip(self.ui.spin_ind_in.toolTip())
585
-
586
- self.ui.spin_npairs.setMinimum(0)
587
- self.ui.spin_npairs.setMaximum(npairs_max)
588
- self.ui.spin_npairs.setToolTip(f'Number of image pairs to process. Max: {npairs_max}')
589
- self.ui.spin_npairs.setStatusTip(self.ui.spin_npairs.toolTip())
590
-
591
- self.ui.spin_step.setMinimum(1)
592
- self.ui.spin_step.setMaximum(npairs_max)
593
- #ind_in=self.INPpar.imSet.ind_in[self.INPpar.frame_a]
594
- pass
595
-
596
- def getIndNpairs(self):
597
- if self.INPpar.imSet.count:
598
- l=[self.INPpar.imSet.ind_in[f] for f in self.INPpar.frame_1 if f>-1]
599
- ind_in_1=min(l) if l else None
600
- l=[self.INPpar.imSet.ind_in[f-1] for f in self.INPpar.frame_2 if f>0]
601
- ind_in_2=min(l) if l else ind_in_1 if ind_in_1 is not None else None
602
- ind_in=min([ind_in_1,ind_in_2]) if ind_in_2 is not None else 0
603
-
604
- l=[self.INPpar.imSet.ind_fin[f] for f in self.INPpar.frame_1 if f>-1]
605
- ind_fin_1=max(l) if l else None
606
- l=[self.INPpar.imSet.ind_fin[f-1] for f in self.INPpar.frame_2 if f>0]
607
- ind_fin_2=max(l) if l else ind_fin_1 if ind_fin_1 is not None else None
608
- ind_fin=min([ind_fin_1,ind_fin_2]) if ind_fin_2 is not None else -1
609
- else:
610
- ind_in=ind_in_2=0
611
- ind_fin=-1
612
- npairs=nimg=ind_fin-ind_in+1
613
- if not all(self.INPpar.frame_2):
614
- npairs=int(npairs/2)
615
- if self.INPpar.FlagTR_Import:
616
- npairs=2*npairs-1+nimg%2 #(1+int(any(self.INPpar.frame_2)))*npairs-1
617
- if npairs==0: ind_in=ind_fin=0
618
- npairs_max=npairs
619
- return ind_in, ind_fin, npairs, npairs_max
620
-
621
- def adjustExampleImageList(self):
622
- exImListPar=['path','frame_1','frame_2','inp_ncam','ind_in','npairs','step','FlagTR_Import']
623
- if self.INPpar.isDifferentFrom(self.INPpar_old,fields=exImListPar):
624
- #self.INPpar_old.printDifferences(self.INPpar,fields=exImListPar)
625
- self.INPpar.exImList,self.INPpar.exImEx=self.INPpar.imSet.genListsFromFrame(self.INPpar.frame_1,self.INPpar.frame_2,self.INPpar.ind_in,min([self.INPpar.npairs,self.INPpar.nExImTree]),self.INPpar.step,self.INPpar.FlagTR_Import)
626
-
627
- def layoutExampleImageList(self):
628
- if self.exImTree.imEx!=self.INPpar.exImEx or self.exImTree.imList!=self.INPpar.exImList:
629
- self.exImTree.imList=self.INPpar.exImList
630
- self.exImTree.imEx=self.INPpar.exImEx
631
- self.exImTree.ncam=self.INPpar.ncam
632
- self.exImTree.setImListEx()
633
- self.exImTree.path=self.INPpar.path
634
- self.exImTree.ncam=self.INPpar.inp_ncam
635
- self.exImTree.setLists(FlagAsync=False)
636
- self.exImTree.resizeColumnToContents(2)
637
- if self.INPpar.inp_ncam==1: self.INPpar.exImTreeExp=[False]*3
638
- height=self.exImTree.header().height()+5
639
- #itemHeight=20
640
- #height=itemHeight+5
641
- for i in range(3):
642
- item = self.exImTree.topLevelItem(i)
643
- if not item: continue
644
- item.setExpanded(self.INPpar.exImTreeExp[i])
645
- height+=self.exImTree.visualItemRect(item).height()
646
- for c in range(item.childCount()):
647
- height+=self.exImTree.visualItemRect(item.child(c)).height()
648
- #if self.INPpar.exImTreeExp[i]:
649
- # height+=item.childCount()*itemHeight
650
- #else: height+=itemHeight
651
- self.exImTree.setMinimumHeight(height)
652
- self.exImTree.setMaximumHeight(height)
653
- self.exImTree.verticalScrollBar().setMinimumHeight(height)
654
- self.exImTree.verticalScrollBar().setMaximumHeight(height)
655
- self.ui.CollapBox_ImSet.heightArea=height+110 if INPpar.FlagExample else 110
656
- self.ui.CollapBox_ImSet.heightOpened=self.ui.CollapBox_ImSet.heightArea+20
657
- self.ui.CollapBox_ImSet.on_click()
658
-
659
- def itemExpandedCollapsed(self):
660
- for i in range(self.exImTree.topLevelItemCount()):
661
- item = self.exImTree.topLevelItem(i)
662
- self.INPpar.exImTreeExp[i]=item.isExpanded()
663
- self.layoutExampleImageList()
664
- return True
665
-
666
- #*************************************************** Image import tool
667
- #******************** Actions
668
- def image_list_action(self):
669
- self.INPpar.imList=self.ui.imTreeWidget.imTree.imList
670
- self.INPpar.imEx=self.ui.imTreeWidget.imTree.imEx
671
- FlagDifferent=self.INPpar.isDifferentFrom(self.INPpar_old,fields=['imList'])
672
- self.INPpar.FlagImport=False
673
- return not FlagDifferent
674
-
675
- def selection_action(self):
676
- if QApplication.keyboardModifiers(): return
677
- w=self.ui.imTreeWidget
678
- if w.imTree.FlagSetting: return
679
- self.INPpar.selection=[w.spin_img.value(),w.spin_cam.value(),w.spin_frame.value()]
680
- self.InputAdjustSelection()
681
- if not TABpar.FlagSettingPar and not self.FlagSettingPar:
682
- FlagAdjustPar=True
683
- self.setTABpar_bridge(FlagAdjustPar,FlagCallback=True)
684
- return True
685
-
686
- def InputAdjustSelection(self,INP:INPpar=None):
687
- if INP is None: INP=self.INPpar
688
- if len(self.TABpar_prev_at(INP.ind)):
689
- self.TABpar_at(INP.ind).selection=copy.deepcopy(INP.selection)
690
-
691
- #******************** Settings
692
- def image_list_set(self):
693
- FlagNewLists=self.INPpar.isDifferentFrom(self.ui.imTreeWidget.imTree,fields=['imList','imEx'])
694
- if FlagNewLists and (not self.ImTreeInd or self.ImTreeInd!=self.INPpar.ind) and (self.ui.imTreeWidget.imTree.itemWorker is None or self.INPpar.ind!=self.INPpar_old.ind):
695
- self.ImTreeInd=copy.deepcopy(self.INPpar.ind)
696
- self.ui.imTreeWidget.imTree.signals.updateLists.disconnect()
697
- self.ui.imTreeWidget.imTree.signals.updateLists.connect(self.restoreSignal)
698
- self.ui.imTreeWidget.setLists(self.INPpar.path,self.INPpar.imList,self.INPpar.imEx,selection=self.INPpar.selection,FlagOnlyPrepare=not FlagNewLists)
699
- if not FlagNewLists: self.restoreSignal()
700
- self.ui.imTreeWidget.imTree.spinSelection(self.INPpar.selection)
701
-
702
- def emptyImTreeInd(self):
703
- self.ImTreeInd=[]
704
-
705
- @Slot()
706
- def restoreSignal(self):
707
- self.ui.imTreeWidget.imTree.signals.updateLists.disconnect()
708
- self.ui.imTreeWidget.imTree.signals.updateLists.connect(self.image_list_callback)
709
-
710
- if __name__ == "__main__":
711
- import sys
712
- app=QApplication.instance()
713
- if not app:app = QApplication(sys.argv)
714
- app.setStyle('Fusion')
715
- object = Input_Tab(None)
716
- object.show()
717
- app.exec()
718
- app.quit()
258
+ #self.ui.imTreeWidget.nullList()
259
+ self.INPpar.Process=ProcessTypes.piv
260
+ self.INPpar.path=basefold_DEBUG if __name__ == "__main__" else basefold
261
+ self.INPpar.imSet.path=self.INPpar.path
262
+ #self.cleanPrevs(self.INPpar.ind,FlagAllPrev=True)
263
+ self.ui.line_edit_path.setText(self.INPpar.path)
264
+ self.line_edit_path_callback()
265
+
266
+ #*************************************************** Adjusting parameters
267
+ def adjustINPpar(self):
268
+ self.INPpar.FlagCam=self.INPpar.Process in ProcessTypes.threeCameras
269
+ if not self.INPpar.FlagCam:
270
+ self.INPpar.inp_ncam=self.INPpar.ncam=self.ncamMinimum()
271
+ else:
272
+ self.INPpar.inp_ncam=self.INPpar.ncam=max([self.INPpar.inp_ncam,self.ncamMinimum()])
273
+ self.INPpar.inp_cam=min([self.INPpar.inp_cam,self.INPpar.inp_ncam])
274
+ if self.INPpar.inp_ncam<self.INPpar_old.inp_ncam:
275
+ del self.INPpar.frame_1[self.INPpar.inp_ncam:]
276
+ del self.INPpar.frame_2[self.INPpar.inp_ncam:]
277
+ elif self.INPpar.inp_ncam>self.INPpar_old.inp_ncam:
278
+ frame_1,frame_2=self.automaticFrames()
279
+ self.INPpar.frame_1[self.INPpar_old.inp_ncam:self.INPpar.inp_ncam]=frame_1[self.INPpar_old.inp_ncam:self.INPpar.inp_ncam]
280
+ self.INPpar.frame_2[self.INPpar_old.inp_ncam:self.INPpar.inp_ncam]=frame_2[self.INPpar_old.inp_ncam:self.INPpar.inp_ncam]
281
+ if len(self.INPpar.frame_1)<self.INPpar.inp_ncam:
282
+ self.INPpar.frame_1+=[self.INPpar.frame_1[0]]*(self.INPpar.inp_ncam-len(self.INPpar.frame_1))
283
+ self.INPpar.frame_2+=[self.INPpar.frame_2[0]]*(self.INPpar.inp_ncam-len(self.INPpar.frame_2))
284
+ #if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['path']):
285
+
286
+ self.INPpar.path=myStandardPath(self.INPpar.path)
287
+ self.INPpar.nimg=0
288
+ if len(self.INPpar.imList[0]):
289
+ if len(self.INPpar.imList[0][0]):
290
+ self.INPpar.nimg=len(self.INPpar.imList[0][0])
291
+ self.checkINPpar(FlagRescan=True)
292
+ if not self.INPpar.OptionValidPath or not self.INPpar.imSet.count: INPpar.FlagExample=False
293
+ self.adjustExampleImageList()
294
+ self.INPpar.FlagImport=self.INPpar.importPar.FlagImport and self.INPpar.importPar.isEqualTo(self.INPpar,exceptions=['name','surname','FlagImport','ind'])
295
+
296
+ #self.INPpar.importPar.printDifferences(self.INPpar,exceptions=['name','surname','FlagImport','ind'],FlagStrictDiff=True)
297
+ return
298
+
299
+ def checkINPpar(self,ind=None,FlagRescan=False): #FlagRescan=False):
300
+ if ind is None: INP:INPpar=self.INPpar
301
+ else: INP:INPpar=self.TABpar_at(ind)
302
+ self.setOptionValidPath(ind)
303
+ FlagWarn=INP.OptionValidPath==0
304
+ if not INP.FlagInit or FlagRescan:
305
+ self.scanImList(ind)
306
+ if not FlagWarn:
307
+ for imExc in INP.imEx:
308
+ for imExf in imExc:
309
+ for ex in imExf:
310
+ if not ex:
311
+ FlagWarn=True
312
+ break
313
+ INP.OptionDone=1 if (len(INP.imList[0][0])>0 and not FlagWarn) else 0 #-1 if len(INP.imList[0][0])>0 else 0
314
+
315
+ def scanImList(self,ind=None):
316
+ if ind: INP:INPpar=self.TABpar_at(ind)
317
+ else: INP:INPpar=self.INPpar
318
+ FlagWarning=False
319
+ for c in range(len(INP.imList)): #INP.ncam
320
+ for f in range(2):
321
+ for k in range(len(INP.imList[0][0])): #INP.nimg
322
+ #ex=INP.imEx[c][f][k]
323
+ INP.imEx[c][f][k]=os.path.exists(INP.path+INP.imList[c][f][k]) if INP.imList[c][f][k] else False
324
+ if not FlagWarning and not INP.imEx[c][f][k]: FlagWarning=True
325
+ return FlagWarning
326
+
327
+ def purgeImList(self, ind=None):
328
+ """Drop every k where any INP.imEx[c][f][k] is False; remove k from both imEx and imList across all c,f."""
329
+ INP = self.INPpar if ind is None else self.TABpar_at(ind)
330
+ if not hasattr(INP,"imEx") or not hasattr(INP,"imList"): return 0
331
+
332
+ # Collect all k to drop if False appears anywhere at that k
333
+ ks_to_drop=set()
334
+ for c in range(len(INP.imEx)):
335
+ for f in range(len(INP.imEx[c])):
336
+ row=INP.imEx[c][f]
337
+ for k, ex in enumerate(row):
338
+ if not ex: ks_to_drop.add(k)
339
+
340
+ if not ks_to_drop: return 0
341
+ ks_sorted=sorted(ks_to_drop, reverse=True)
342
+
343
+ # Delete k across all c,f for both imEx and imList (bounds-checked, ragged-safe)
344
+ for c in range(len(INP.imEx)):
345
+ for f in range(len(INP.imEx[c])):
346
+ for k in ks_sorted:
347
+ if k < len(INP.imEx[c][f]): del INP.imEx[c][f][k]
348
+ if c < len(INP.imList) and f < len(INP.imList[c]) and k < len(INP.imList[c][f]):
349
+ del INP.imList[c][f][k]
350
+ return len(ks_to_drop)
351
+
352
+ #*************************************************** Layout
353
+ def setINPlayout(self):
354
+ self.ui.label_process.setVisible(__name__ == "__main__")
355
+ self.ui.combo_process.setVisible(__name__ == "__main__")
356
+ self.setPathLabel()
357
+ self.setPathCompleter()
358
+
359
+ self.ui.g_ImSet.setEnabled(self.INPpar.OptionValidPath and self.INPpar.imSet.count)
360
+ #if self.INPpar.imSet.isDifferentFrom(self.INPpar_old.imSet,fields=['pattern']):
361
+ self.ui.combo_frame_a.clear()
362
+ self.ui.combo_frame_a.addItems(self.INPpar.imSet.pattern)
363
+ self.ui.combo_frame_b.clear()
364
+ self.ui.combo_frame_b.addItems(['-']+self.INPpar.imSet.pattern)
365
+
366
+ self.ui.spin_inp_ncam.setEnabled(self.INPpar.FlagCam)
367
+ self.ui.spin_inp_ncam.setMinimum(self.ncamMinimum())
368
+ self.ui.imTreeWidget.spin_ncam.setEnabled(False)
369
+ self.ui.imTreeWidget.FlagCam=self.INPpar.FlagCam
370
+ self.ui.imTreeWidget.spin_ncam.setMinimum(self.ncamMinimum())
371
+ self.ui.imTreeWidget.spin_ncam.setValue(self.INPpar.importPar.inp_ncam)
372
+ self.ui.spin_inp_cam.setEnabled(self.INPpar.inp_ncam>1)
373
+ self.ui.spin_inp_cam.setMaximum(self.INPpar.inp_ncam)
374
+ self.setImageNumberSpinLimits()
375
+ self.containerExImTree.setVisible(INPpar.FlagExample)
376
+ self.layoutExampleImageList()
377
+ #self.ui.button_import.setEnabled(not self.INPpar.FlagImport)
378
+
379
+ """
380
+ if self.INPpar.ind[-1]<len(self.TABpar_prev_at(self.INPpar.ind))-1:
381
+ self.ui.imTreeWidget.w_button.setVisible(False)
382
+ else:
383
+ self.ui.imTreeWidget.w_button.setVisible(True)
384
+ """
385
+
386
+ self.checkINPpar(FlagRescan=False)
387
+ self.setINPwarn()
388
+ self.setTABWarnLabel()
389
+ return
390
+
391
+ def setINPwarn(self,ind=None):
392
+ if ind is None: INP:INPpar=self.INPpar
393
+ else: INP:INPpar=self.TABpar_at(ind)
394
+ if INP.OptionDone==1:
395
+ INP.warningMessage='Input image files correctly identified!'
396
+ else:
397
+ FlagWarn=False
398
+ for imExc in INP.imEx:
399
+ for imExf in imExc:
400
+ for ex in imExf:
401
+ if not ex:
402
+ FlagWarn=True
403
+ break
404
+ if INP.OptionValidPath==0:
405
+ INP.warningMessage='Invalid input path!'
406
+ elif len(INP.imList[0][0])==0:
407
+ INP.warningMessage='Image set empty!'
408
+ elif FlagWarn:
409
+ INP.warningMessage='Some image files missing!'
410
+ else:
411
+ INP.warningMessage='Issues with identifying input image files!'
412
+
413
+ def ncamMinimum(self):
414
+ return 3 if self.INPpar.Process==ProcessTypes.tpiv else 2 if self.INPpar.Process==ProcessTypes.spiv else 1
415
+
416
+ def disableInputTab(self,flag):
417
+ self.setEnabled(not flag)
418
+
419
+ #*************************************************** Mode
420
+ #******************** Actions
421
+ def combo_process_action(self):
422
+ current_ind=self.ui.combo_process.currentIndex()
423
+ self.INPpar.Process=list(process)[current_ind]
424
+ if self.INPpar.Process in ProcessTypes.threeCameras:
425
+ self.INPpar.ncam=self.INPpar.inp_ncam=max([self.INPpar.ncam,self.ncamMinimum()])
426
+ else:
427
+ self.INPpar.ncam=self.INPpar.inp_ncam=self.ncamMinimum()
428
+
429
+ if INPpar.FlagAutoList:
430
+ self.button_scan_path_action()
431
+ else:
432
+ self.ui.imTreeWidget.spin_ncam.setMinimum(self.ncamMinimum())
433
+ self.ui.imTreeWidget.spin_ncam.setValue(self.INPpar.ncam)
434
+ self.INPpar.imList=self.ui.imTreeWidget.imTree.imList
435
+ self.INPpar.imEx=self.ui.imTreeWidget.imTree.imEx
436
+ self.ui.imTreeWidget.spin_ncam_action()
437
+ return
438
+
439
+ #******************** Set
440
+ def combo_process_set(self):
441
+ current_proc=process[self.INPpar.Process]
442
+ self.ui.combo_process.setCurrentIndex(process_items.index(current_proc))
443
+
444
+ #*************************************************** Path
445
+ #******************** Actions
446
+ def line_edit_path_changing(self):
447
+ self.ui.label_check_path.setPixmap(QPixmap())
448
+
449
+ def line_edit_path_preaction(self):
450
+ currpath=myStandardPath(self.ui.line_edit_path.text())
451
+ self.FlagScanPath=os.path.normpath(self.INPpar.path)!=currpath
452
+ currpath=relativizePath(currpath)
453
+ if os.path.exists(currpath) and currpath!='./':
454
+ pathCompleter=INPpar.pathCompleter #self.INPpar.pathCompleter
455
+ if currpath in pathCompleter: pathCompleter.remove(currpath)
456
+ pathCompleter.insert(0,currpath)
457
+ if len(pathCompleter)>pathCompleterLength:
458
+ INPpar.pathCompleter=pathCompleter[:pathCompleterLength]
459
+ self.ui.line_edit_path.setText(currpath)
460
+
461
+ def line_edit_path_action_future(self):
462
+ if self.FlagScanPath:
463
+ self.button_scan_path_action()
464
+
465
+ def button_path_action(self):
466
+ directory = str(QFileDialog.getExistingDirectory(self,\
467
+ "Choose an input folder", dir=self.INPpar.path,options=optionNativeDialog))
468
+ currpath='{}'.format(directory)
469
+ if not currpath=='':
470
+ currpath=myStandardPath(currpath)
471
+ self.ui.line_edit_path.setText(currpath)
472
+ self.INPpar.path=self.ui.line_edit_path.text()
473
+ self.line_edit_path_preaction()
474
+ else:
475
+ currpath='./'
476
+
477
+ def button_path_action_future(self):
478
+ self.line_edit_path_action_future()
479
+
480
+ def button_scan_path_action(self):
481
+ self.scanInputPath()
482
+ if INPpar.FlagAutoList:
483
+ self.button_import_action()
484
+ else:
485
+ self.ui.imTreeWidget.imTree.path=self.INPpar.path
486
+ self.ui.imTreeWidget.imTree.scanLists()
487
+ self.INPpar.imEx=self.ui.imTreeWidget.imTree.imEx
488
+
489
+ def scanInputPath(self,ind=None,patterns=None,FlagNoWarning=True):
490
+ INP = self.INPpar if ind is None else self.TABpar_at(ind)
491
+ INP.imSet.scanPath(INP.path)
492
+ ncam = INP.inp_ncam
493
+
494
+ FlagAutomaticFrames=True
495
+ if patterns and len(patterns)==2 and INP.imSet.count:
496
+ A,B = patterns # lists of patterns (len <= ncam)
497
+ INP.frame_1 = [-1]*ncam
498
+ INP.frame_2 = [-1]*ncam
499
+
500
+ # Build first-occurrence lookup: pattern -> index in slave's INP.imSet.pattern
501
+ pat_list = getattr(INP.imSet, "pattern", [])
502
+ idx_map = {}
503
+ for idx,p in enumerate(pat_list):
504
+ if p not in idx_map: idx_map[p]=idx
505
+
506
+ # Assign frames by matching patterns; leave -1 if not found
507
+ def _assign(dst, src, ind0=0):
508
+ for k in range(ncam):
509
+ key = src[k] if k < len(src) else None
510
+ dst[k] = idx_map.get(key, -1)
511
+ if ind0 and key is not None: dst[k]+=ind0
512
+
513
+ _assign(INP.frame_1, A)
514
+ _assign(INP.frame_2, B, 1)
515
+
516
+ valid=any(f>-1 for f in INP.frame_1) or any(f>0 for f in INP.frame_2)
517
+ if not valid and FlagNoWarning:
518
+ FlagAutomaticFrames = True
519
+ else:
520
+ FlagAutomaticFrames = False
521
+
522
+ if FlagAutomaticFrames:
523
+ if INP.imSet.count:
524
+ INP.frame_1[0]=0
525
+ INP.frame_1,INP.frame_2=self.automaticFrames(ind)
526
+ else:
527
+ INP.frame_1=[-1]*INP.inp_ncam
528
+ INP.frame_2=[-1]*INP.inp_ncam
529
+ # Update derived indices and safety on step
530
+ INP.ind_in, _, INP.npairs, _= self.getIndNpairs(ind)
531
+ if INP.npairs<1: INP.step=1
532
+
533
+ def automaticFrames(self,ind=None):
534
+ INP = self.INPpar if ind is None else self.TABpar_at(ind)
535
+ cam=INP.inp_cam-1
536
+ if not INP.imSet.nimg:
537
+ return INP.frame_1,INP.frame_2
538
+ f1=INP.frame_1[cam]
539
+ link1=INP.imSet.link[f1]
540
+ nlink1=len(link1)
541
+ frame_1=[f1]*INP.inp_ncam
542
+ frame_2=[f1+1]*INP.inp_ncam
543
+ frame_2[0]=link1[0]+1 if link1[0]!=f1 else 0
544
+ for c in range(1,INP.inp_ncam):
545
+ flagValid=c<nlink1-1
546
+ frame_1[c]=f1c=link1[c] if flagValid else -1
547
+ frame_2[c]=INP.imSet.link[f1c][0]+1 if flagValid else -1
548
+ if cam:
549
+ frame_1=frame_1[-cam:]+frame_1[:-cam]
550
+ frame_2=frame_2[-cam:]+frame_2[:-cam]
551
+ return frame_1, frame_2
552
+
553
+ def button_automatic_list_action(self):
554
+ INPpar.FlagAutoList=self.ui.button_automatic_list.isChecked()
555
+ return True
556
+
557
+ #******************** Settings
558
+ def setOptionValidPath(self,ind=None):
559
+ if ind is None: INP:INPpar=self.INPpar
560
+ else: INP:INPpar=self.TABpar_at(ind)
561
+ INP.OptionValidPath=int(os.path.exists(INP.path))
562
+ return
563
+
564
+ def setPathCompleter(self):
565
+ self.edit_path_completer=QCompleter(self.INPpar.pathCompleter)
566
+ self.edit_path_completer.setCompletionMode(QCompleter.CompletionMode(1))
567
+ self.edit_path_completer.setModelSorting(QCompleter.ModelSorting(2))
568
+ self.edit_path_completer.setWidget(self.ui.line_edit_path)
569
+ if self.INPpar.path in self.INPpar.pathCompleter:
570
+ k=self.INPpar.pathCompleter.index(self.INPpar.path)
571
+ self.edit_path_completer.setCurrentRow(k)
572
+ self.ui.line_edit_path.setCompleter(self.edit_path_completer)
573
+ self.ui.line_edit_path.FlagCompleter=True
574
+
575
+ def button_automatic_list_set(self):
576
+ self.ui.button_automatic_list.setChecked(INPpar.FlagAutoList)
577
+
578
+ #******************** Layout
579
+ def setPathLabel(self):
580
+ #Clickable label: no need for setStatusTip
581
+ if self.INPpar.OptionValidPath==1:
582
+ self.ui.label_check_path.setPixmap(self.pixmap_v)
583
+ self.ui.label_check_path.setToolTip("The specified path of the input folder exists!")
584
+ elif self.INPpar.OptionValidPath==0:
585
+ self.ui.label_check_path.setPixmap(self.pixmap_x)
586
+ self.ui.label_check_path.setToolTip("The specified path of the input folder does not exist!")
587
+ elif self.INPpar.OptionValidPath==-10:
588
+ self.ui.label_check_path.setPixmap(self.pixmap_wait)
589
+ self.ui.label_check_path.setToolTip("The specified path of the input folder is currently under inspection!")
590
+
591
+ #*************************************************** Image import tool
592
+ #******************** Actions
593
+ """
594
+ def button_box_action(self):
595
+ self.INPpar.FlagCollapBox=self.ui.CollapBox_ImSet.toggle_button.isChecked()
596
+ return True
597
+ """
598
+
599
+ def button_automatic_frame_action(self):
600
+ INPpar.FlagAutoFrame=self.ui.button_automatic_frame.isChecked()
601
+ return True
602
+
603
+ def combo_frame_a_action(self):
604
+ self.INPpar.frame_1[self.INPpar.inp_cam-1]=self.ui.combo_frame_a.currentIndex()
605
+ if INPpar.FlagAutoFrame:
606
+ self.INPpar.frame_1,self.INPpar.frame_2=self.automaticFrames()
607
+ self.INPpar.ind_in, _, self.INPpar.npairs, _= self.getIndNpairs()
608
+
609
+ def combo_frame_b_action(self):
610
+ self.INPpar.frame_2[self.INPpar.inp_cam-1]=self.ui.combo_frame_b.currentIndex()
611
+
612
+ def button_example_list_action(self):
613
+ INPpar.FlagExample=self.ui.button_example_list.isChecked()
614
+ self.containerExImTree.setVisible(INPpar.FlagExample)
615
+ return True
616
+
617
+ def spin_inp_cam_action(self):
618
+ if INPpar.FlagExample:
619
+ items=[self.exImTree.topLevelItem(0)] if not self.exImTree.selectedItems() else self.exImTree.selectedItems()
620
+ self.exImTree.clearSelection()
621
+ for item in items:
622
+ if item.parent(): item=item.parent()
623
+ if self.INPpar.inp_cam-1:
624
+ if not item.isExpanded():
625
+ self.INPpar.exImTreeExp[self.exImTree.indexOfTopLevelItem(item)]=True
626
+ item=item.child(self.INPpar.inp_cam-2)
627
+ item.setSelected(True)
628
+
629
+ def button_import_action(self):
630
+ self.INPpar.imList,self.INPpar.imEx=self.INPpar.imSet.genListsFromFrame(self.INPpar.frame_1,self.INPpar.frame_2,self.INPpar.ind_in,self.INPpar.npairs,self.INPpar.step,self.INPpar.FlagTR_Import)
631
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['imList','imEx']):
632
+ INPpar.FlagExample=False
633
+ self.INPpar.selection=[1,1,1]
634
+ self.InputAdjustSelection()
635
+ self.INPpar.FlagImport=True
636
+ self.INPpar.importPar.copyfrom(self.INPpar,exceptions=['name','surname'])
637
+ self.ui.CollapBox_ImSet.toggle_button.click()
638
+ self.ui.imTreeWidget.setFocus()
639
+ else:
640
+ # --- Tooltip warning ---
641
+ msg = "No changes to be applied to the image list!"
642
+ self.signals.tooltipRequested.emit(msg) # thread-safe
643
+
644
+ @Slot(str)
645
+ def show_import_tooltip(self, msg: str):
646
+ btn = self.ui.button_import
647
+ pos = btn.mapToGlobal(btn.rect().center())
648
+ QToolTip.showText(pos, msg, btn)
649
+ QTimer.singleShot(2000, QToolTip.hideText)
650
+
651
+ #******************** Settings
652
+ """
653
+ def button_box_set(self):
654
+ if self.INPpar.FlagCollapBox:
655
+ self.ui.CollapBox_ImSet.openBox()
656
+ else:
657
+ self.ui.CollapBox_ImSet.closeBox()
658
+ """
659
+
660
+ def button_automatic_frame_set(self):
661
+ self.ui.button_automatic_frame.setChecked(INPpar.FlagAutoFrame)
662
+
663
+ def combo_frame_a_set(self):
664
+ i=self.INPpar.frame_1[self.INPpar.inp_cam-1]
665
+ self.ui.combo_frame_a.setCurrentIndex(i)
666
+
667
+ def combo_frame_b_set(self):
668
+ i=self.INPpar.frame_2[self.INPpar.inp_cam-1]
669
+ self.ui.combo_frame_b.setCurrentIndex(i)
670
+
671
+ def button_example_list_set(self):
672
+ self.ui.button_example_list.setChecked(INPpar.FlagExample)
673
+
674
+ #******************** Layout & Adjustments
675
+ def setImageNumberSpinLimits(self):
676
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['imSet','frame_1','frame_2','inp_ncam','FlagTR_Import']):
677
+ ind_in, ind_fin, npairs, npairs_max= self.getIndNpairs()
678
+ self.INPpar.ind_in=min([max([ind_in,self.INPpar.ind_in]),ind_fin])
679
+ self.INPpar.npairs=npairs if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['FlagTR_Import']) else min([self.INPpar.npairs,npairs])
680
+ self.INPpar.step=max([min([self.INPpar.step,npairs]),1])
681
+
682
+ self.ui.spin_ind_in.setMinimum(ind_in)
683
+ self.ui.spin_ind_in.setMaximum(ind_fin)
684
+ s_ind_in=formatNumber(self.ui.spin_ind_in,ind_in)
685
+ s_ind_fin=formatNumber(self.ui.spin_ind_in,ind_fin)
686
+ self.ui.spin_ind_in.setToolTip(f'Number of the first image in the sequence to process. Min.: {s_ind_in}, max: {s_ind_fin}')
687
+ self.ui.spin_ind_in.setStatusTip(self.ui.spin_ind_in.toolTip())
688
+
689
+ self.ui.spin_npairs.setMinimum(0)
690
+ self.ui.spin_npairs.setMaximum(npairs_max)
691
+ self.ui.spin_npairs.setToolTip(f'Number of image pairs to process. Max: {npairs_max}')
692
+ self.ui.spin_npairs.setStatusTip(self.ui.spin_npairs.toolTip())
693
+
694
+ self.ui.spin_step.setMinimum(1)
695
+ self.ui.spin_step.setMaximum(npairs_max)
696
+ #ind_in=self.INPpar.imSet.ind_in[self.INPpar.frame_a]
697
+ pass
698
+
699
+ def getIndNpairs(self,ind=None):
700
+ INP = self.INPpar if ind is None else self.TABpar_at(ind)
701
+ if INP.imSet.count:
702
+ l=[INP.imSet.ind_in[f] for f in INP.frame_1 if f>-1]
703
+ ind_in_1=min(l) if l else None
704
+ l=[INP.imSet.ind_in[f-1] for f in INP.frame_2 if f>0]
705
+ ind_in_2=min(l) if l else ind_in_1 if ind_in_1 is not None else None
706
+ ind_in=min([ind_in_1,ind_in_2]) if ind_in_2 is not None else 0
707
+
708
+ l=[INP.imSet.ind_fin[f] for f in INP.frame_1 if f>-1]
709
+ ind_fin_1=max(l) if l else None
710
+ l=[INP.imSet.ind_fin[f-1] for f in INP.frame_2 if f>0]
711
+ ind_fin_2=max(l) if l else ind_fin_1 if ind_fin_1 is not None else None
712
+ ind_fin=min([ind_fin_1,ind_fin_2]) if ind_fin_2 is not None else -1
713
+ else:
714
+ ind_in=ind_in_2=0
715
+ ind_fin=-1
716
+ npairs=nimg=ind_fin-ind_in+1
717
+ if not all(INP.frame_2):
718
+ npairs=int(npairs/2)
719
+ if INP.FlagTR_Import:
720
+ npairs=2*npairs-1+nimg%2 #(1+int(any(INP.frame_2)))*npairs-1
721
+ if npairs==0: ind_in=ind_fin=0
722
+ npairs_max=npairs
723
+ return ind_in, ind_fin, npairs, npairs_max
724
+
725
+ def adjustExampleImageList(self):
726
+ exImListPar=['path','frame_1','frame_2','inp_ncam','ind_in','npairs','step','FlagTR_Import']
727
+ if self.INPpar.isDifferentFrom(self.INPpar_old,fields=exImListPar):
728
+ #self.INPpar_old.printDifferences(self.INPpar,fields=exImListPar)
729
+ self.INPpar.exImList,self.INPpar.exImEx=self.INPpar.imSet.genListsFromFrame(self.INPpar.frame_1,self.INPpar.frame_2,self.INPpar.ind_in,min([self.INPpar.npairs,self.INPpar.nExImTree]),self.INPpar.step,self.INPpar.FlagTR_Import)
730
+
731
+ def layoutExampleImageList(self):
732
+ if self.exImTree.imEx!=self.INPpar.exImEx or self.exImTree.imList!=self.INPpar.exImList:
733
+ self.exImTree.imList=self.INPpar.exImList
734
+ self.exImTree.imEx=self.INPpar.exImEx
735
+ self.exImTree.ncam=self.INPpar.ncam
736
+ self.exImTree.setImListEx()
737
+ self.exImTree.path=self.INPpar.path
738
+ self.exImTree.ncam=self.INPpar.inp_ncam
739
+ self.exImTree.setLists(FlagAsync=False)
740
+ self.exImTree.resizeColumnToContents(2)
741
+ if self.INPpar.inp_ncam==1: self.INPpar.exImTreeExp=[False]*3
742
+ height=self.exImTree.header().height()+5
743
+ #itemHeight=20
744
+ #height=itemHeight+5
745
+ for i in range(3):
746
+ item = self.exImTree.topLevelItem(i)
747
+ if not item: continue
748
+ item.setExpanded(self.INPpar.exImTreeExp[i])
749
+ height+=self.exImTree.visualItemRect(item).height()
750
+ for c in range(item.childCount()):
751
+ height+=self.exImTree.visualItemRect(item.child(c)).height()
752
+ #if self.INPpar.exImTreeExp[i]:
753
+ # height+=item.childCount()*itemHeight
754
+ #else: height+=itemHeight
755
+ self.exImTree.setMinimumHeight(height)
756
+ self.exImTree.setMaximumHeight(height)
757
+ self.exImTree.verticalScrollBar().setMinimumHeight(height)
758
+ self.exImTree.verticalScrollBar().setMaximumHeight(height)
759
+ if self.hbarExImTree.maximum()==self.hbarExImTree.minimum():
760
+ self.hbarExImTree.setVisible(False)
761
+ containerHeight=height
762
+ else:
763
+ self.hbarExImTree.setVisible(True)
764
+ containerHeight=height+self.hbarExImTree.height()
765
+ self.containerExImTree.setMinimumHeight(containerHeight)
766
+ self.containerExImTree.setMaximumHeight(containerHeight)
767
+ self.ui.CollapBox_ImSet.heightArea=height+110 if INPpar.FlagExample else 110
768
+ self.ui.CollapBox_ImSet.heightOpened=self.ui.CollapBox_ImSet.heightArea+20
769
+ self.ui.CollapBox_ImSet.on_click()
770
+
771
+ def itemExpandedCollapsed(self):
772
+ for i in range(self.exImTree.topLevelItemCount()):
773
+ item = self.exImTree.topLevelItem(i)
774
+ self.INPpar.exImTreeExp[i]=item.isExpanded()
775
+ self.layoutExampleImageList()
776
+ return True
777
+
778
+ #*************************************************** Image import tool
779
+ #******************** Actions
780
+ def image_list_action(self):
781
+ self.INPpar.imList=self.ui.imTreeWidget.imTree.imList
782
+ self.INPpar.imEx=self.ui.imTreeWidget.imTree.imEx
783
+ FlagDifferent=self.INPpar.isDifferentFrom(self.INPpar_old,fields=['imList'])
784
+ self.INPpar.FlagImport=False
785
+ return not FlagDifferent
786
+
787
+ def selection_action(self):
788
+ if QApplication.keyboardModifiers(): return
789
+ w=self.ui.imTreeWidget
790
+ if w.imTree.FlagSetting: return
791
+ self.INPpar.selection=[w.spin_img.value(),w.spin_cam.value(),w.spin_frame.value()]
792
+ self.InputAdjustSelection()
793
+ if not TABpar.FlagSettingPar and not self.FlagSettingPar:
794
+ FlagAdjustPar=True
795
+ self.setTABpar_bridge(FlagAdjustPar,FlagCallback=True)
796
+ return True
797
+
798
+ def InputAdjustSelection(self,INP:INPpar=None):
799
+ if INP is None: INP=self.INPpar
800
+ if len(self.TABpar_prev_at(INP.ind)):
801
+ self.TABpar_at(INP.ind).selection=copy.deepcopy(INP.selection)
802
+
803
+ #******************** Settings
804
+ def image_list_set(self):
805
+ FlagNewLists=self.INPpar.isDifferentFrom(self.ui.imTreeWidget.imTree,fields=['imList','imEx'])
806
+ if FlagNewLists and (not self.ImTreeInd or self.ImTreeInd!=self.INPpar.ind) and (self.ui.imTreeWidget.imTree.itemWorker is None or self.INPpar.ind!=self.INPpar_old.ind):
807
+ self.ImTreeInd=copy.deepcopy(self.INPpar.ind)
808
+ self.ui.imTreeWidget.imTree.signals.updateLists.disconnect()
809
+ self.ui.imTreeWidget.imTree.signals.updateLists.connect(self.restoreSignal)
810
+ self.ui.imTreeWidget.setLists(self.INPpar.path,self.INPpar.imList,self.INPpar.imEx,selection=self.INPpar.selection,FlagOnlyPrepare=not FlagNewLists)
811
+ if not FlagNewLists: self.restoreSignal()
812
+ self.ui.imTreeWidget.imTree.spinSelection(self.INPpar.selection)
813
+
814
+ def emptyImTreeInd(self):
815
+ self.ImTreeInd=[]
816
+
817
+ @Slot()
818
+ def restoreSignal(self):
819
+ self.ui.imTreeWidget.imTree.signals.updateLists.disconnect()
820
+ self.ui.imTreeWidget.imTree.signals.updateLists.connect(self.image_list_callback)
821
+
822
+ if __name__ == "__main__":
823
+ import sys
824
+ app=QApplication.instance()
825
+ if not app:app = QApplication(sys.argv)
826
+ app.setStyle('Fusion')
827
+ object = Input_Tab(None)
828
+ object.show()
829
+ app.exec()
830
+ app.quit()
719
831
  app=None