PaIRS-UniNa 0.2.9__cp312-cp312-macosx_11_0_universal2.whl → 0.2.10__cp312-cp312-macosx_11_0_universal2.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.
- PaIRS_UniNa/Calibration_Tab.py +4 -3
- PaIRS_UniNa/Changes.txt +12 -0
- PaIRS_UniNa/Explorer.py +222 -68
- PaIRS_UniNa/Input_Tab.py +2 -4
- PaIRS_UniNa/Input_Tab_CalVi.py +1 -0
- PaIRS_UniNa/Input_Tab_tools.py +14 -10
- PaIRS_UniNa/PaIRS_pypacks.py +18 -65
- PaIRS_UniNa/Process_Tab.py +19 -15
- PaIRS_UniNa/Process_Tab_Disp.py +8 -1
- PaIRS_UniNa/Saving_tools.py +2 -0
- PaIRS_UniNa/TabTools.py +165 -6
- PaIRS_UniNa/Vis_Tab.py +11 -4
- PaIRS_UniNa/Vis_Tab_CalVi.py +1 -2
- PaIRS_UniNa/_PaIRS_PIV.so +0 -0
- PaIRS_UniNa/__init__.py +3 -3
- PaIRS_UniNa/addwidgets_ps.py +570 -70
- PaIRS_UniNa/gPaIRS.py +60 -17
- PaIRS_UniNa/rqrdpckgs.txt +7 -7
- PaIRS_UniNa/ui_Calibration_Tab.py +3 -3
- PaIRS_UniNa/ui_gPairs.py +8 -8
- PaIRS_UniNa/whatsnew.txt +2 -4
- {pairs_unina-0.2.9.dist-info → pairs_unina-0.2.10.dist-info}/METADATA +7 -14
- {pairs_unina-0.2.9.dist-info → pairs_unina-0.2.10.dist-info}/RECORD +25 -25
- {pairs_unina-0.2.9.dist-info → pairs_unina-0.2.10.dist-info}/WHEEL +0 -0
- {pairs_unina-0.2.9.dist-info → pairs_unina-0.2.10.dist-info}/top_level.txt +0 -0
PaIRS_UniNa/Calibration_Tab.py
CHANGED
|
@@ -171,12 +171,12 @@ class Calibration_Tab(gPaIRS_Tab):
|
|
|
171
171
|
#*************************************************** Buttons
|
|
172
172
|
#******************** Actions
|
|
173
173
|
def button_CalVi_action(self):
|
|
174
|
-
if
|
|
174
|
+
if CALpar.FlagSPIVCal and self.ui.button_info.isVisible() and self.ui.button_CalVi.isChecked():
|
|
175
175
|
showSPIVCalHelp(self,self.dontShowAgainSPIVCalHelp)
|
|
176
176
|
self.CALpar.FlagCalVi=self.ui.button_CalVi.isChecked()
|
|
177
177
|
|
|
178
178
|
def dontShowAgainSPIVCalHelp(self):
|
|
179
|
-
|
|
179
|
+
CALpar.FlagSPIVCal = False
|
|
180
180
|
|
|
181
181
|
def button_info_action(self):
|
|
182
182
|
showSPIVCalHelp(self)
|
|
@@ -186,7 +186,7 @@ class Calibration_Tab(gPaIRS_Tab):
|
|
|
186
186
|
self.CALpar.calEx=deep_duplicate(self.ui.calTree.calEx)
|
|
187
187
|
|
|
188
188
|
def button_import_action(self):
|
|
189
|
-
if
|
|
189
|
+
if CALpar.FlagSPIVCal and self.ui.button_info.isVisible():
|
|
190
190
|
showSPIVCalHelp(self,self.dontShowAgainSPIVCalHelp)
|
|
191
191
|
filenames, _ = QFileDialog.getOpenFileNames(self,\
|
|
192
192
|
"Select calibration files from the current directory", filter='*.cal',\
|
|
@@ -311,6 +311,7 @@ class Calibration_Tab(gPaIRS_Tab):
|
|
|
311
311
|
#*************************************************** Context Menu
|
|
312
312
|
def contextMenuEvent(self, event):
|
|
313
313
|
menu=QMenu(self)
|
|
314
|
+
menu.setStyleSheet(self.gui.ui.menu.styleSheet())
|
|
314
315
|
name=[]
|
|
315
316
|
act=[]
|
|
316
317
|
fun=[]
|
PaIRS_UniNa/Changes.txt
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
********* Changes in version 0.2.10 (2026.01.05) **********
|
|
2
|
+
Bug fixes:
|
|
3
|
+
- fixed a bug affecting the "Edit list" functionality of the image-tree in the Input tab; the feature is now fully operational and behaves as expected;
|
|
4
|
+
- fixed a minor issue that could affect the correct assessment of the PIV process stability.
|
|
5
|
+
|
|
6
|
+
User-interface enhancements:
|
|
7
|
+
- minor UI restyling aimed at improving visual feedback, with clearer highlighting of widgets involved in user interactions;
|
|
8
|
+
- improved the visualization of contextual help messages, providing clearer and more consistent tooltip-like feedback within the interface;
|
|
9
|
+
- enhanced the management and restoration of global tab settings to ensure better consistency when loading previously saved workspaces.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
1
13
|
********* Changes in version 0.2.9 (2025.12.12) **********
|
|
2
14
|
Bug fixes:
|
|
3
15
|
- fixed a bug in the batch folder-copy tool enabling automatic removal of incomplete image pairs and a full re-scan of destination folders to detect and resolve any image-set mismatches.
|
PaIRS_UniNa/Explorer.py
CHANGED
|
@@ -14,11 +14,11 @@ MONTH_ABBREVIATIONS = {
|
|
|
14
14
|
1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "May", 6: "Jun",
|
|
15
15
|
7: "Jul", 8: "Aug", 9: "Sep", StepTypes.cal: "Oct", 11: "Nov", 12: "Dec"
|
|
16
16
|
}
|
|
17
|
-
projectActionButtonSize=[20,
|
|
18
|
-
processActionButtonSize=[20,
|
|
17
|
+
projectActionButtonSize=[20,25]
|
|
18
|
+
processActionButtonSize=[20,25]
|
|
19
19
|
actionButtonSpacing=3
|
|
20
|
-
processButtonSize=[40,
|
|
21
|
-
stepButtonSize=[32,
|
|
20
|
+
processButtonSize=[40,50] #icon, button
|
|
21
|
+
stepButtonSize=[32,40]
|
|
22
22
|
headerHeight=24
|
|
23
23
|
titleHeight=22
|
|
24
24
|
subtitleHeight=14
|
|
@@ -323,12 +323,28 @@ class ModernSwitch(QWidget):
|
|
|
323
323
|
self._checked = True
|
|
324
324
|
par.FlagQueue=self._checked
|
|
325
325
|
|
|
326
|
+
# --- HOVER SETUP ---
|
|
327
|
+
self.setAttribute(Qt.WA_Hover, True)
|
|
328
|
+
self.setMouseTracking(True)
|
|
329
|
+
self._hovered = False
|
|
330
|
+
self._border_width = 1
|
|
331
|
+
self._border_width_hover = 2
|
|
332
|
+
self._border_color = QColor(0, 0, 0)
|
|
333
|
+
self._border_color_hover = QColor(240, 116, 35) # highlight
|
|
334
|
+
|
|
326
335
|
# Load image for the handle and scale it to fit the ellipse
|
|
327
336
|
self.handle_image = QPixmap(icons_path+"gear.png") # Replace with your image path
|
|
328
337
|
self.handle_image = self.handle_image.scaledToHeight(self.height() - self.handleMargin*2, Qt.SmoothTransformation)
|
|
329
338
|
|
|
330
339
|
self.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
|
|
331
340
|
self.FlagAnimation=False
|
|
341
|
+
|
|
342
|
+
self.FlagRunning = False
|
|
343
|
+
self.gearMovie: QMovie = None
|
|
344
|
+
|
|
345
|
+
self._bg_color = QColor(46, 204, 113) if self._checked else QColor(175, 175, 175, 128)
|
|
346
|
+
self._handle_position = 0 # inizializzato in setSwitchLayout()
|
|
347
|
+
|
|
332
348
|
self.setSwitchLayout()
|
|
333
349
|
|
|
334
350
|
self.animation = QPropertyAnimation(self, b"handle_position", self)
|
|
@@ -357,20 +373,35 @@ class ModernSwitch(QWidget):
|
|
|
357
373
|
if par and self.gui.procdata:
|
|
358
374
|
if self.gui.procdata.ind[:-2]==par.ind[:-2]:
|
|
359
375
|
self.startTimer()
|
|
360
|
-
#self.timer.start(50) # Aggiorna ogni 50 ms
|
|
361
376
|
|
|
377
|
+
# ----------------- Hover events -----------------
|
|
378
|
+
def enterEvent(self, event):
|
|
379
|
+
self._hovered = True
|
|
380
|
+
self.update()
|
|
381
|
+
super().enterEvent(event)
|
|
382
|
+
|
|
383
|
+
def leaveEvent(self, event):
|
|
384
|
+
self._hovered = False
|
|
385
|
+
self.update()
|
|
386
|
+
super().leaveEvent(event)
|
|
387
|
+
|
|
388
|
+
# ----------------- Timer control -----------------
|
|
362
389
|
def startTimer(self):
|
|
363
390
|
if not self.FlagRunning and hasattr(self.gui,'gearMovie'):
|
|
364
391
|
self.FlagRunning=True
|
|
365
392
|
self.gearMovie=self.gui.gearMovie
|
|
366
393
|
self.timer.start(self.timerTime)
|
|
367
|
-
|
|
394
|
+
try:
|
|
395
|
+
pri.Coding.yellow('Start switch timer')
|
|
396
|
+
except Exception:
|
|
397
|
+
pass
|
|
368
398
|
|
|
369
399
|
def stopTimer(self):
|
|
370
400
|
if self.FlagRunning:
|
|
371
401
|
self.FlagRunning=False
|
|
372
402
|
self.timer.stop()
|
|
373
403
|
|
|
404
|
+
# ----------------- Property animation -----------------
|
|
374
405
|
def set_handle_position(self, pos):
|
|
375
406
|
self._handle_position = pos
|
|
376
407
|
self.update()
|
|
@@ -380,90 +411,98 @@ class ModernSwitch(QWidget):
|
|
|
380
411
|
|
|
381
412
|
handle_position = Property(int, fget=get_handle_position, fset=set_handle_position)
|
|
382
413
|
|
|
414
|
+
# ----------------- Painting -----------------
|
|
383
415
|
def paintEvent(self, event):
|
|
384
416
|
painter = QPainter(self)
|
|
385
417
|
painter.setRenderHint(QPainter.Antialiasing)
|
|
386
418
|
|
|
387
|
-
#
|
|
388
|
-
bg_rect = QRect(0, 0, self.width(), self.height())
|
|
389
|
-
|
|
390
|
-
#
|
|
419
|
+
# Background rect (rounded)
|
|
420
|
+
bg_rect = QRect(0, 0, self.width(), self.height()).adjusted(1, 1, -1, -1)
|
|
421
|
+
|
|
422
|
+
# Border pen (changes on hover)
|
|
423
|
+
if not self.isEnabled():
|
|
424
|
+
pen = QPen(self._border_color)
|
|
425
|
+
pen.setWidth(self._border_width)
|
|
426
|
+
else:
|
|
427
|
+
pen = QPen(self._border_color_hover if self._hovered else self._border_color)
|
|
428
|
+
pen.setWidth(self._border_width_hover if self._hovered else self._border_width)
|
|
429
|
+
|
|
430
|
+
painter.setPen(pen)
|
|
391
431
|
painter.setBrush(self._bg_color)
|
|
392
|
-
painter.drawRoundedRect(bg_rect
|
|
432
|
+
painter.drawRoundedRect(bg_rect, self.height() / 2, self.height() / 2)
|
|
393
433
|
|
|
394
|
-
#
|
|
434
|
+
# Handle position and size
|
|
395
435
|
handle_x = self._handle_position
|
|
396
436
|
handle_y = self.handleMargin
|
|
397
|
-
|
|
398
|
-
|
|
437
|
+
handle_w = self.handle_image.width()
|
|
438
|
+
handle_h = self.handle_image.height()
|
|
439
|
+
handle_rect = QRect(handle_x, handle_y, handle_w, handle_h)
|
|
399
440
|
|
|
400
|
-
|
|
401
|
-
if self.
|
|
402
|
-
|
|
403
|
-
handle_rect = QRect(handle_x, handle_y, handle_width, handle_height)
|
|
404
|
-
painter.drawPixmap(handle_rect, self.handle_image)
|
|
405
|
-
else:
|
|
406
|
-
# Draw handle circle
|
|
407
|
-
handle_radius = self.height() - self.handleMargin*2
|
|
408
|
-
handle_rect = QRect(self._handle_position, self.handleMargin, handle_radius, handle_radius)
|
|
409
|
-
painter.setBrush(Qt.white)
|
|
410
|
-
painter.drawEllipse(handle_rect)
|
|
411
|
-
"""
|
|
412
|
-
handle_rect = QRect(handle_x, handle_y, handle_width, handle_height)
|
|
413
|
-
#painter.drawPixmap(handle_rect, self.handle_image)
|
|
414
|
-
if self.FlagRunning:
|
|
415
|
-
painter.drawImage(handle_rect,self.gearMovie.currentImage())
|
|
441
|
+
# Draw gear (static or animated)
|
|
442
|
+
if self.FlagRunning and self.gearMovie is not None:
|
|
443
|
+
painter.drawImage(handle_rect, self.gearMovie.currentImage())
|
|
416
444
|
else:
|
|
417
|
-
painter.drawImage(handle_rect,self.handle_image.toImage())
|
|
418
|
-
|
|
445
|
+
painter.drawImage(handle_rect, self.handle_image.toImage())
|
|
446
|
+
|
|
447
|
+
# Draw label text
|
|
419
448
|
if self.FlagAnimation:
|
|
420
449
|
self.text_label.setText("")
|
|
421
450
|
else:
|
|
422
451
|
if self._checked:
|
|
423
452
|
self.text_label.setText("run ")
|
|
424
|
-
self.text_label.
|
|
453
|
+
self.text_label.adjustSize()
|
|
454
|
+
self.text_label.move(self.handleMargin * 2, (self.height() - self.text_label.height()) // 2)
|
|
425
455
|
else:
|
|
426
456
|
self.text_label.setText("skip")
|
|
427
|
-
self.text_label.
|
|
457
|
+
self.text_label.adjustSize()
|
|
458
|
+
self.text_label.move(self.width() - self.height() - self.handleMargin * 2,
|
|
459
|
+
(self.height() - self.text_label.height()) // 2)
|
|
428
460
|
|
|
461
|
+
# ----------------- Interaction -----------------
|
|
429
462
|
def mousePressEvent(self, event):
|
|
430
|
-
if event.button() == Qt.LeftButton and not self.FlagAnimation:
|
|
463
|
+
if event.button() == Qt.LeftButton and not self.FlagAnimation and self.isEnabled():
|
|
431
464
|
self.toggle()
|
|
432
465
|
|
|
433
466
|
def toggle(self):
|
|
434
467
|
self._checked = not self._checked
|
|
435
|
-
if self.par:
|
|
468
|
+
if self.par:
|
|
469
|
+
self.par.FlagQueue = self._checked
|
|
470
|
+
|
|
436
471
|
self.toggled.emit(self._checked)
|
|
472
|
+
|
|
473
|
+
self.animation.stop()
|
|
474
|
+
self.animation.setStartValue(self._handle_position)
|
|
437
475
|
self.animation.setEndValue(self.switchHandlePosition())
|
|
438
|
-
self.FlagAnimation=True
|
|
476
|
+
self.FlagAnimation = True
|
|
439
477
|
self.animation.start()
|
|
440
|
-
|
|
478
|
+
|
|
479
|
+
# ----------------- Layout helpers -----------------
|
|
441
480
|
def switchHandlePosition(self):
|
|
442
481
|
if self._checked:
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
handle_position = self.handleMargin
|
|
446
|
-
return handle_position
|
|
482
|
+
return self.width() - self.height() + self.handleMargin
|
|
483
|
+
return self.handleMargin
|
|
447
484
|
|
|
448
485
|
def setSwitchLayout(self):
|
|
449
|
-
self.FlagAnimation=False
|
|
486
|
+
self.FlagAnimation = False
|
|
450
487
|
if self._checked:
|
|
451
|
-
self._bg_color = QColor(46, 204, 113)
|
|
452
|
-
tip=f'{self.name if self.name else "Item"} added to run queue.'
|
|
488
|
+
self._bg_color = QColor(46, 204, 113)
|
|
489
|
+
tip = f'{self.name if self.name else "Item"} added to run queue.'
|
|
453
490
|
else:
|
|
454
|
-
tip=f'{self.name if self.name else "Item"} excluded from run queue.'
|
|
455
|
-
#text_color = self.palette().color(QPalette.WindowText)
|
|
456
491
|
self._bg_color = QColor(175, 175, 175)
|
|
457
|
-
self._bg_color.setAlpha(
|
|
492
|
+
self._bg_color.setAlpha(64)
|
|
493
|
+
tip = f'{self.name if self.name else "Item"} excluded from run queue.'
|
|
494
|
+
|
|
458
495
|
self.setToolTip(tip)
|
|
459
496
|
self.setStatusTip(tip)
|
|
460
497
|
self.set_handle_position(self.switchHandlePosition())
|
|
461
498
|
|
|
462
|
-
def setSwitch(self,FlagChecked):
|
|
463
|
-
if FlagChecked!=self._checked:
|
|
464
|
-
self._checked=FlagChecked
|
|
499
|
+
def setSwitch(self, FlagChecked: bool):
|
|
500
|
+
if FlagChecked != self._checked:
|
|
501
|
+
self._checked = FlagChecked
|
|
502
|
+
if self.par:
|
|
503
|
+
self.par.FlagQueue = self._checked
|
|
465
504
|
self.setSwitchLayout()
|
|
466
|
-
|
|
505
|
+
|
|
467
506
|
class ActionButtonBar(QWidget):
|
|
468
507
|
FlagShortCuts = True
|
|
469
508
|
|
|
@@ -495,7 +534,7 @@ class ActionButtonBar(QWidget):
|
|
|
495
534
|
setattr(self,'sep_'+icon_name[1:],separator)
|
|
496
535
|
self.buttonLayout.addWidget(separator)
|
|
497
536
|
else:
|
|
498
|
-
b =
|
|
537
|
+
b = HoverZoomToolButton(self)
|
|
499
538
|
b.setObjectName('button_'+icon_name)
|
|
500
539
|
b.setCursor(Qt.CursorShape.PointingHandCursor)
|
|
501
540
|
if FlagInvisible:
|
|
@@ -560,6 +599,7 @@ class ActionButtonBar(QWidget):
|
|
|
560
599
|
tree.FlagContexMenu=True
|
|
561
600
|
|
|
562
601
|
menu=QMenu(tree)
|
|
602
|
+
menu.setStyleSheet(self.window().ui.menu.styleSheet())
|
|
563
603
|
name=[]
|
|
564
604
|
act=[]
|
|
565
605
|
fun=[]
|
|
@@ -578,7 +618,7 @@ class ActionButtonBar(QWidget):
|
|
|
578
618
|
if FlagNamedBar and 'class' in bar.buttonData[type]:
|
|
579
619
|
if 'PIV'!=nameAction[:3]: nameAction=nameAction[:1].lower()+nameAction[1:]
|
|
580
620
|
if b.isCheckable():
|
|
581
|
-
nameAction=
|
|
621
|
+
nameAction=b.toolTip()
|
|
582
622
|
else:
|
|
583
623
|
nameAction='Add '+nameAction
|
|
584
624
|
act.append(QAction(b.icon(),nameAction,self))
|
|
@@ -1039,7 +1079,63 @@ class ProjectTree(PaIRSTree):
|
|
|
1039
1079
|
self.actionBar.button_close.setEnabled(FlagEnabled)
|
|
1040
1080
|
self.actionBar.button_clean.setEnabled(self.topLevelItemCount()>0)
|
|
1041
1081
|
|
|
1042
|
-
class
|
|
1082
|
+
class HoverZoomToolButton(QToolButton):
|
|
1083
|
+
def __init__(self, parent=None, base_icon=24, zoom=1.25):
|
|
1084
|
+
super().__init__(parent)
|
|
1085
|
+
|
|
1086
|
+
self.zoom_factor = zoom
|
|
1087
|
+
self.base_size = QSize(base_icon, base_icon)
|
|
1088
|
+
self.zoom_size = QSize(
|
|
1089
|
+
int(base_icon * zoom),
|
|
1090
|
+
int(base_icon * zoom)
|
|
1091
|
+
)
|
|
1092
|
+
|
|
1093
|
+
self.setIconSize(self.base_size)
|
|
1094
|
+
|
|
1095
|
+
self.anim = QPropertyAnimation(self, b"iconSize", self)
|
|
1096
|
+
self.anim.setDuration(120)
|
|
1097
|
+
self.anim.setEasingCurve(QEasingCurve.OutCubic)
|
|
1098
|
+
|
|
1099
|
+
# --- OVERRIDE ---
|
|
1100
|
+
def setIconSize(self, size: QSize):
|
|
1101
|
+
"""
|
|
1102
|
+
Override setIconSize to automatically update base and zoom sizes.
|
|
1103
|
+
"""
|
|
1104
|
+
super().setIconSize(size)
|
|
1105
|
+
self.updateFromCurrentIconSize()
|
|
1106
|
+
|
|
1107
|
+
def updateFromCurrentIconSize(self, zoom: float | None = None):
|
|
1108
|
+
"""
|
|
1109
|
+
Recompute base_size and zoom_size starting from the current iconSize().
|
|
1110
|
+
Optionally updates the zoom factor.
|
|
1111
|
+
"""
|
|
1112
|
+
if zoom is not None:
|
|
1113
|
+
self.zoom_factor = zoom
|
|
1114
|
+
|
|
1115
|
+
current = self.iconSize()
|
|
1116
|
+
self.base_size = QSize(current.width(), current.height())
|
|
1117
|
+
self.zoom_size = QSize(
|
|
1118
|
+
int(current.width() * self.zoom_factor),
|
|
1119
|
+
int(current.height() * self.zoom_factor)
|
|
1120
|
+
)
|
|
1121
|
+
|
|
1122
|
+
def enterEvent(self, event):
|
|
1123
|
+
if self.isEnabled():
|
|
1124
|
+
self.anim.stop()
|
|
1125
|
+
self.anim.setStartValue(self.iconSize())
|
|
1126
|
+
self.anim.setEndValue(self.zoom_size)
|
|
1127
|
+
self.anim.start()
|
|
1128
|
+
super().enterEvent(event)
|
|
1129
|
+
|
|
1130
|
+
def leaveEvent(self, event):
|
|
1131
|
+
if self.isEnabled():
|
|
1132
|
+
self.anim.stop()
|
|
1133
|
+
self.anim.setStartValue(self.iconSize())
|
|
1134
|
+
self.anim.setEndValue(self.base_size)
|
|
1135
|
+
self.anim.start()
|
|
1136
|
+
super().leaveEvent(event)
|
|
1137
|
+
|
|
1138
|
+
class DraggableButton(HoverZoomToolButton):
|
|
1043
1139
|
def __init__(self, data: dict = {}, buttonSize: list = processButtonSize, FlagInvisible=True, parent=None):
|
|
1044
1140
|
super().__init__(parent)
|
|
1045
1141
|
self.buttonData = data
|
|
@@ -1052,6 +1148,7 @@ class DraggableButton(QToolButton):
|
|
|
1052
1148
|
self.setIconSize(QSize(self.buttonSize[0], self.buttonSize[0]))
|
|
1053
1149
|
self.setIcon(self.buttonIcon)
|
|
1054
1150
|
self.setFixedSize(self.buttonSize[1], self.buttonSize[1])
|
|
1151
|
+
|
|
1055
1152
|
if FlagInvisible:
|
|
1056
1153
|
self.setCursor(Qt.CursorShape.OpenHandCursor)
|
|
1057
1154
|
self.setStyleSheet("QToolButton { border: none; background: none;} QToolButton::menu-indicator { image: none; }")
|
|
@@ -1103,7 +1200,7 @@ class ProcessButtonBar(QWidget):
|
|
|
1103
1200
|
super().__init__()
|
|
1104
1201
|
self.buttonLayout = QHBoxLayout()
|
|
1105
1202
|
self.buttonLayout.setContentsMargins(0, 0, 0, 0)
|
|
1106
|
-
self.buttonLayout.setSpacing(int(buttonSize[0]
|
|
1203
|
+
self.buttonLayout.setSpacing(int(buttonSize[0]/4))
|
|
1107
1204
|
self.setLayout(self.buttonLayout)
|
|
1108
1205
|
self.buttonData=buttonData
|
|
1109
1206
|
self.buttonSize = buttonSize
|
|
@@ -1123,7 +1220,7 @@ class StepButtonBar(QWidget):
|
|
|
1123
1220
|
super().__init__()
|
|
1124
1221
|
self.buttonLayout = QVBoxLayout()
|
|
1125
1222
|
self.buttonLayout.setContentsMargins(10, headerHeight+5, 0, 10)
|
|
1126
|
-
self.buttonLayout.setSpacing(int(buttonSize[0]/
|
|
1223
|
+
self.buttonLayout.setSpacing(int(buttonSize[0]/4))
|
|
1127
1224
|
self.setLayout(self.buttonLayout)
|
|
1128
1225
|
self.buttonData=buttonData
|
|
1129
1226
|
self.buttonSize = buttonSize
|
|
@@ -1135,8 +1232,7 @@ class StepButtonBar(QWidget):
|
|
|
1135
1232
|
data=buttonData[type]
|
|
1136
1233
|
|
|
1137
1234
|
if all([f in list(data) for f in ('icon', 'name', 'type')]):
|
|
1138
|
-
button =
|
|
1139
|
-
button.setIconSize(QSize(self.buttonSize[0], self.buttonSize[0]))
|
|
1235
|
+
button = HoverZoomToolButton(self, base_icon=self.buttonSize[0], zoom=1.25)
|
|
1140
1236
|
button.setFixedSize(self.buttonSize[1], self.buttonSize[1])
|
|
1141
1237
|
|
|
1142
1238
|
if FlagInvisible:
|
|
@@ -1223,7 +1319,7 @@ class ProcessTree(PaIRSTree):
|
|
|
1223
1319
|
|
|
1224
1320
|
if self.FlagBin:
|
|
1225
1321
|
columns=["#","Deleted processes"]
|
|
1226
|
-
self.setStyleSheet("""
|
|
1322
|
+
self.setStyleSheet(self.styleSheet() + """
|
|
1227
1323
|
QHeaderView::section {
|
|
1228
1324
|
color: red;
|
|
1229
1325
|
}
|
|
@@ -2350,7 +2446,8 @@ class PaIRS_Explorer(gPaIRS_Tab):
|
|
|
2350
2446
|
self.main_layout.addWidget(self.Explorer_main_splitter)
|
|
2351
2447
|
|
|
2352
2448
|
# Creazione del pulsante checkable
|
|
2353
|
-
self.binButton =
|
|
2449
|
+
self.binButton = HoverZoomToolButton(self.processButtonBar)
|
|
2450
|
+
self.binButton.setObjectName('binButton')
|
|
2354
2451
|
self.binButton.setIconSize(QSize(self.processButtonBar.buttonSize[0], self.processButtonBar.buttonSize[0]))
|
|
2355
2452
|
self.binButton.setFixedSize(self.processButtonBar.buttonSize[1], self.processButtonBar.buttonSize[1])
|
|
2356
2453
|
if self.processButtonBar.FlagInvisible:
|
|
@@ -2431,7 +2528,7 @@ class PaIRS_Explorer(gPaIRS_Tab):
|
|
|
2431
2528
|
tree.setCurrentItem(child)
|
|
2432
2529
|
self.processTree_item_selection(tree)
|
|
2433
2530
|
else:
|
|
2434
|
-
|
|
2531
|
+
show_mouse_tooltip(self,'Current step is disabled! Please, reset the subsequemt step in the process to access it.')
|
|
2435
2532
|
for t,b in self.stepButtonBar.buttons.items():
|
|
2436
2533
|
b:QToolButton
|
|
2437
2534
|
b.clicked.connect(lambda flag, butt=b, type=t: stepButtonAction(butt, type))
|
|
@@ -2546,13 +2643,22 @@ class PaIRS_Explorer(gPaIRS_Tab):
|
|
|
2546
2643
|
if item.childCount()>ind:
|
|
2547
2644
|
item_child=item.child(ind)
|
|
2548
2645
|
item_child.setHidden(not ITEs[ind+1].active)
|
|
2549
|
-
b.setVisible(
|
|
2550
|
-
|
|
2646
|
+
b.setVisible(True)
|
|
2647
|
+
#b.setVisible(c not in ITEs[0].mandatory) #b.setVisible(True)
|
|
2648
|
+
#lab.setVisible(c in ITEs[0].mandatory)
|
|
2551
2649
|
flagRunnable=all([ITEs[j].flagRun==0 for j in range(ind+2,nsteps+1)]) if ind<nsteps else True
|
|
2552
2650
|
flagRunnable=flagRunnable and ITEs[ind+1].flagRun==0 and ITEs[0].flagRun!=-2 #and len(ITEs[ind+1].link)==0
|
|
2553
2651
|
b.setEnabled(flagRunnable)
|
|
2554
|
-
lab.setEnabled(flagRunnable)
|
|
2652
|
+
#lab.setEnabled(flagRunnable)
|
|
2555
2653
|
b.setChecked(ITEs[ind+1].active)
|
|
2654
|
+
nameAction=ITEs[ind+1].name
|
|
2655
|
+
if 'PIV'!=nameAction[:3]: nameAction=nameAction[:1].lower()+nameAction[1:]
|
|
2656
|
+
if c not in ITEs[0].mandatory:
|
|
2657
|
+
nameAction=f"{'De-activate' if b.isChecked() else 'Activate'} {nameAction}"
|
|
2658
|
+
else:
|
|
2659
|
+
nameAction=f"{'Go to and edit'} {nameAction}"
|
|
2660
|
+
b.setToolTip(nameAction)
|
|
2661
|
+
b.setStatusTip(nameAction)
|
|
2556
2662
|
else:
|
|
2557
2663
|
flagRunnable=False
|
|
2558
2664
|
b.setVisible(False)
|
|
@@ -2562,10 +2668,27 @@ class PaIRS_Explorer(gPaIRS_Tab):
|
|
|
2562
2668
|
b.setChecked(False)
|
|
2563
2669
|
b.setButtonIcon()
|
|
2564
2670
|
if self.stepPage:
|
|
2565
|
-
|
|
2671
|
+
FlagChild=c in ITEs[0].children
|
|
2672
|
+
self.stepPage.items[c].setVisible(FlagChild) #and b.isChecked())
|
|
2673
|
+
FlagEnabled=b.isEnabled() or b.isChecked()
|
|
2674
|
+
self.stepPage.items[c].setEnabled(FlagEnabled)
|
|
2566
2675
|
pageButton:QPushButton=self.stepPage.items[c].findChildren(QPushButton)[0]
|
|
2676
|
+
|
|
2677
|
+
if FlagChild:
|
|
2678
|
+
ind=list(ITEs[0].children).index(c)
|
|
2679
|
+
nameAction=ITEs[ind+1].name
|
|
2680
|
+
nameAction_lowerCase=nameAction[:1].lower()+nameAction[1:] if 'PIV'!=nameAction[:3] else nameAction
|
|
2681
|
+
if b.isEnabled():
|
|
2682
|
+
toolTip="Go to and edit " + nameAction_lowerCase if b.isChecked() else b.toolTip()
|
|
2683
|
+
else:
|
|
2684
|
+
toolTip="Go to and view " + nameAction_lowerCase if b.isChecked() else nameAction+" step was excluded from the process!"
|
|
2685
|
+
self.stepPage.items[c].setToolTip(toolTip)
|
|
2686
|
+
self.stepPage.items[c].setStatusTip(toolTip)
|
|
2687
|
+
|
|
2688
|
+
self.stepPage.setProcessTextActive(not (b.isEnabled() and not b.isChecked()),c)
|
|
2689
|
+
|
|
2567
2690
|
if flagRunnable:
|
|
2568
|
-
pageButton.setIcon(b.icon())
|
|
2691
|
+
pageButton.setIcon(b.icon())
|
|
2569
2692
|
else:
|
|
2570
2693
|
pageButton.setIcon(b.iconOn)
|
|
2571
2694
|
else:
|
|
@@ -3007,6 +3130,7 @@ class StartingPage(QFrame):
|
|
|
3007
3130
|
button_margin=self.ITEM_HEIGHT-self.ICON_SIZE-self.BUTTON_LAYOUT_TOP_MARGIN
|
|
3008
3131
|
CAPTION_HEIGHT=self.ITEM_HEIGHT-self.NAME_LABEL_HEIGHT-self.TEXT_LAYOUT_SPACING
|
|
3009
3132
|
self.items={}
|
|
3133
|
+
self.textItems={}
|
|
3010
3134
|
# Itera sui dizionari nella lista
|
|
3011
3135
|
for n, process in processes.items():
|
|
3012
3136
|
# Layout orizzontale per ogni processo
|
|
@@ -3014,7 +3138,7 @@ class StartingPage(QFrame):
|
|
|
3014
3138
|
widget.setObjectName("process_item")
|
|
3015
3139
|
widget.setStyleSheet("""
|
|
3016
3140
|
QWidget#process_item:hover {
|
|
3017
|
-
background-color: rgba(
|
|
3141
|
+
background-color: rgba(0, 116, 255, 0.1);
|
|
3018
3142
|
border-radius: 10px;
|
|
3019
3143
|
}
|
|
3020
3144
|
""")
|
|
@@ -3028,6 +3152,7 @@ class StartingPage(QFrame):
|
|
|
3028
3152
|
button_layout.setContentsMargins(0, self.BUTTON_LAYOUT_TOP_MARGIN, 0, button_margin)
|
|
3029
3153
|
|
|
3030
3154
|
icon_button = QPushButton()
|
|
3155
|
+
icon_button.setObjectName("StartingPage_Button")
|
|
3031
3156
|
pixmap = QPixmap(icons_path+process['icon']).scaled(self.ICON_SIZE, self.ICON_SIZE, mode=Qt.TransformationMode.SmoothTransformation)
|
|
3032
3157
|
icon_button.setIcon(pixmap)
|
|
3033
3158
|
icon_button.setIconSize(pixmap.size())
|
|
@@ -3112,6 +3237,10 @@ class StartingPage(QFrame):
|
|
|
3112
3237
|
#make_clickable(caption_text_edit, click_callback)
|
|
3113
3238
|
|
|
3114
3239
|
self.items[n]=widget
|
|
3240
|
+
self.textItems[n]={
|
|
3241
|
+
"name_label": name_label,
|
|
3242
|
+
"caption": caption_text_edit,
|
|
3243
|
+
}
|
|
3115
3244
|
|
|
3116
3245
|
self.main_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding))
|
|
3117
3246
|
|
|
@@ -3136,6 +3265,31 @@ class StartingPage(QFrame):
|
|
|
3136
3265
|
caption_font.setPixelSize(CAPTION_FONT_SIZE)
|
|
3137
3266
|
c.setFont(caption_font)
|
|
3138
3267
|
|
|
3268
|
+
def setProcessTextActive(self, active: bool, key=None):
|
|
3269
|
+
"""
|
|
3270
|
+
If active=True -> black text (active)
|
|
3271
|
+
If active=False -> light bluish text (inactive)
|
|
3272
|
+
If key is None -> apply to all items
|
|
3273
|
+
If key is provided -> apply only to that process key
|
|
3274
|
+
"""
|
|
3275
|
+
active_color = "none"
|
|
3276
|
+
inactive_color = "rgb(150, 150, 255)"
|
|
3277
|
+
|
|
3278
|
+
color = active_color if active else inactive_color
|
|
3279
|
+
|
|
3280
|
+
def apply_to(item):
|
|
3281
|
+
item["name_label"].setStyleSheet(f"color: {color};")
|
|
3282
|
+
# QTextEdit draws text in its viewport -> set color on QTextEdit itself is fine
|
|
3283
|
+
item["caption"].setStyleSheet(f"color: {color}; background: transparent;")
|
|
3284
|
+
|
|
3285
|
+
if key is None:
|
|
3286
|
+
for item in self.textItems.values():
|
|
3287
|
+
apply_to(item)
|
|
3288
|
+
else:
|
|
3289
|
+
if key in self.textItems:
|
|
3290
|
+
apply_to(self.textItems[key])
|
|
3291
|
+
|
|
3292
|
+
|
|
3139
3293
|
if __name__ == "__main__":
|
|
3140
3294
|
app = QApplication([])
|
|
3141
3295
|
app.setStyle('Fusion')
|
PaIRS_UniNa/Input_Tab.py
CHANGED
|
@@ -611,6 +611,7 @@ class Input_Tab(gPaIRS_Tab):
|
|
|
611
611
|
|
|
612
612
|
def button_example_list_action(self):
|
|
613
613
|
INPpar.FlagExample=self.ui.button_example_list.isChecked()
|
|
614
|
+
self.layoutExampleImageList()
|
|
614
615
|
self.containerExImTree.setVisible(INPpar.FlagExample)
|
|
615
616
|
return True
|
|
616
617
|
|
|
@@ -643,10 +644,7 @@ class Input_Tab(gPaIRS_Tab):
|
|
|
643
644
|
|
|
644
645
|
@Slot(str)
|
|
645
646
|
def show_import_tooltip(self, msg: str):
|
|
646
|
-
|
|
647
|
-
pos = btn.mapToGlobal(btn.rect().center())
|
|
648
|
-
QToolTip.showText(pos, msg, btn)
|
|
649
|
-
QTimer.singleShot(2000, QToolTip.hideText)
|
|
647
|
+
show_mouse_tooltip(self,msg)
|
|
650
648
|
|
|
651
649
|
#******************** Settings
|
|
652
650
|
"""
|
PaIRS_UniNa/Input_Tab_CalVi.py
CHANGED
|
@@ -178,6 +178,7 @@ class Input_Tab_CalVi(gPaIRS_Tab):
|
|
|
178
178
|
|
|
179
179
|
def listContextMenuEvent(self, list_images:QTableWidget, event):
|
|
180
180
|
menu=QMenu(list_images)
|
|
181
|
+
menu.setStyleSheet(self.gui.ui.menu.styleSheet())
|
|
181
182
|
buttons=['import', 'import_plane',
|
|
182
183
|
-1,'down','up',
|
|
183
184
|
-1,'delete','clean']
|
PaIRS_UniNa/Input_Tab_tools.py
CHANGED
|
@@ -477,6 +477,9 @@ class PaIRSTree(QTreeWidget):
|
|
|
477
477
|
#self.setStyleSheet(f"QTreeWidget::item:selected:active {{{style}}}")
|
|
478
478
|
|
|
479
479
|
style = """
|
|
480
|
+
QTreeWidget::item:hover {
|
|
481
|
+
background-color: rgba(0, 116, 255, 0.1);
|
|
482
|
+
}
|
|
480
483
|
QTreeWidget::item:selected:!active {
|
|
481
484
|
background-color: rgba(0, 116, 255, 0.4);
|
|
482
485
|
}
|
|
@@ -1209,7 +1212,7 @@ class GlobalImageTree(AsynPaIRSTree):
|
|
|
1209
1212
|
header.setSectionResizeMode(2, QHeaderView.ResizeMode.Interactive)
|
|
1210
1213
|
self.headerItem().setTextAlignment(0,Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
|
|
1211
1214
|
self.setUniformRowHeights(True)
|
|
1212
|
-
self.setStyleSheet(f"QTreeView::item {{ height: {self.default_row_height} px; }}")
|
|
1215
|
+
self.setStyleSheet(self.styleSheet()+f"QTreeView::item {{ height: {self.default_row_height} px; }}")
|
|
1213
1216
|
|
|
1214
1217
|
self.path=''
|
|
1215
1218
|
self.ncam=1
|
|
@@ -1320,11 +1323,11 @@ class GlobalImageTree(AsynPaIRSTree):
|
|
|
1320
1323
|
topLevelItem.setIcon(0,self.icon_warning)
|
|
1321
1324
|
topLevelItem.setToolTip(0,'Files (!) missing')
|
|
1322
1325
|
topLevelItem.setStatusTip(0,'Files (!) missing')
|
|
1323
|
-
|
|
1326
|
+
elif k in self.warns:
|
|
1324
1327
|
self.warns.remove(k)
|
|
1325
1328
|
topLevelItem.setIcon(0,QIcon())
|
|
1326
1329
|
topLevelItem.setToolTip(0,'')
|
|
1327
|
-
topLevelItem.setStatusTip(0,'
|
|
1330
|
+
topLevelItem.setStatusTip(0,'')
|
|
1328
1331
|
return
|
|
1329
1332
|
for k in range(self.topLevelItemCount()): scan_items(k)
|
|
1330
1333
|
self.resetImNumber()
|
|
@@ -1817,7 +1820,7 @@ class ImageTreeWidget(QWidget):
|
|
|
1817
1820
|
self.imTree.setVisible(True)
|
|
1818
1821
|
self.imTree.keyPressEvent=lambda e: self.treeKeyPressEvent(e)
|
|
1819
1822
|
self.imTree.installEventFilter(self)
|
|
1820
|
-
|
|
1823
|
+
|
|
1821
1824
|
self.FlagSettingPar=None
|
|
1822
1825
|
|
|
1823
1826
|
def eventFilter(self, obj, event):
|
|
@@ -2417,6 +2420,7 @@ class ImageTreeWidget(QWidget):
|
|
|
2417
2420
|
item=tree.currentItem()
|
|
2418
2421
|
if not item: return
|
|
2419
2422
|
menu=QMenu(tree)
|
|
2423
|
+
menu.setStyleSheet(self.window().ui.menu.styleSheet())
|
|
2420
2424
|
name=[]
|
|
2421
2425
|
act=[]
|
|
2422
2426
|
fun=[]
|
|
@@ -2465,7 +2469,7 @@ class CalibrationTree(PaIRSTree):
|
|
|
2465
2469
|
header=self.header()
|
|
2466
2470
|
header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
|
|
2467
2471
|
header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
|
|
2468
|
-
self.setStyleSheet(f"QTreeView::item {{ height: {self.default_row_height} px; }}")
|
|
2472
|
+
self.setStyleSheet(self.styleSheet()+f"QTreeView::item {{ height: {self.default_row_height} px; }}")
|
|
2469
2473
|
self.headerItem().setTextAlignment(0,Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
|
|
2470
2474
|
|
|
2471
2475
|
self.ncam=1
|
|
@@ -2626,15 +2630,15 @@ class PaIRSTable(QTableWidget):
|
|
|
2626
2630
|
|
|
2627
2631
|
self.pen = QPen(qRgba(127,227,255,0.9))
|
|
2628
2632
|
self.pen.setWidth(3)
|
|
2629
|
-
#style="background-color: rgba(173,216,230,0.1); color: rgba(128,128,128,0.25);"
|
|
2630
|
-
#self.setStyleSheet(f"QTreeWidget::item:selected {{{style}}}")
|
|
2631
|
-
#self.setStyleSheet(f"QTreeWidget::item:selected:active {{{style}}}")
|
|
2632
2633
|
|
|
2633
2634
|
style = """
|
|
2634
|
-
|
|
2635
|
+
QTableWidget::item:hover {
|
|
2636
|
+
background-color: rgba(0, 116, 255, 0.1);
|
|
2637
|
+
}
|
|
2638
|
+
QTableWidget::item:selected:!active {
|
|
2635
2639
|
background-color: rgba(0, 116, 255, 0.4);
|
|
2636
2640
|
}
|
|
2637
|
-
|
|
2641
|
+
QTableWidget::item:selected:active {
|
|
2638
2642
|
background-color: rgba(0, 116, 255, 0.8);
|
|
2639
2643
|
}
|
|
2640
2644
|
"""
|