cellects 0.3.0__py3-none-any.whl → 0.3.5__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.
@@ -164,21 +164,20 @@ class ImageAnalysisWindow(MainTabsType):
164
164
  self.row1_layout.addWidget(self.image_number_label)
165
165
  self.row1_layout.addWidget(self.image_number)
166
166
  self.row1_layout.addWidget(self.read)
167
- self.row1_layout.addItem(self.horizontal_space)
167
+ self.row1_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
168
168
  self.row1_layout.addWidget(self.one_blob_per_arena_label)
169
169
  self.row1_layout.addWidget(self.one_blob_per_arena)
170
- self.row1_layout.addItem(self.horizontal_space)
170
+ self.row1_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
171
171
  self.row1_layout.addWidget(self.scale_with_label)
172
172
  self.row1_layout.addWidget(self.scale_with)
173
- self.row1_layout.addItem(self.horizontal_space)
173
+ self.row1_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
174
174
  self.row1_layout.addWidget(self.scale_size_label)
175
175
  self.row1_layout.addWidget(self.horizontal_size)
176
176
 
177
177
  self.row1_widget.setLayout(self.row1_layout)
178
- self.Vlayout.addItem(self.vertical_space)
178
+ self.Vlayout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.MinimumExpanding))
179
179
  self.Vlayout.addWidget(self.row1_widget)
180
- self.Vlayout.addItem(self.vertical_space)
181
- self.Vlayout.setSpacing(0)
180
+ self.Vlayout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.MinimumExpanding))
182
181
 
183
182
  # 2) Open the central row layout
184
183
  self.central_row_widget = QtWidgets.QWidget()
@@ -255,11 +254,7 @@ class ImageAnalysisWindow(MainTabsType):
255
254
  self.message.setStyleSheet("color: rgb(230, 145, 18)")
256
255
 
257
256
  # 2)c) The csc editing
258
- self.central_right_widget = QtWidgets.QWidget()
259
- self.central_right_layout = QtWidgets.QVBoxLayout()
260
257
  self.generate_csc_editing()
261
- self.central_right_layout.addWidget(self.edit_widget)
262
- self.central_right_widget.setLayout(self.central_right_layout)
263
258
 
264
259
  self.central_row_layout.addWidget(self.central_right_widget, 0, 2)
265
260
  self.central_row_layout.setAlignment(QtCore.Qt.AlignLeft)
@@ -267,7 +262,7 @@ class ImageAnalysisWindow(MainTabsType):
267
262
  # 2) Close the central row layout
268
263
  self.central_row_widget.setLayout(self.central_row_layout)
269
264
  self.Vlayout.addWidget(self.central_row_widget)
270
- self.Vlayout.addItem(self.vertical_space)
265
+ self.Vlayout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.MinimumExpanding))
271
266
 
272
267
  # 3) Add Set supplementary parameters row 1
273
268
  self.sup_param_row1_widget = QtWidgets.QWidget()
@@ -300,7 +295,7 @@ class ImageAnalysisWindow(MainTabsType):
300
295
  self.spot_size = Spinbox(min=0, max=100000, val=self.parent().po.all['starting_blob_hsize_in_mm'], decimals=2,
301
296
  night_mode=self.parent().po.all['night_mode'])
302
297
  self.spot_size.valueChanged.connect(self.spot_size_changed)
303
- self.sup_param_row2_layout.addItem(self.horizontal_space)
298
+ self.sup_param_row2_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
304
299
  self.sup_param_row2_layout.addWidget(self.arena_shape_label)
305
300
  self.sup_param_row2_layout.addWidget(self.arena_shape)
306
301
  self.sup_param_row2_layout.addWidget(self.set_spot_shape)
@@ -310,9 +305,8 @@ class ImageAnalysisWindow(MainTabsType):
310
305
  self.sup_param_row2_layout.addWidget(self.spot_size_label)
311
306
  self.sup_param_row2_layout.addWidget(self.spot_size)
312
307
  self.sup_param_row2_widget.setLayout(self.sup_param_row2_layout)
313
- self.sup_param_row2_layout.addItem(self.horizontal_space)
308
+ self.sup_param_row2_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
314
309
  self.Vlayout.addWidget(self.sup_param_row2_widget)
315
- self.Vlayout.setSpacing(0)
316
310
 
317
311
  self.one_blob_per_arena.setVisible(True)
318
312
  self.one_blob_per_arena_label.setVisible(True)
@@ -344,14 +338,13 @@ class ImageAnalysisWindow(MainTabsType):
344
338
  self.sup_param_row1_layout.addWidget(self.generate_analysis_options)
345
339
  self.sup_param_row1_layout.addWidget(self.basic)
346
340
  self.sup_param_row1_layout.addWidget(self.network_shaped)
347
- self.sup_param_row1_layout.addItem(self.horizontal_space)
348
- self.sup_param_row1_layout.addItem(self.horizontal_space)
341
+ self.sup_param_row1_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
342
+ self.sup_param_row1_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
349
343
  self.sup_param_row1_layout.addWidget(self.visualize_label)
350
344
  self.sup_param_row1_layout.addWidget(self.visualize)
351
345
 
352
346
  self.sup_param_row1_widget.setLayout(self.sup_param_row1_layout)
353
347
  self.Vlayout.addWidget(self.sup_param_row1_widget)
354
- self.Vlayout.setSpacing(0)
355
348
 
356
349
  # 6) Open the choose best option row layout
357
350
  self.options_row_widget = QtWidgets.QWidget()
@@ -369,14 +362,13 @@ class ImageAnalysisWindow(MainTabsType):
369
362
  self.select_option_label.setVisible(False)
370
363
  self.select_option.setVisible(False)
371
364
  self.n_shapes_detected.setVisible(False)
372
- self.options_row_layout.addItem(self.horizontal_space)
365
+ self.options_row_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
373
366
  self.options_row_layout.addWidget(self.select_option_label)
374
367
  self.options_row_layout.addWidget(self.select_option)
375
368
  self.options_row_layout.addWidget(self.n_shapes_detected)
376
- self.options_row_layout.addItem(self.horizontal_space)
369
+ self.options_row_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
377
370
  self.options_row_widget.setLayout(self.options_row_layout)
378
371
  self.Vlayout.addWidget(self.options_row_widget)
379
- self.Vlayout.setSpacing(0)
380
372
 
381
373
  # 7) Open decision row layout
382
374
  self.decision_row_widget = QtWidgets.QWidget()
@@ -390,11 +382,11 @@ class ImageAnalysisWindow(MainTabsType):
390
382
  self.decision_label.setVisible(False)
391
383
  self.yes.setVisible(False)
392
384
  self.no.setVisible(False)
393
- self.decision_row_layout.addItem(self.horizontal_space)
385
+ self.decision_row_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
394
386
  self.decision_row_layout.addWidget(self.decision_label)
395
387
  self.decision_row_layout.addWidget(self.yes)
396
388
  self.decision_row_layout.addWidget(self.no)
397
- self.decision_row_layout.addItem(self.horizontal_space)
389
+ self.decision_row_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
398
390
  self.decision_row_widget.setLayout(self.decision_row_layout)
399
391
  self.Vlayout.addWidget(self.decision_row_widget)
400
392
 
@@ -413,8 +405,6 @@ class ImageAnalysisWindow(MainTabsType):
413
405
  self.special_cases_widget.setLayout(self.special_cases_layout)
414
406
  self.Vlayout.addWidget(self.special_cases_widget)
415
407
 
416
- self.Vlayout.setSpacing(0)
417
-
418
408
  # 9) Open the last row layout
419
409
  self.last_row_widget = QtWidgets.QWidget()
420
410
  self.last_row_layout = QtWidgets.QHBoxLayout()
@@ -432,30 +422,30 @@ class ImageAnalysisWindow(MainTabsType):
432
422
  self.next.clicked.connect(self.go_to_next_widget)
433
423
  self.last_row_layout.addWidget(self.previous)
434
424
  self.last_row_layout.addWidget(self.message)
435
- self.last_row_layout.addItem(self.horizontal_space)
425
+ self.last_row_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
436
426
  self.last_row_layout.addWidget(self.complete_image_analysis)
437
427
  self.last_row_layout.addWidget(self.next)
438
428
  self.last_row_widget.setLayout(self.last_row_layout)
439
429
  self.Vlayout.addWidget(self.last_row_widget)
440
- self.setLayout(self.Vlayout)
441
430
  self.Vlayout.setSpacing(0)
431
+ self.setLayout(self.Vlayout)
442
432
 
443
433
  self.advanced_mode_check()
444
434
 
445
- self.thread = {}
446
- self.thread["GetFirstIm"] = GetFirstImThread(self.parent())
435
+ self.thread_dict = {}
436
+ self.thread_dict["GetFirstIm"] = GetFirstImThread(self.parent())
447
437
  self.reinitialize_image_and_masks(self.parent().po.first_im)
448
- self.thread["GetLastIm"] = GetLastImThread(self.parent())
438
+ self.thread_dict["GetLastIm"] = GetLastImThread(self.parent())
449
439
  if self.parent().po.all['im_or_vid'] == 0:
450
- self.thread["GetLastIm"].start()
440
+ self.thread_dict["GetLastIm"].start()
451
441
  self.parent().po.first_image = OneImageAnalysis(self.parent().po.first_im)
452
- self.thread["FirstImageAnalysis"] = FirstImageAnalysisThread(self.parent())
453
- self.thread["LastImageAnalysis"] = LastImageAnalysisThread(self.parent())
454
- self.thread['UpdateImage'] = UpdateImageThread(self.parent())
455
- self.thread['CropScaleSubtractDelineate'] = CropScaleSubtractDelineateThread(self.parent())
456
- self.thread['SaveManualDelineation'] = SaveManualDelineationThread(self.parent())
457
- self.thread['CompleteImageAnalysisThread'] = CompleteImageAnalysisThread(self.parent())
458
- self.thread['PrepareVideoAnalysis'] = PrepareVideoAnalysisThread(self.parent())
442
+ self.thread_dict["FirstImageAnalysis"] = FirstImageAnalysisThread(self.parent())
443
+ self.thread_dict["LastImageAnalysis"] = LastImageAnalysisThread(self.parent())
444
+ self.thread_dict['UpdateImage'] = UpdateImageThread(self.parent())
445
+ self.thread_dict['CropScaleSubtractDelineate'] = CropScaleSubtractDelineateThread(self.parent())
446
+ self.thread_dict['SaveManualDelineation'] = SaveManualDelineationThread(self.parent())
447
+ self.thread_dict['CompleteImageAnalysisThread'] = CompleteImageAnalysisThread(self.parent())
448
+ self.thread_dict['PrepareVideoAnalysis'] = PrepareVideoAnalysisThread(self.parent())
459
449
 
460
450
  def previous_is_clicked(self):
461
451
  """
@@ -535,11 +525,11 @@ class ImageAnalysisWindow(MainTabsType):
535
525
  It ensures that only one thread runs at a time, updates the UI with relevant messages,
536
526
  and resets visual components once processing begins.
537
527
  """
538
- if not self.thread["GetFirstIm"].isRunning():
528
+ if not self.thread_dict["GetFirstIm"].isRunning():
539
529
  self.parent().po.vars['first_detection_frame'] = int(self.image_number.value())
540
530
  self.message.setText(f"Reading image n°{self.parent().po.vars['first_detection_frame']}")
541
- self.thread["GetFirstIm"].start()
542
- self.thread["GetFirstIm"].message_when_thread_finished.connect(self.reinitialize_image_and_masks)
531
+ self.thread_dict["GetFirstIm"].start()
532
+ self.thread_dict["GetFirstIm"].message_when_thread_finished.connect(self.reinitialize_image_and_masks)
543
533
  self.reinitialize_bio_and_back_legend()
544
534
 
545
535
 
@@ -605,10 +595,10 @@ class ImageAnalysisWindow(MainTabsType):
605
595
  """
606
596
  self.parent().po.vars['arena_shape'] = self.arena_shape.currentText()
607
597
  if self.asking_delineation_flag:
608
- if self.thread['CropScaleSubtractDelineate'].isRunning():
609
- self.thread['CropScaleSubtractDelineate'].wait()
610
- if self.thread['UpdateImage'].isRunning():
611
- self.thread['UpdateImage'].wait()
598
+ if self.thread_dict['CropScaleSubtractDelineate'].isRunning():
599
+ self.thread_dict['CropScaleSubtractDelineate'].wait()
600
+ if self.thread_dict['UpdateImage'].isRunning():
601
+ self.thread_dict['UpdateImage'].wait()
612
602
  self.message.setText("Updating display...")
613
603
  self.decision_label.setVisible(False)
614
604
  self.yes.setVisible(False)
@@ -616,10 +606,10 @@ class ImageAnalysisWindow(MainTabsType):
616
606
  self.reinitialize_bio_and_back_legend()
617
607
  self.reinitialize_image_and_masks(self.parent().po.first_image.bgr)
618
608
  self.delineation_done = True
619
- if self.thread["UpdateImage"].isRunning():
620
- self.thread["UpdateImage"].wait()
621
- self.thread["UpdateImage"].start()
622
- self.thread["UpdateImage"].message_when_thread_finished.connect(self.automatic_delineation_display_done)
609
+ if self.thread_dict["UpdateImage"].isRunning():
610
+ self.thread_dict["UpdateImage"].wait()
611
+ self.thread_dict["UpdateImage"].start()
612
+ self.thread_dict["UpdateImage"].message_when_thread_finished.connect(self.automatic_delineation_display_done)
623
613
 
624
614
  def reinitialize_bio_and_back_legend(self):
625
615
  """
@@ -834,7 +824,7 @@ class ImageAnalysisWindow(MainTabsType):
834
824
  The mouse event that triggered the function.
835
825
  """
836
826
  if self.back1_bio2 > 0 or self.manual_delineation_flag:
837
- if not self.is_image_analysis_display_running and not self.thread["UpdateImage"].isRunning():
827
+ if not self.is_image_analysis_display_running and not self.thread_dict["UpdateImage"].isRunning():
838
828
  self.hold_click_flag = True
839
829
  self.saved_coord.append([event.pos().y(), event.pos().x()])
840
830
  else:
@@ -851,10 +841,10 @@ class ImageAnalysisWindow(MainTabsType):
851
841
  The mouse event object containing position information.
852
842
  """
853
843
  if self.hold_click_flag:
854
- if not self.thread["UpdateImage"].isRunning():
844
+ if not self.thread_dict["UpdateImage"].isRunning():
855
845
  if self.saved_coord[0][0] != event.pos().y() and self.saved_coord[0][1] != event.pos().x():
856
846
  self.temporary_mask_coord = [self.saved_coord[0], [event.pos().y(), event.pos().x()]]
857
- self.thread["UpdateImage"].start()
847
+ self.thread_dict["UpdateImage"].start()
858
848
 
859
849
  def get_mouse_release_coordinates(self, event):
860
850
  """
@@ -876,16 +866,16 @@ class ImageAnalysisWindow(MainTabsType):
876
866
  state.
877
867
  """
878
868
  if self.hold_click_flag:
879
- if self.thread["UpdateImage"].isRunning():
880
- self.thread["UpdateImage"].wait()
869
+ if self.thread_dict["UpdateImage"].isRunning():
870
+ self.thread_dict["UpdateImage"].wait()
881
871
  self.temporary_mask_coord = []
882
872
  if self.manual_delineation_flag and len(self.parent().imageanalysiswindow.available_arena_names) == 0:
883
873
  self.message.setText(f"The total number of arenas are already drawn ({self.parent().po.sample_number})")
884
874
  self.saved_coord = []
885
875
  else:
886
876
  self.saved_coord.append([event.pos().y(), event.pos().x()])
887
- self.thread["UpdateImage"].start()
888
- self.thread["UpdateImage"].message_when_thread_finished.connect(self.user_defined_shape_displayed)
877
+ self.thread_dict["UpdateImage"].start()
878
+ self.thread_dict["UpdateImage"].message_when_thread_finished.connect(self.user_defined_shape_displayed)
889
879
  self.hold_click_flag = False
890
880
 
891
881
  def user_defined_shape_displayed(self, when_finished: bool):
@@ -936,7 +926,7 @@ class ImageAnalysisWindow(MainTabsType):
936
926
  self.saved_coord = []
937
927
  self.back1_bio2 = 0
938
928
 
939
- self.thread["UpdateImage"].message_when_thread_finished.disconnect()
929
+ self.thread_dict["UpdateImage"].message_when_thread_finished.disconnect()
940
930
 
941
931
  def new_pbutton_on_the_left(self, pbutton_name: str):
942
932
  """
@@ -972,7 +962,7 @@ class ImageAnalysisWindow(MainTabsType):
972
962
  and updates the layout and available names accordingly. It starts the image update thread
973
963
  after removing the line.
974
964
  """
975
- if not self.is_image_analysis_display_running and not self.thread["UpdateImage"].isRunning() and hasattr(self.sender(), 'text'):
965
+ if not self.is_image_analysis_display_running and not self.thread_dict["UpdateImage"].isRunning() and hasattr(self.sender(), 'text'):
976
966
  pbutton_name = self.sender().text()
977
967
  if pbutton_name[2:6] == "Back":
978
968
  line_name = np.uint8(pbutton_name[6:])
@@ -1003,7 +993,7 @@ class ImageAnalysisWindow(MainTabsType):
1003
993
 
1004
994
  self.arena_masks_number -= 1
1005
995
  self.available_arena_names = np.sort(np.concatenate(([line_name], self.available_arena_names)))
1006
- self.thread["UpdateImage"].start()
996
+ self.thread_dict["UpdateImage"].start()
1007
997
 
1008
998
  def network_shaped_is_clicked(self):
1009
999
  """
@@ -1090,9 +1080,9 @@ class ImageAnalysisWindow(MainTabsType):
1090
1080
  self.is_image_analysis_running = False
1091
1081
  if not self.parent().po.visualize or not self.csc_dict_is_empty:
1092
1082
  self.parent().po.vars['convert_for_origin'] = self.csc_dict.copy()
1093
- self.thread["FirstImageAnalysis"].start()
1094
- self.thread["FirstImageAnalysis"].message_from_thread.connect(self.display_message_from_thread)
1095
- self.thread["FirstImageAnalysis"].message_when_thread_finished.connect(self.when_image_analysis_finishes)
1083
+ self.thread_dict["FirstImageAnalysis"].start()
1084
+ self.thread_dict["FirstImageAnalysis"].message_from_thread.connect(self.display_message_from_thread)
1085
+ self.thread_dict["FirstImageAnalysis"].message_when_thread_finished.connect(self.when_image_analysis_finishes)
1096
1086
 
1097
1087
  def run_last_image_analysis(self):
1098
1088
  """
@@ -1110,9 +1100,9 @@ class ImageAnalysisWindow(MainTabsType):
1110
1100
  self.message.setText('Select non null value(s) to combine colors')
1111
1101
  self.message.setStyleSheet("color: rgb(230, 145, 18)")
1112
1102
  else:
1113
- self.thread["LastImageAnalysis"].start()
1114
- self.thread["LastImageAnalysis"].message_from_thread.connect(self.display_message_from_thread)
1115
- self.thread["LastImageAnalysis"].message_when_thread_finished.connect(self.when_image_analysis_finishes)
1103
+ self.thread_dict["LastImageAnalysis"].start()
1104
+ self.thread_dict["LastImageAnalysis"].message_from_thread.connect(self.display_message_from_thread)
1105
+ self.thread_dict["LastImageAnalysis"].message_when_thread_finished.connect(self.when_image_analysis_finishes)
1116
1106
 
1117
1107
  def when_image_analysis_finishes(self):
1118
1108
  """
@@ -1156,10 +1146,10 @@ class ImageAnalysisWindow(MainTabsType):
1156
1146
  if self.parent().po.visualize or len(im_combinations) > 0:
1157
1147
  self.is_image_analysis_display_running = True
1158
1148
  # Update image display
1159
- if self.thread["UpdateImage"].isRunning():
1160
- self.thread["UpdateImage"].wait()
1161
- self.thread["UpdateImage"].start()
1162
- self.thread["UpdateImage"].message_when_thread_finished.connect(self.image_analysis_displayed)
1149
+ if self.thread_dict["UpdateImage"].isRunning():
1150
+ self.thread_dict["UpdateImage"].wait()
1151
+ self.thread_dict["UpdateImage"].start()
1152
+ self.thread_dict["UpdateImage"].message_when_thread_finished.connect(self.image_analysis_displayed)
1163
1153
 
1164
1154
  def image_analysis_displayed(self):
1165
1155
  """
@@ -1229,7 +1219,7 @@ class ImageAnalysisWindow(MainTabsType):
1229
1219
  self.message.setText('When the resulting segmentation of the last image seems good, save image analysis.')
1230
1220
  self.complete_image_analysis.setVisible(True)
1231
1221
 
1232
- self.thread["UpdateImage"].message_when_thread_finished.disconnect()
1222
+ self.thread_dict["UpdateImage"].message_when_thread_finished.disconnect()
1233
1223
  self.is_image_analysis_running = False
1234
1224
  self.is_image_analysis_display_running = False
1235
1225
 
@@ -1272,9 +1262,9 @@ class ImageAnalysisWindow(MainTabsType):
1272
1262
  self.init_drawn_image(im_combinations)
1273
1263
  if im_combinations is not None and len(im_combinations) > 0:
1274
1264
  # Update image display
1275
- if self.thread["UpdateImage"].isRunning():
1276
- self.thread["UpdateImage"].wait()
1277
- self.thread["UpdateImage"].start()
1265
+ if self.thread_dict["UpdateImage"].isRunning():
1266
+ self.thread_dict["UpdateImage"].wait()
1267
+ self.thread_dict["UpdateImage"].start()
1278
1268
  # Update csc editing
1279
1269
  self.update_csc_editing_display()
1280
1270
 
@@ -1314,8 +1304,8 @@ class ImageAnalysisWindow(MainTabsType):
1314
1304
  including checkboxes, labels, and drop-down menus. It also configures the layout
1315
1305
  and connections between components.
1316
1306
  """
1317
- self.edit_widget = QtWidgets.QWidget()
1318
- self.edit_layout = QtWidgets.QVBoxLayout()
1307
+ self.central_right_widget = QtWidgets.QWidget()
1308
+ self.central_right_layout = QtWidgets.QVBoxLayout()
1319
1309
 
1320
1310
  # 1) Advanced mode option
1321
1311
  self.advanced_mode_widget = QtWidgets.QWidget()
@@ -1336,9 +1326,9 @@ class ImageAnalysisWindow(MainTabsType):
1336
1326
  self.advanced_mode_label.setAlignment(QtCore.Qt.AlignTop)
1337
1327
  self.advanced_mode_layout.addWidget(self.advanced_mode_cb)
1338
1328
  self.advanced_mode_layout.addWidget(self.advanced_mode_label)
1339
- self.advanced_mode_layout.addItem(self.horizontal_space)
1329
+ self.advanced_mode_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
1340
1330
  self.advanced_mode_widget.setLayout(self.advanced_mode_layout)
1341
- self.edit_layout.addWidget(self.advanced_mode_widget)
1331
+ self.central_right_layout.addWidget(self.advanced_mode_widget)
1342
1332
 
1343
1333
  self.csc_scroll_table = QtWidgets.QScrollArea() # QTableWidget() # Scroll Area which contains the widgets, set as the centralWidget
1344
1334
  self.csc_scroll_table.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
@@ -1358,7 +1348,7 @@ class ImageAnalysisWindow(MainTabsType):
1358
1348
  night_mode=self.parent().po.all['night_mode'])
1359
1349
 
1360
1350
  self.edit_labels_layout.addWidget(self.space_label)
1361
- self.edit_labels_layout.addItem(self.horizontal_space)
1351
+ self.edit_labels_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
1362
1352
  self.space_label.setVisible(False)
1363
1353
  self.edit_labels_widget.setLayout(self.edit_labels_layout)
1364
1354
  self.csc_table_layout.addWidget(self.edit_labels_widget)
@@ -1400,7 +1390,7 @@ class ImageAnalysisWindow(MainTabsType):
1400
1390
  self.row2[i].setVisible(False)
1401
1391
  self.row3[i].setVisible(False)
1402
1392
  self.first_csc_layout.setHorizontalSpacing(0)
1403
- self.first_csc_layout.addItem(self.horizontal_space, 0, 5, 3, 1)
1393
+ self.first_csc_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum), 0, 5, 3, 1)
1404
1394
  self.first_csc_widget.setLayout(self.first_csc_layout)
1405
1395
  self.csc_table_layout.addWidget(self.first_csc_widget)
1406
1396
 
@@ -1436,10 +1426,10 @@ class ImageAnalysisWindow(MainTabsType):
1436
1426
  self.filter1_param2.valueChanged.connect(self.filter1_param2_changed)
1437
1427
  self.filter1_layout.addWidget(self.filter1)
1438
1428
  # self.filter1_layout.addWidget(self.filter1_label)
1439
- self.filter1_layout.addItem(self.horizontal_space)
1429
+ self.filter1_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
1440
1430
  self.filter1_layout.addWidget(self.filter1_param1_label)
1441
1431
  self.filter1_layout.addWidget(self.filter1_param1)
1442
- self.filter1_layout.addItem(self.horizontal_space)
1432
+ self.filter1_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
1443
1433
  self.filter1_layout.addWidget(self.filter1_param2_label)
1444
1434
  self.filter1_layout.addWidget(self.filter1_param2)
1445
1435
  self.filter1.setVisible(False)
@@ -1456,7 +1446,7 @@ class ImageAnalysisWindow(MainTabsType):
1456
1446
  self.logical_op_layout = QtWidgets.QHBoxLayout()
1457
1447
  self.logical_op_layout.addWidget(self.logical_operator_label)
1458
1448
  self.logical_op_layout.addWidget(self.logical_operator_between_combination_result)
1459
- self.logical_op_layout.addItem(self.horizontal_space)
1449
+ self.logical_op_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
1460
1450
  self.logical_operator_between_combination_result.setVisible(False)
1461
1451
  self.logical_operator_label.setVisible(False)
1462
1452
  self.logical_op_widget.setLayout(self.logical_op_layout)
@@ -1473,15 +1463,15 @@ class ImageAnalysisWindow(MainTabsType):
1473
1463
  self.row22[i].setVisible(False)
1474
1464
  self.row23[i].setVisible(False)
1475
1465
  self.second_csc_layout.setHorizontalSpacing(0)
1476
- self.second_csc_layout.addItem(self.horizontal_space, 0, 5, 3, 1)
1466
+ self.second_csc_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum), 0, 5, 3, 1)
1477
1467
  self.second_csc_widget.setLayout(self.second_csc_layout)
1478
1468
  self.csc_table_layout.addWidget(self.second_csc_widget)
1479
1469
 
1480
1470
  self.csc_table_widget.setLayout(self.csc_table_layout)
1481
1471
  self.csc_scroll_table.setWidget(self.csc_table_widget)
1482
1472
  self.csc_scroll_table.setWidgetResizable(True)
1483
- self.edit_layout.addWidget(self.csc_scroll_table)
1484
- self.edit_layout.addItem(self.vertical_space)
1473
+ self.central_right_layout.addWidget(self.csc_scroll_table)
1474
+ self.central_right_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.MinimumExpanding))
1485
1475
 
1486
1476
  # Second filters
1487
1477
  self.filter2_label = FixedText(IAW["Filter"]["label"] + ': ', halign='l',
@@ -1515,10 +1505,10 @@ class ImageAnalysisWindow(MainTabsType):
1515
1505
 
1516
1506
  self.filter1_param2.valueChanged.connect(self.filter2_param2_changed)
1517
1507
  self.filter2_layout.addWidget(self.filter2)
1518
- self.filter2_layout.addItem(self.horizontal_space)
1508
+ self.filter2_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
1519
1509
  self.filter2_layout.addWidget(self.filter2_param1_label)
1520
1510
  self.filter2_layout.addWidget(self.filter2_param1)
1521
- self.filter2_layout.addItem(self.horizontal_space)
1511
+ self.filter2_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
1522
1512
  self.filter2_layout.addWidget(self.filter2_param2_label)
1523
1513
  self.filter2_layout.addWidget(self.filter2_param2)
1524
1514
  self.filter2.setVisible(False)
@@ -1551,9 +1541,9 @@ class ImageAnalysisWindow(MainTabsType):
1551
1541
 
1552
1542
  self.rolling_window_segmentation_layout.addWidget(self.rolling_window_segmentation)
1553
1543
  self.rolling_window_segmentation_layout.addWidget(self.rolling_window_segmentation_label)
1554
- self.rolling_window_segmentation_layout.addItem(self.horizontal_space)
1544
+ self.rolling_window_segmentation_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
1555
1545
  self.rolling_window_segmentation_widget.setLayout(self.rolling_window_segmentation_layout)
1556
- self.edit_layout.addWidget(self.rolling_window_segmentation_widget)
1546
+ self.central_right_layout.addWidget(self.rolling_window_segmentation_widget)
1557
1547
 
1558
1548
  # 6) Open the more_than_2_colors row layout
1559
1549
  self.more_than_2_colors_widget = QtWidgets.QWidget()
@@ -1586,11 +1576,11 @@ class ImageAnalysisWindow(MainTabsType):
1586
1576
  self.more_than_2_colors_layout.addWidget(self.more_than_two_colors)
1587
1577
  self.more_than_2_colors_layout.addWidget(self.more_than_two_colors_label)
1588
1578
  self.more_than_2_colors_layout.addWidget(self.distinct_colors_number)
1589
- self.more_than_2_colors_layout.addItem(self.horizontal_space)
1579
+ self.more_than_2_colors_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
1590
1580
  self.more_than_2_colors_widget.setLayout(self.more_than_2_colors_layout)
1591
- self.edit_layout.addWidget(self.more_than_2_colors_widget)
1581
+ self.central_right_layout.addWidget(self.more_than_2_colors_widget)
1592
1582
 
1593
- self.edit_widget.setLayout(self.edit_layout)
1583
+ self.central_right_widget.setLayout(self.central_right_layout)
1594
1584
 
1595
1585
  def update_filter_display(self):
1596
1586
  self.filter1.setCurrentText(self.parent().po.vars['filter_spec']['filter1_type'])
@@ -2031,11 +2021,11 @@ class ImageAnalysisWindow(MainTabsType):
2031
2021
  subtract, and delineate operations on the image. It also updates the
2032
2022
  UI elements to reflect the ongoing process.
2033
2023
  """
2034
- if not self.thread['CropScaleSubtractDelineate'].isRunning():
2024
+ if not self.thread_dict['CropScaleSubtractDelineate'].isRunning():
2035
2025
  self.message.setText("Looking for each arena contour, wait...")
2036
- self.thread['CropScaleSubtractDelineate'].start()
2037
- self.thread['CropScaleSubtractDelineate'].message_from_thread.connect(self.display_message_from_thread)
2038
- self.thread['CropScaleSubtractDelineate'].message_when_thread_finished.connect(self.delineate_is_done)
2026
+ self.thread_dict['CropScaleSubtractDelineate'].start()
2027
+ self.thread_dict['CropScaleSubtractDelineate'].message_from_thread.connect(self.display_message_from_thread)
2028
+ self.thread_dict['CropScaleSubtractDelineate'].message_when_thread_finished.connect(self.delineate_is_done)
2039
2029
 
2040
2030
  self.yes.setVisible(False)
2041
2031
  self.no.setVisible(False)
@@ -2074,14 +2064,14 @@ class ImageAnalysisWindow(MainTabsType):
2074
2064
  self.reinitialize_bio_and_back_legend()
2075
2065
  self.reinitialize_image_and_masks(self.parent().po.first_image.bgr)
2076
2066
  self.delineation_done = True
2077
- if self.thread["UpdateImage"].isRunning():
2078
- self.thread["UpdateImage"].wait()
2079
- self.thread["UpdateImage"].start()
2080
- self.thread["UpdateImage"].message_when_thread_finished.connect(self.automatic_delineation_display_done)
2067
+ if self.thread_dict["UpdateImage"].isRunning():
2068
+ self.thread_dict["UpdateImage"].wait()
2069
+ self.thread_dict["UpdateImage"].start()
2070
+ self.thread_dict["UpdateImage"].message_when_thread_finished.connect(self.automatic_delineation_display_done)
2081
2071
 
2082
2072
  try:
2083
- self.thread['CropScaleSubtractDelineate'].message_from_thread.disconnect()
2084
- self.thread['CropScaleSubtractDelineate'].message_when_thread_finished.disconnect()
2073
+ self.thread_dict['CropScaleSubtractDelineate'].message_from_thread.disconnect()
2074
+ self.thread_dict['CropScaleSubtractDelineate'].message_when_thread_finished.disconnect()
2085
2075
  except RuntimeError:
2086
2076
  pass
2087
2077
  if not self.slower_delineation_flag:
@@ -2116,7 +2106,7 @@ class ImageAnalysisWindow(MainTabsType):
2116
2106
  self.yes.setVisible(True)
2117
2107
  self.no.setVisible(True)
2118
2108
 
2119
- self.thread["UpdateImage"].message_when_thread_finished.disconnect()
2109
+ self.thread_dict["UpdateImage"].message_when_thread_finished.disconnect()
2120
2110
 
2121
2111
  def display_message_from_thread(self, text_from_thread: str):
2122
2112
  """
@@ -2220,7 +2210,7 @@ class ImageAnalysisWindow(MainTabsType):
2220
2210
  elif self.manual_delineation_flag:
2221
2211
  if is_yes:
2222
2212
  if self.parent().po.sample_number == self.arena_masks_number:
2223
- self.thread['SaveManualDelineation'].start()
2213
+ self.thread_dict['SaveManualDelineation'].start()
2224
2214
  self.last_image_question()
2225
2215
  self.manual_delineation_flag = False
2226
2216
  else:
@@ -2407,8 +2397,8 @@ class ImageAnalysisWindow(MainTabsType):
2407
2397
  self.starting_differs_from_growing_label.setVisible(False)
2408
2398
  self.message.setText('Gathering data and visualizing last image analysis result')
2409
2399
  self.parent().po.get_last_image()
2410
- if self.thread['SaveManualDelineation'].isRunning():
2411
- self.thread['SaveManualDelineation'].wait()
2400
+ if self.thread_dict['SaveManualDelineation'].isRunning():
2401
+ self.thread_dict['SaveManualDelineation'].wait()
2412
2402
  self.parent().po.cropping(is_first_image=False)
2413
2403
  self.reinitialize_image_and_masks(self.parent().po.last_image.bgr)
2414
2404
  self.reinitialize_bio_and_back_legend()
@@ -2428,12 +2418,12 @@ class ImageAnalysisWindow(MainTabsType):
2428
2418
  """
2429
2419
  Completes the image analysis process if no listed threads are running.
2430
2420
  """
2431
- if (not self.thread['SaveManualDelineation'].isRunning() or not self.thread[
2432
- 'PrepareVideoAnalysis'].isRunning() or not self.thread['SaveData'].isRunning() or not
2433
- self.thread['CompleteImageAnalysisThread'].isRunning()):
2421
+ if (not self.thread_dict['SaveManualDelineation'].isRunning() or not self.thread_dict[
2422
+ 'PrepareVideoAnalysis'].isRunning() or not self.thread_dict['SaveData'].isRunning() or not
2423
+ self.thread_dict['CompleteImageAnalysisThread'].isRunning()):
2434
2424
  self.message.setText(f"Analyzing and saving the segmentation result, wait... ")
2435
- self.thread['CompleteImageAnalysisThread'].start()
2436
- self.thread['CompleteImageAnalysisThread'].message_when_thread_finished.connect(self.complete_image_analysis_done)
2425
+ self.thread_dict['CompleteImageAnalysisThread'].start()
2426
+ self.thread_dict['CompleteImageAnalysisThread'].message_when_thread_finished.connect(self.complete_image_analysis_done)
2437
2427
 
2438
2428
  def complete_image_analysis_done(self, res):
2439
2429
  self.message.setText(f"Complete image analysis done.")
@@ -2449,7 +2439,7 @@ class ImageAnalysisWindow(MainTabsType):
2449
2439
  - Waits for some background threads to complete their execution.
2450
2440
  - Advances the UI to the video analysis window if certain conditions are met.
2451
2441
  """
2452
- if not self.thread['SaveManualDelineation'].isRunning() or not self.thread['PrepareVideoAnalysis'].isRunning() or not self.thread['SaveData'].isRunning():
2442
+ if not self.thread_dict['SaveManualDelineation'].isRunning() or not self.thread_dict['PrepareVideoAnalysis'].isRunning() or not self.thread_dict['SaveData'].isRunning():
2453
2443
 
2454
2444
  self.popup = QtWidgets.QMessageBox()
2455
2445
  self.popup.setWindowTitle("Info")
@@ -2465,14 +2455,14 @@ class ImageAnalysisWindow(MainTabsType):
2465
2455
 
2466
2456
  self.message.setText(f"Final checks, wait... ")
2467
2457
  self.parent().last_tab = "image_analysis"
2468
- self.thread['PrepareVideoAnalysis'].start()
2458
+ self.thread_dict['PrepareVideoAnalysis'].start()
2469
2459
  if self.parent().po.vars["color_number"] > 2:
2470
2460
  self.parent().videoanalysiswindow.select_option.clear()
2471
2461
  self.parent().videoanalysiswindow.select_option.addItem(f"1) Kmeans")
2472
2462
  self.parent().videoanalysiswindow.select_option.setCurrentIndex(0)
2473
2463
  self.parent().po.all['video_option'] = 0
2474
2464
  time.sleep(1 / 10)
2475
- self.thread['PrepareVideoAnalysis'].wait()
2465
+ self.thread_dict['PrepareVideoAnalysis'].wait()
2476
2466
  self.message.setText(f"")
2477
2467
 
2478
2468
  self.video_tab.set_not_in_use()
@@ -2480,9 +2470,3 @@ class ImageAnalysisWindow(MainTabsType):
2480
2470
  self.parent().change_widget(3) # VideoAnalysisWindow
2481
2471
 
2482
2472
  self.popup.close()
2483
-
2484
- def closeEvent(self, event):
2485
- """
2486
- Handle the close event for a QWidget.
2487
- """
2488
- event.accept
@@ -72,8 +72,7 @@ class RequiredOutput(WindowType):
72
72
  # Create the main layout
73
73
  self.vlayout = QtWidgets.QVBoxLayout()
74
74
  self.vlayout.addWidget(self.title) #
75
- horzspaceItem = QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.MinimumExpanding)
76
- self.vlayout.addItem(horzspaceItem) #
75
+ self.vlayout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.MinimumExpanding)) #
77
76
 
78
77
  # Create the stylesheet for the boxes allowing to categorize required outputs.
79
78
  boxstylesheet = \
@@ -152,22 +151,20 @@ class RequiredOutput(WindowType):
152
151
  self.cancel.clicked.connect(self.cancel_is_clicked)
153
152
  self.ok = PButton('Ok', night_mode=self.parent().po.all['night_mode'])
154
153
  self.ok.clicked.connect(self.ok_is_clicked)
155
- self.last_row_layout.addItem(self.horizontal_space)
154
+ self.last_row_layout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
156
155
  self.last_row_layout.addWidget(self.cancel)
157
156
  self.last_row_layout.addWidget(self.ok)
158
157
 
159
- self.vlayout.addItem(horzspaceItem)
160
- vertspaceItem = QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum)
161
-
158
+ self.vlayout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.MinimumExpanding))
162
159
  self.last_row_widget.setLayout(self.last_row_layout)
163
160
  self.vlayout.addWidget(self.last_row_widget)
164
161
 
165
162
  self.hlayout = QtWidgets.QHBoxLayout()
166
163
  self.vwidget = QtWidgets.QWidget()
167
164
  self.vwidget.setLayout(self.vlayout)
168
- self.hlayout.addItem(vertspaceItem)
165
+ self.hlayout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
169
166
  self.hlayout.addWidget(self.vwidget)
170
- self.hlayout.addItem(vertspaceItem)
167
+ self.hlayout.addItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Maximum))
171
168
  self.setLayout(self.hlayout)
172
169
 
173
170
  def create_check_boxes_table(self):
@@ -264,16 +261,10 @@ class RequiredOutput(WindowType):
264
261
  self.parent().po.vars['oscilacyto_analysis'] = checked_status
265
262
  if name == 'fractal_analysis':
266
263
  self.parent().po.vars['fractal_analysis'] = checked_status
267
- if not self.parent().thread['SaveAllVars'].isRunning():
268
- self.parent().thread['SaveAllVars'].start()
264
+ if not self.parent().thread_dict['SaveAllVars'].isRunning():
265
+ self.parent().thread_dict['SaveAllVars'].start()
269
266
  self.parent().po.update_output_list()
270
267
  if self.parent().last_is_first:
271
268
  self.parent().change_widget(0) # FirstWidget
272
269
  else:
273
270
  self.parent().change_widget(3) # ThirdWidget
274
-
275
- def closeEvent(self, event):
276
- """
277
- Handle the close event for a QWidget.
278
- """
279
- event.accept