PaIRS-UniNa 0.2.10__cp313-cp313-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 +347 -0
- PaIRS_UniNa/Changes.txt +174 -0
- PaIRS_UniNa/Custom_Top.py +303 -0
- PaIRS_UniNa/Explorer.py +3322 -0
- PaIRS_UniNa/FolderLoop.py +562 -0
- PaIRS_UniNa/Input_Tab.py +829 -0
- PaIRS_UniNa/Input_Tab_CalVi.py +787 -0
- PaIRS_UniNa/Input_Tab_tools.py +3026 -0
- PaIRS_UniNa/Log_Tab.py +110 -0
- PaIRS_UniNa/Output_Tab.py +922 -0
- PaIRS_UniNa/PaIRS.py +18 -0
- PaIRS_UniNa/PaIRS_PIV.py +873 -0
- PaIRS_UniNa/PaIRS_pypacks.py +1374 -0
- PaIRS_UniNa/Process_Tab.py +1761 -0
- PaIRS_UniNa/Process_Tab_CalVi.py +313 -0
- PaIRS_UniNa/Process_Tab_Disp.py +170 -0
- PaIRS_UniNa/Process_Tab_Min.py +120 -0
- PaIRS_UniNa/ResizePopup.py +55 -0
- PaIRS_UniNa/SPIVCalHelp.py +155 -0
- PaIRS_UniNa/Saving_tools.py +298 -0
- PaIRS_UniNa/TabTools.py +1413 -0
- PaIRS_UniNa/Vis_Tab.py +2176 -0
- PaIRS_UniNa/Vis_Tab_CalVi.py +982 -0
- PaIRS_UniNa/Whatsnew.py +130 -0
- PaIRS_UniNa/_PaIRS_PIV.so +0 -0
- PaIRS_UniNa/__init__.py +6 -0
- PaIRS_UniNa/__main__.py +45 -0
- PaIRS_UniNa/addwidgets_ps.py +1633 -0
- PaIRS_UniNa/calib.py +1488 -0
- PaIRS_UniNa/calibView.py +833 -0
- PaIRS_UniNa/gPaIRS.py +3957 -0
- PaIRS_UniNa/gPalette.py +189 -0
- PaIRS_UniNa/icons/abort.png +0 -0
- PaIRS_UniNa/icons/about.png +0 -0
- PaIRS_UniNa/icons/align_all.png +0 -0
- PaIRS_UniNa/icons/announcement.png +0 -0
- PaIRS_UniNa/icons/automatic_levels_off.png +0 -0
- PaIRS_UniNa/icons/automatic_levels_on.png +0 -0
- PaIRS_UniNa/icons/automatic_off.png +0 -0
- PaIRS_UniNa/icons/automatic_on.png +0 -0
- PaIRS_UniNa/icons/automatic_size_off.png +0 -0
- PaIRS_UniNa/icons/automatic_size_on.png +0 -0
- PaIRS_UniNa/icons/axes.png +0 -0
- PaIRS_UniNa/icons/background.png +0 -0
- PaIRS_UniNa/icons/background_vectors.png +0 -0
- PaIRS_UniNa/icons/bin_off.png +0 -0
- PaIRS_UniNa/icons/bin_on.png +0 -0
- PaIRS_UniNa/icons/browse_file_c.png +0 -0
- PaIRS_UniNa/icons/browse_folder_c.png +0 -0
- PaIRS_UniNa/icons/brush_cursor.png +0 -0
- PaIRS_UniNa/icons/bugfix.png +0 -0
- PaIRS_UniNa/icons/cal_proc.png +0 -0
- PaIRS_UniNa/icons/cal_proc_off.png +0 -0
- PaIRS_UniNa/icons/cal_step.png +0 -0
- PaIRS_UniNa/icons/cal_step_off.png +0 -0
- PaIRS_UniNa/icons/calibrate.png +0 -0
- PaIRS_UniNa/icons/calibration_logo.png +0 -0
- PaIRS_UniNa/icons/change_folder.png +0 -0
- PaIRS_UniNa/icons/change_folder_off.png +0 -0
- PaIRS_UniNa/icons/checklist.png +0 -0
- PaIRS_UniNa/icons/clean.png +0 -0
- PaIRS_UniNa/icons/clean_run.png +0 -0
- PaIRS_UniNa/icons/close.png +0 -0
- PaIRS_UniNa/icons/close_all.png +0 -0
- PaIRS_UniNa/icons/close_project.png +0 -0
- PaIRS_UniNa/icons/close_workspace.png +0 -0
- PaIRS_UniNa/icons/colormap.png +0 -0
- PaIRS_UniNa/icons/colormaps/Accent.png +0 -0
- PaIRS_UniNa/icons/colormaps/BrBG.png +0 -0
- PaIRS_UniNa/icons/colormaps/Dark2.png +0 -0
- PaIRS_UniNa/icons/colormaps/PRGn.png +0 -0
- PaIRS_UniNa/icons/colormaps/Paired.png +0 -0
- PaIRS_UniNa/icons/colormaps/Pastel1.png +0 -0
- PaIRS_UniNa/icons/colormaps/Pastel2.png +0 -0
- PaIRS_UniNa/icons/colormaps/PiYG.png +0 -0
- PaIRS_UniNa/icons/colormaps/PuOr.png +0 -0
- PaIRS_UniNa/icons/colormaps/RdBu.png +0 -0
- PaIRS_UniNa/icons/colormaps/RdGy.png +0 -0
- PaIRS_UniNa/icons/colormaps/RdYlBu.png +0 -0
- PaIRS_UniNa/icons/colormaps/RdYlGn.png +0 -0
- PaIRS_UniNa/icons/colormaps/Set1.png +0 -0
- PaIRS_UniNa/icons/colormaps/Set2.png +0 -0
- PaIRS_UniNa/icons/colormaps/Set3.png +0 -0
- PaIRS_UniNa/icons/colormaps/Spectral.png +0 -0
- PaIRS_UniNa/icons/colormaps/Wistia.png +0 -0
- PaIRS_UniNa/icons/colormaps/afmhot.png +0 -0
- PaIRS_UniNa/icons/colormaps/autumn.png +0 -0
- PaIRS_UniNa/icons/colormaps/binary.png +0 -0
- PaIRS_UniNa/icons/colormaps/blackVector.png +0 -0
- PaIRS_UniNa/icons/colormaps/blueVector.png +0 -0
- PaIRS_UniNa/icons/colormaps/bone.png +0 -0
- PaIRS_UniNa/icons/colormaps/brg.png +0 -0
- PaIRS_UniNa/icons/colormaps/bwr.png +0 -0
- PaIRS_UniNa/icons/colormaps/cividis.png +0 -0
- PaIRS_UniNa/icons/colormaps/cool.png +0 -0
- PaIRS_UniNa/icons/colormaps/coolwarm.png +0 -0
- PaIRS_UniNa/icons/colormaps/copper.png +0 -0
- PaIRS_UniNa/icons/colormaps/cubehelix.png +0 -0
- PaIRS_UniNa/icons/colormaps/cyanVector.png +0 -0
- PaIRS_UniNa/icons/colormaps/flag.png +0 -0
- PaIRS_UniNa/icons/colormaps/gist_heat.png +0 -0
- PaIRS_UniNa/icons/colormaps/gray.png +0 -0
- PaIRS_UniNa/icons/colormaps/greenVector.png +0 -0
- PaIRS_UniNa/icons/colormaps/hot.png +0 -0
- PaIRS_UniNa/icons/colormaps/hsv.png +0 -0
- PaIRS_UniNa/icons/colormaps/inferno.png +0 -0
- PaIRS_UniNa/icons/colormaps/jet.png +0 -0
- PaIRS_UniNa/icons/colormaps/magentaVector.png +0 -0
- PaIRS_UniNa/icons/colormaps/magma.png +0 -0
- PaIRS_UniNa/icons/colormaps/ocean.png +0 -0
- PaIRS_UniNa/icons/colormaps/pink.png +0 -0
- PaIRS_UniNa/icons/colormaps/plasma.png +0 -0
- PaIRS_UniNa/icons/colormaps/prism.png +0 -0
- PaIRS_UniNa/icons/colormaps/rainbow.png +0 -0
- PaIRS_UniNa/icons/colormaps/redVector.png +0 -0
- PaIRS_UniNa/icons/colormaps/seismic.png +0 -0
- PaIRS_UniNa/icons/colormaps/spring.png +0 -0
- PaIRS_UniNa/icons/colormaps/summer.png +0 -0
- PaIRS_UniNa/icons/colormaps/tab10.png +0 -0
- PaIRS_UniNa/icons/colormaps/tab20.png +0 -0
- PaIRS_UniNa/icons/colormaps/tab20b.png +0 -0
- PaIRS_UniNa/icons/colormaps/tab20c.png +0 -0
- PaIRS_UniNa/icons/colormaps/terrain.png +0 -0
- PaIRS_UniNa/icons/colormaps/twilight.png +0 -0
- PaIRS_UniNa/icons/colormaps/viridis.png +0 -0
- PaIRS_UniNa/icons/colormaps/whiteVector.png +0 -0
- PaIRS_UniNa/icons/colormaps/winter.png +0 -0
- PaIRS_UniNa/icons/colormaps/yellowVector.png +0 -0
- PaIRS_UniNa/icons/common_region.png +0 -0
- PaIRS_UniNa/icons/common_region_off.png +0 -0
- PaIRS_UniNa/icons/completed.png +0 -0
- PaIRS_UniNa/icons/contourf_off.png +0 -0
- PaIRS_UniNa/icons/contourf_on.png +0 -0
- PaIRS_UniNa/icons/copy.png +0 -0
- PaIRS_UniNa/icons/copy_process.png +0 -0
- PaIRS_UniNa/icons/copy_process_off.png +0 -0
- PaIRS_UniNa/icons/copygrid.png +0 -0
- PaIRS_UniNa/icons/cursor_lamp.png +0 -0
- PaIRS_UniNa/icons/cut.png +0 -0
- PaIRS_UniNa/icons/cut_warnings.png +0 -0
- PaIRS_UniNa/icons/darkmode.png +0 -0
- PaIRS_UniNa/icons/debug_run.png +0 -0
- PaIRS_UniNa/icons/delete.png +0 -0
- PaIRS_UniNa/icons/deleteErr.png +0 -0
- PaIRS_UniNa/icons/disp_step.png +0 -0
- PaIRS_UniNa/icons/disp_step_off.png +0 -0
- PaIRS_UniNa/icons/down.png +0 -0
- PaIRS_UniNa/icons/edit_list.png +0 -0
- PaIRS_UniNa/icons/editing.png +0 -0
- PaIRS_UniNa/icons/example_list.png +0 -0
- PaIRS_UniNa/icons/find_all_planes.png +0 -0
- PaIRS_UniNa/icons/find_plane.png +0 -0
- PaIRS_UniNa/icons/flaticon_PaIRS.png +0 -0
- PaIRS_UniNa/icons/flaticon_PaIRS_beta.png +0 -0
- PaIRS_UniNa/icons/flaticon_PaIRS_download.png +0 -0
- PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
- PaIRS_UniNa/icons/flip_y_off.png +0 -0
- PaIRS_UniNa/icons/flip_y_on.png +0 -0
- PaIRS_UniNa/icons/focusErrr.png +0 -0
- PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
- PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
- PaIRS_UniNa/icons/gear.gif +0 -0
- PaIRS_UniNa/icons/gear.png +0 -0
- PaIRS_UniNa/icons/ger.png +0 -0
- PaIRS_UniNa/icons/greenv.png +0 -0
- PaIRS_UniNa/icons/guide.png +0 -0
- PaIRS_UniNa/icons/icon_CalVi.png +0 -0
- PaIRS_UniNa/icons/icon_PaIRS.png +0 -0
- PaIRS_UniNa/icons/import.png +0 -0
- PaIRS_UniNa/icons/import_set.png +0 -0
- PaIRS_UniNa/icons/information.png +0 -0
- PaIRS_UniNa/icons/information2.png +0 -0
- PaIRS_UniNa/icons/input_logo.png +0 -0
- PaIRS_UniNa/icons/issue.png +0 -0
- PaIRS_UniNa/icons/laser_NTR.png +0 -0
- PaIRS_UniNa/icons/laser_TR_double.png +0 -0
- PaIRS_UniNa/icons/laser_TR_single.png +0 -0
- PaIRS_UniNa/icons/link.png +0 -0
- PaIRS_UniNa/icons/linked.png +0 -0
- PaIRS_UniNa/icons/loaded.png +0 -0
- PaIRS_UniNa/icons/loading_2.gif +0 -0
- PaIRS_UniNa/icons/log_logo.png +0 -0
- PaIRS_UniNa/icons/logo_CalVi.png +0 -0
- PaIRS_UniNa/icons/logo_CalVi_completo.png +0 -0
- PaIRS_UniNa/icons/logo_CalVi_party.png +0 -0
- PaIRS_UniNa/icons/logo_PaIRS.png +0 -0
- PaIRS_UniNa/icons/logo_PaIRS_completo.png +0 -0
- PaIRS_UniNa/icons/logo_PaIRS_download.png +0 -0
- PaIRS_UniNa/icons/logo_PaIRS_party_rect.png +0 -0
- PaIRS_UniNa/icons/logo_PaIRS_rect.png +0 -0
- PaIRS_UniNa/icons/logo_opaco.png +0 -0
- PaIRS_UniNa/icons/mask.png +0 -0
- PaIRS_UniNa/icons/measure.png +0 -0
- PaIRS_UniNa/icons/measure_off.png +0 -0
- PaIRS_UniNa/icons/min_proc.png +0 -0
- PaIRS_UniNa/icons/min_proc_off.png +0 -0
- PaIRS_UniNa/icons/min_step.png +0 -0
- PaIRS_UniNa/icons/min_step_off.png +0 -0
- PaIRS_UniNa/icons/minus.png +0 -0
- PaIRS_UniNa/icons/mirror_u.png +0 -0
- PaIRS_UniNa/icons/mirror_v.png +0 -0
- PaIRS_UniNa/icons/mirror_x.png +0 -0
- PaIRS_UniNa/icons/mirror_y.png +0 -0
- PaIRS_UniNa/icons/mtplt.png +0 -0
- PaIRS_UniNa/icons/new.png +0 -0
- PaIRS_UniNa/icons/new_workspace.png +0 -0
- PaIRS_UniNa/icons/news.png +0 -0
- PaIRS_UniNa/icons/normal_run.png +0 -0
- PaIRS_UniNa/icons/open.png +0 -0
- PaIRS_UniNa/icons/open_image.png +0 -0
- PaIRS_UniNa/icons/open_new_window.png +0 -0
- PaIRS_UniNa/icons/open_result.png +0 -0
- PaIRS_UniNa/icons/open_workspace.png +0 -0
- PaIRS_UniNa/icons/output_logo.png +0 -0
- PaIRS_UniNa/icons/paste_above.png +0 -0
- PaIRS_UniNa/icons/paste_below.png +0 -0
- PaIRS_UniNa/icons/pause.png +0 -0
- PaIRS_UniNa/icons/paused.png +0 -0
- PaIRS_UniNa/icons/pencil_bw.png +0 -0
- PaIRS_UniNa/icons/piv_proc.png +0 -0
- PaIRS_UniNa/icons/piv_proc_off.png +0 -0
- PaIRS_UniNa/icons/piv_step.png +0 -0
- PaIRS_UniNa/icons/piv_step_off.png +0 -0
- PaIRS_UniNa/icons/plane.png +0 -0
- PaIRS_UniNa/icons/play.png +0 -0
- PaIRS_UniNa/icons/plus.png +0 -0
- PaIRS_UniNa/icons/process_logo.png +0 -0
- PaIRS_UniNa/icons/process_loop.png +0 -0
- PaIRS_UniNa/icons/project.png +0 -0
- PaIRS_UniNa/icons/pylog.png +0 -0
- PaIRS_UniNa/icons/python_warning.png +0 -0
- PaIRS_UniNa/icons/queue.png +0 -0
- PaIRS_UniNa/icons/quit.png +0 -0
- PaIRS_UniNa/icons/read.png +0 -0
- PaIRS_UniNa/icons/read_list.png +0 -0
- PaIRS_UniNa/icons/redo.png +0 -0
- PaIRS_UniNa/icons/redx.png +0 -0
- PaIRS_UniNa/icons/reset.png +0 -0
- PaIRS_UniNa/icons/reset_levels.png +0 -0
- PaIRS_UniNa/icons/resize_icon.png +0 -0
- PaIRS_UniNa/icons/restore.png +0 -0
- PaIRS_UniNa/icons/restore_undo.png +0 -0
- PaIRS_UniNa/icons/rotate_clock.png +0 -0
- PaIRS_UniNa/icons/rotate_counter.png +0 -0
- PaIRS_UniNa/icons/rotate_v_clock.png +0 -0
- PaIRS_UniNa/icons/rotate_v_counter.png +0 -0
- PaIRS_UniNa/icons/running.gif +0 -0
- PaIRS_UniNa/icons/running.png +0 -0
- PaIRS_UniNa/icons/running_warn.png +0 -0
- PaIRS_UniNa/icons/sandglass.png +0 -0
- PaIRS_UniNa/icons/save.png +0 -0
- PaIRS_UniNa/icons/save_and_stop.png +0 -0
- PaIRS_UniNa/icons/save_cfg.png +0 -0
- PaIRS_UniNa/icons/saveas.png +0 -0
- PaIRS_UniNa/icons/saveas_workspace.png +0 -0
- PaIRS_UniNa/icons/scale_all.png +0 -0
- PaIRS_UniNa/icons/scale_down.png +0 -0
- PaIRS_UniNa/icons/scale_up.png +0 -0
- PaIRS_UniNa/icons/scan_list.png +0 -0
- PaIRS_UniNa/icons/scan_path.png +0 -0
- PaIRS_UniNa/icons/scan_path_loop.png +0 -0
- PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
- PaIRS_UniNa/icons/search.png +0 -0
- PaIRS_UniNa/icons/showIW_off.png +0 -0
- PaIRS_UniNa/icons/showIW_on.png +0 -0
- PaIRS_UniNa/icons/show_all.png +0 -0
- PaIRS_UniNa/icons/sort.png +0 -0
- PaIRS_UniNa/icons/sort_reversed.png +0 -0
- PaIRS_UniNa/icons/spiv_proc.png +0 -0
- PaIRS_UniNa/icons/spiv_proc_off.png +0 -0
- PaIRS_UniNa/icons/spiv_setup_no.png +0 -0
- PaIRS_UniNa/icons/spiv_setup_ok.png +0 -0
- PaIRS_UniNa/icons/star.png +0 -0
- PaIRS_UniNa/icons/step_inheritance.png +0 -0
- PaIRS_UniNa/icons/subMIN_off.png +0 -0
- PaIRS_UniNa/icons/subMIN_on.png +0 -0
- PaIRS_UniNa/icons/tom.png +0 -0
- PaIRS_UniNa/icons/trash.png +0 -0
- PaIRS_UniNa/icons/undo.png +0 -0
- PaIRS_UniNa/icons/unedited.png +0 -0
- PaIRS_UniNa/icons/unina_dii.png +0 -0
- PaIRS_UniNa/icons/uninitialized.png +0 -0
- PaIRS_UniNa/icons/unlink.png +0 -0
- PaIRS_UniNa/icons/unwrap_items.png +0 -0
- PaIRS_UniNa/icons/up.png +0 -0
- PaIRS_UniNa/icons/updating_import.gif +0 -0
- PaIRS_UniNa/icons/updating_pairs.gif +0 -0
- PaIRS_UniNa/icons/vectorColor.png +0 -0
- PaIRS_UniNa/icons/vettore.png +0 -0
- PaIRS_UniNa/icons/view.png +0 -0
- PaIRS_UniNa/icons/view_off.png +0 -0
- PaIRS_UniNa/icons/vis_logo.png +0 -0
- PaIRS_UniNa/icons/waiting_circle.png +0 -0
- PaIRS_UniNa/icons/warning.png +0 -0
- PaIRS_UniNa/icons/warning_circle.png +0 -0
- PaIRS_UniNa/icons/window.png +0 -0
- PaIRS_UniNa/icons/workspace.png +0 -0
- PaIRS_UniNa/icons/wrap_items.png +0 -0
- PaIRS_UniNa/icons/write_list.png +0 -0
- PaIRS_UniNa/listLib.py +303 -0
- PaIRS_UniNa/mtfPIV.py +256 -0
- PaIRS_UniNa/parForMulti.py +435 -0
- PaIRS_UniNa/parForWorkers.py +593 -0
- PaIRS_UniNa/pivParFor.py +235 -0
- PaIRS_UniNa/plt_util.py +141 -0
- PaIRS_UniNa/preProcParFor.py +155 -0
- PaIRS_UniNa/procTools.py +1439 -0
- PaIRS_UniNa/readcfg.py +52 -0
- PaIRS_UniNa/rqrdpckgs.txt +9 -0
- PaIRS_UniNa/stereoPivParFor.py +227 -0
- PaIRS_UniNa/tAVarie.py +215 -0
- PaIRS_UniNa/tabSplitter.py +612 -0
- PaIRS_UniNa/ui_Calibration_Tab.py +578 -0
- PaIRS_UniNa/ui_Custom_Top.py +296 -0
- PaIRS_UniNa/ui_Input_Tab.py +1101 -0
- PaIRS_UniNa/ui_Input_Tab_CalVi.py +1283 -0
- PaIRS_UniNa/ui_Log_Tab.py +263 -0
- PaIRS_UniNa/ui_Output_Tab.py +2362 -0
- PaIRS_UniNa/ui_Process_Tab.py +3810 -0
- PaIRS_UniNa/ui_Process_Tab_CalVi.py +1549 -0
- PaIRS_UniNa/ui_Process_Tab_Disp.py +1141 -0
- PaIRS_UniNa/ui_Process_Tab_Min.py +437 -0
- PaIRS_UniNa/ui_ResizePopup.py +204 -0
- PaIRS_UniNa/ui_Vis_Tab.py +1628 -0
- PaIRS_UniNa/ui_Vis_Tab_CalVi.py +1251 -0
- PaIRS_UniNa/ui_Whatsnew.py +132 -0
- PaIRS_UniNa/ui_gPairs.py +877 -0
- PaIRS_UniNa/ui_infoPaIRS.py +551 -0
- PaIRS_UniNa/whatsnew.txt +4 -0
- pairs_unina-0.2.10.dist-info/METADATA +159 -0
- pairs_unina-0.2.10.dist-info/RECORD +333 -0
- pairs_unina-0.2.10.dist-info/WHEEL +5 -0
- pairs_unina-0.2.10.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,1633 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from .PaIRS_pypacks import *
|
|
3
|
+
#from ui_Tree_Tab import Ui_TreeTab
|
|
4
|
+
|
|
5
|
+
QLocale.setDefault(QLocale.Language.English)
|
|
6
|
+
curr_locale = QLocale()
|
|
7
|
+
|
|
8
|
+
InitCheck=True #False=Collap closed, True=opened
|
|
9
|
+
#fonts
|
|
10
|
+
font_italic=True
|
|
11
|
+
font_weight=QFont.DemiBold
|
|
12
|
+
backgroundcolor_none=" background-color: none;"
|
|
13
|
+
backgroundcolor_changing=" background-color: rgb(255,230,230);"
|
|
14
|
+
backgroundcolor_hover=" background-color: rgba(0, 116, 255, 0.1);"
|
|
15
|
+
border_hover = " " #"border: 1px solid gray; "
|
|
16
|
+
color_changing="color: rgb(33,33,255); "+backgroundcolor_changing
|
|
17
|
+
|
|
18
|
+
#********************************************* Operating Widgets
|
|
19
|
+
def setSS(b,style):
|
|
20
|
+
ss=f"{b.metaObject().className()}{'{'+style+'}'}\\nQToolTip{'{'+b.initialStyle+'}'}"
|
|
21
|
+
return ss
|
|
22
|
+
|
|
23
|
+
class MyTabLabel(QLabel):
|
|
24
|
+
def __init__(self,parent):
|
|
25
|
+
super().__init__(parent)
|
|
26
|
+
#self.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
|
|
27
|
+
self.addfuncclick={}
|
|
28
|
+
|
|
29
|
+
def mousePressEvent(self, event):
|
|
30
|
+
for f in self.addfuncclick:
|
|
31
|
+
self.addfuncclick[f]()
|
|
32
|
+
return super().mousePressEvent(event)
|
|
33
|
+
|
|
34
|
+
def setCustomCursor(self):
|
|
35
|
+
if self.addfuncclick:
|
|
36
|
+
self.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
|
|
37
|
+
else:
|
|
38
|
+
self.setCursor(QCursor(Qt.CursorShape.ArrowCursor))
|
|
39
|
+
|
|
40
|
+
#MyQLineEdit=QtWidgets.QLineEdit
|
|
41
|
+
class MyQLineEdit(QtWidgets.QLineEdit):
|
|
42
|
+
def __init__(self,parent):
|
|
43
|
+
super().__init__(parent)
|
|
44
|
+
self.addlab=QtWidgets.QLabel()
|
|
45
|
+
self.addwid=[]
|
|
46
|
+
self.initFlag=False
|
|
47
|
+
self.initFlag2=False
|
|
48
|
+
self.styleFlag=False
|
|
49
|
+
self.addfuncin={}
|
|
50
|
+
self.addfuncout={}
|
|
51
|
+
self.addfuncreturn={}
|
|
52
|
+
self.FlagCompleter=False
|
|
53
|
+
self.FunSetCompleterList=lambda: None
|
|
54
|
+
|
|
55
|
+
def setup(self):
|
|
56
|
+
if not self.initFlag:
|
|
57
|
+
self.initFlag=True
|
|
58
|
+
self.FlagFocusIn=False
|
|
59
|
+
self.oldFont=None
|
|
60
|
+
self.oldStyle=None
|
|
61
|
+
font_changing = QtGui.QFont(self.font())
|
|
62
|
+
font_changing.setItalic(font_italic)
|
|
63
|
+
font_changing.setWeight(font_weight)
|
|
64
|
+
children=self.parent().children()
|
|
65
|
+
self.bros=children+self.addwid
|
|
66
|
+
for b in self.bros:
|
|
67
|
+
hasStyleFlag=hasattr(b,'styleFlag')
|
|
68
|
+
if hasattr(b,'setStyleSheet'):
|
|
69
|
+
if hasStyleFlag:
|
|
70
|
+
if b.styleFlag: continue
|
|
71
|
+
b.initialStyle=b.styleSheet()+" "+backgroundcolor_none
|
|
72
|
+
b.setEnabled(False)
|
|
73
|
+
b.disabledStyle=b.styleSheet()
|
|
74
|
+
b.setEnabled(True)
|
|
75
|
+
b.setStyleSheet(setSS(b,b.initialStyle))
|
|
76
|
+
if hasattr(b,'setFont'):
|
|
77
|
+
b.initialFont=b.font()
|
|
78
|
+
b.font_changing=font_changing
|
|
79
|
+
if hasStyleFlag: b.styleFlag=True
|
|
80
|
+
self.CElabs=[w for w in self.bros if isinstance(w, ClickableEditLabel)]
|
|
81
|
+
self.CElabs_styles=[w.styleSheet() for w in self.CElabs]
|
|
82
|
+
|
|
83
|
+
def setup2(self):
|
|
84
|
+
if not self.initFlag2:
|
|
85
|
+
self.initFlag2=True
|
|
86
|
+
for b in self.bros:
|
|
87
|
+
if hasattr(b,'bros'):
|
|
88
|
+
for c in b.bros:
|
|
89
|
+
if c not in self.bros:
|
|
90
|
+
self.bros.append(c)
|
|
91
|
+
|
|
92
|
+
def setCompleterList(self):
|
|
93
|
+
if not self.FlagCompleter:
|
|
94
|
+
self.FunSetCompleterList()
|
|
95
|
+
self.FlagCompleter=True
|
|
96
|
+
self.showCompleter()
|
|
97
|
+
|
|
98
|
+
def mouseReleaseEvent(self, event):
|
|
99
|
+
super().mouseReleaseEvent(event) #to preserve classical behaviour before adding the below
|
|
100
|
+
self.setCompleterList()
|
|
101
|
+
|
|
102
|
+
def enterEvent(self, event):
|
|
103
|
+
if not self.hasFocus() and self.isEnabled():
|
|
104
|
+
self.oldFont=self.font()
|
|
105
|
+
self.oldStyle=self.styleSheet()
|
|
106
|
+
self.setFont(self.font_changing)
|
|
107
|
+
self.setStyleSheet(setSS(self,self.initialStyle+" "+backgroundcolor_hover))
|
|
108
|
+
for k,w in enumerate(self.CElabs):
|
|
109
|
+
self.CElabs_styles[k]=w.styleSheet()
|
|
110
|
+
w.setStyleSheet(w.styleSheet()+" "+f"""
|
|
111
|
+
ClickableEditLabel {{
|
|
112
|
+
{backgroundcolor_hover};
|
|
113
|
+
}}
|
|
114
|
+
""")
|
|
115
|
+
w.repaint()
|
|
116
|
+
super().enterEvent(event)
|
|
117
|
+
|
|
118
|
+
def leaveEvent(self, event):
|
|
119
|
+
if not self.hasFocus() and self.oldFont is not None:
|
|
120
|
+
self.setFont(self.oldFont)
|
|
121
|
+
self.setStyleSheet(self.oldStyle)
|
|
122
|
+
for k,w in enumerate(self.CElabs):
|
|
123
|
+
w.setStyleSheet(self.CElabs_styles[k])
|
|
124
|
+
w.repaint()
|
|
125
|
+
self.oldFont=None
|
|
126
|
+
self.oldStyle=None
|
|
127
|
+
super().leaveEvent(event)
|
|
128
|
+
|
|
129
|
+
def focusInEvent(self, event):
|
|
130
|
+
super().focusInEvent(event)
|
|
131
|
+
for f in self.addfuncin:
|
|
132
|
+
self.addfuncin[f]()
|
|
133
|
+
self.focusInFun()
|
|
134
|
+
|
|
135
|
+
def setFocus(self):
|
|
136
|
+
super().setFocus()
|
|
137
|
+
self.focusInFun()
|
|
138
|
+
|
|
139
|
+
def focusInFun(self):
|
|
140
|
+
self.setStyleFont(color_changing,self.font_changing)
|
|
141
|
+
|
|
142
|
+
def setStyleFont(self,color_changing,font):
|
|
143
|
+
for b in self.bros:
|
|
144
|
+
if hasattr(b,'setInitalStyle') and hasattr(b,'FlagFocusIn') and b.FlagFocusIn:
|
|
145
|
+
b.setInitalStyle()
|
|
146
|
+
break
|
|
147
|
+
if not self.FlagFocusIn:
|
|
148
|
+
self.FlagFocusIn=True
|
|
149
|
+
self.setFont(font)
|
|
150
|
+
for b in self.bros:
|
|
151
|
+
if hasattr(b,'initialStyle'):
|
|
152
|
+
b.setStyleSheet(setSS(b,b.initialStyle+" "+color_changing))
|
|
153
|
+
|
|
154
|
+
def focusOutEvent(self, event):
|
|
155
|
+
super().focusOutEvent(event) #to preserve classical behaviour before adding the below
|
|
156
|
+
for f in self.addfuncout:
|
|
157
|
+
self.addfuncout[f]()
|
|
158
|
+
self.setInitalStyle()
|
|
159
|
+
|
|
160
|
+
def clearFocus(self):
|
|
161
|
+
super().clearFocus()
|
|
162
|
+
self.setInitalStyle()
|
|
163
|
+
|
|
164
|
+
def setInitalStyle(self):
|
|
165
|
+
if self.FlagFocusIn:
|
|
166
|
+
self.FlagFocusIn=False
|
|
167
|
+
for b in self.bros:
|
|
168
|
+
if hasattr(b,'default_stylesheet'):
|
|
169
|
+
b.setStyleSheet(b.default_stylesheet)
|
|
170
|
+
elif hasattr(b,'initialStyle'):
|
|
171
|
+
b.setStyleSheet(b.initialStyle)
|
|
172
|
+
if hasattr(b,'initialFont'):
|
|
173
|
+
b.setFont(b.initialFont)
|
|
174
|
+
for k,w in enumerate(self.CElabs):
|
|
175
|
+
self.CElabs_styles[k]=w.default_stylesheet
|
|
176
|
+
w.setStyleSheet(self.CElabs_styles[k])
|
|
177
|
+
w.repaint()
|
|
178
|
+
self.oldFont=None
|
|
179
|
+
self.oldStyle=None
|
|
180
|
+
#self.addlab.clear()
|
|
181
|
+
|
|
182
|
+
def showCompleter(self):
|
|
183
|
+
if self.completer():
|
|
184
|
+
self.completer().complete()
|
|
185
|
+
|
|
186
|
+
class MyQLineEditNumber(MyQLineEdit):
|
|
187
|
+
def __init__(self,parent):
|
|
188
|
+
super().__init__(parent)
|
|
189
|
+
self.addfuncreturn={}
|
|
190
|
+
|
|
191
|
+
def keyPressEvent(self, event):
|
|
192
|
+
#infoPrint.white(event.key())
|
|
193
|
+
if event.key() in (Qt.Key.Key_Space, #space
|
|
194
|
+
Qt.Key.Key_Comma, #comma
|
|
195
|
+
Qt.Key.Key_Delete, Qt.Key.Key_Backspace, #del, backspace
|
|
196
|
+
Qt.Key.Key_Left,Qt.Key.Key_Right, #left, right
|
|
197
|
+
Qt.Key.Key_Return, Qt.Key.Key_Enter #return
|
|
198
|
+
) \
|
|
199
|
+
or (event.key()>=Qt.Key.Key_0 and event.key()<=Qt.Key.Key_9):
|
|
200
|
+
super().keyPressEvent(event)
|
|
201
|
+
if event.key()==16777220:
|
|
202
|
+
for f in self.addfuncreturn:
|
|
203
|
+
self.addfuncreturn[f]()
|
|
204
|
+
|
|
205
|
+
class MyQCombo(QtWidgets.QComboBox):
|
|
206
|
+
def wheelEvent(self, event):
|
|
207
|
+
event.ignore()
|
|
208
|
+
|
|
209
|
+
#MyQSpin=QtWidgets.QSpinBox
|
|
210
|
+
class MyQSpin(QtWidgets.QSpinBox):
|
|
211
|
+
def __init__(self,parent):
|
|
212
|
+
super().__init__(parent)
|
|
213
|
+
self.addwid=[]
|
|
214
|
+
self.initFlag=False
|
|
215
|
+
self.styleFlag=False
|
|
216
|
+
self.addfuncin={}
|
|
217
|
+
self.addfuncout={}
|
|
218
|
+
self.addfuncreturn={}
|
|
219
|
+
|
|
220
|
+
self.setAccelerated(True)
|
|
221
|
+
self.setGroupSeparatorShown(True)
|
|
222
|
+
|
|
223
|
+
def setup(self):
|
|
224
|
+
if not self.initFlag:
|
|
225
|
+
self.initFlag=True
|
|
226
|
+
self.FlagFocusIn=False
|
|
227
|
+
self.oldFont=None
|
|
228
|
+
self.oldStyle=None
|
|
229
|
+
font_changing = QtGui.QFont(self.font())
|
|
230
|
+
font_changing.setItalic(font_italic)
|
|
231
|
+
font_changing.setWeight(font_weight)
|
|
232
|
+
self.bros=[self]+self.addwid
|
|
233
|
+
for b in self.bros:
|
|
234
|
+
if b.styleFlag: continue
|
|
235
|
+
b.initialStyle=b.styleSheet()+" "+backgroundcolor_none
|
|
236
|
+
b.initialFont=b.font()
|
|
237
|
+
b.font_changing=font_changing
|
|
238
|
+
b.styleFlag=True
|
|
239
|
+
#self.spinFontObj = self.findChildren(QtWidgets.QLineEdit)[0]
|
|
240
|
+
#self.spinFontObj.initialStyle=self.spinFontObj.styleSheet()+" "+backgroundcolor_none
|
|
241
|
+
#self.spinFontObj.font_changing=font_changing
|
|
242
|
+
|
|
243
|
+
def setFocus(self):
|
|
244
|
+
super().setFocus()
|
|
245
|
+
self.focusInFun()
|
|
246
|
+
|
|
247
|
+
def focusInEvent(self, event):
|
|
248
|
+
super().focusInEvent(event) #to preserve classical behaviour before adding the below
|
|
249
|
+
for f in self.addfuncin:
|
|
250
|
+
self.addfuncin[f]()
|
|
251
|
+
self.focusInFun()
|
|
252
|
+
|
|
253
|
+
def focusInFun(self):
|
|
254
|
+
if not self.FlagFocusIn:
|
|
255
|
+
self.FlagFocusIn=True
|
|
256
|
+
#self.spinFontObj.setStyleSheet(self.spinFontObj.initialStyle+" "+color_changing)
|
|
257
|
+
for b in self.bros:
|
|
258
|
+
b.setStyleSheet(setSS(b,b.initialStyle+" "+color_changing))
|
|
259
|
+
b.setFont(self.font_changing)
|
|
260
|
+
|
|
261
|
+
def clearFocus(self):
|
|
262
|
+
super().clearFocus()
|
|
263
|
+
self.setInitalStyle()
|
|
264
|
+
|
|
265
|
+
def focusOutEvent(self, event):
|
|
266
|
+
super().focusOutEvent(event) #to preserve classical behaviour before adding the below
|
|
267
|
+
for f in self.addfuncout:
|
|
268
|
+
self.addfuncout[f]()
|
|
269
|
+
self.setInitalStyle()
|
|
270
|
+
|
|
271
|
+
def setInitalStyle(self):
|
|
272
|
+
if self.FlagFocusIn:
|
|
273
|
+
self.FlagFocusIn=False
|
|
274
|
+
#self.spinFontObj.setStyleSheet(self.spinFontObj.initialStyle)
|
|
275
|
+
for b in self.bros:
|
|
276
|
+
b.setStyleSheet(setSS(b,b.initialStyle))
|
|
277
|
+
b.setFont(self.initialFont)
|
|
278
|
+
self.findChildren(QtWidgets.QLineEdit)[0].setFont(self.initialFont)
|
|
279
|
+
self.oldFont=None
|
|
280
|
+
self.oldStyle=None
|
|
281
|
+
|
|
282
|
+
def enterEvent(self, event):
|
|
283
|
+
super().enterEvent(event)
|
|
284
|
+
if not self.hasFocus() and self.isEnabled():
|
|
285
|
+
self.oldFont=self.font()
|
|
286
|
+
self.setFont(self.font_changing)
|
|
287
|
+
b=self #b=self.spinFontObj
|
|
288
|
+
self.oldStyle=b.styleSheet()
|
|
289
|
+
b.setStyleSheet(setSS(b,b.initialStyle+" "+backgroundcolor_hover+" "+border_hover))
|
|
290
|
+
|
|
291
|
+
def leaveEvent(self, event):
|
|
292
|
+
super().leaveEvent(event)
|
|
293
|
+
if not self.hasFocus() and self.oldFont is not None:
|
|
294
|
+
self.setFont(self.oldFont)
|
|
295
|
+
b=self #b=self.spinFontObj
|
|
296
|
+
b.setStyleSheet(self.oldStyle)
|
|
297
|
+
self.oldFont=None
|
|
298
|
+
self.oldStyle=None
|
|
299
|
+
|
|
300
|
+
def keyPressEvent(self, event):
|
|
301
|
+
super().keyPressEvent(event)
|
|
302
|
+
if event.key() in (Qt.Key.Key_Return,Qt.Key.Key_Enter) and self.hasFocus():
|
|
303
|
+
for f in self.addfuncreturn:
|
|
304
|
+
self.addfuncreturn[f]()
|
|
305
|
+
|
|
306
|
+
def wheelEvent(self, event):
|
|
307
|
+
event.ignore()
|
|
308
|
+
|
|
309
|
+
def textFromValue(self, value):
|
|
310
|
+
return formatNumber(self,value)
|
|
311
|
+
|
|
312
|
+
def formatNumber(self:QWidget,value):
|
|
313
|
+
if Flag_GROUPSEPARATOR:
|
|
314
|
+
text=self.locale().toString(float(value), 'd')
|
|
315
|
+
else:
|
|
316
|
+
text=f"{value:f}"
|
|
317
|
+
return (text).rstrip('0').rstrip(curr_locale.decimalPoint())
|
|
318
|
+
#return ('%f' % value).rstrip('0').rstrip('.')
|
|
319
|
+
|
|
320
|
+
class MyQSpinXW(MyQSpin):
|
|
321
|
+
def __init__(self,parent):
|
|
322
|
+
super().__init__(parent)
|
|
323
|
+
self.Win=-1
|
|
324
|
+
|
|
325
|
+
def focusInEvent(self, event):
|
|
326
|
+
super().focusInEvent(event) #to preserve classical behaviour before adding the below
|
|
327
|
+
if len(self.addwid)>0:
|
|
328
|
+
self.Win=self.addwid[0].value()
|
|
329
|
+
|
|
330
|
+
class MyToolButton(QtWidgets.QToolButton):
|
|
331
|
+
def __init__(self,parent):
|
|
332
|
+
super().__init__(parent)
|
|
333
|
+
|
|
334
|
+
class MyQDoubleSpin(QtWidgets.QDoubleSpinBox):
|
|
335
|
+
def __init__(self,parent):
|
|
336
|
+
super().__init__(parent)
|
|
337
|
+
self.addwid=[]
|
|
338
|
+
self.initFlag=False
|
|
339
|
+
self.styleFlag=False
|
|
340
|
+
self.addfuncin={}
|
|
341
|
+
self.addfuncout={}
|
|
342
|
+
self.addfuncreturn={}
|
|
343
|
+
|
|
344
|
+
self.setAccelerated(True)
|
|
345
|
+
self.setGroupSeparatorShown(True)
|
|
346
|
+
|
|
347
|
+
def setup(self):
|
|
348
|
+
if not self.initFlag:
|
|
349
|
+
self.initFlag=True
|
|
350
|
+
self.FlagFocusIn=False
|
|
351
|
+
self.oldFont=None
|
|
352
|
+
self.oldStyle=None
|
|
353
|
+
font_changing = QtGui.QFont(self.font())
|
|
354
|
+
font_changing.setItalic(font_italic)
|
|
355
|
+
font_changing.setWeight(font_weight)
|
|
356
|
+
self.bros=[self]+self.addwid
|
|
357
|
+
for b in self.bros:
|
|
358
|
+
if self.styleFlag: continue
|
|
359
|
+
b.initialStyle=b.styleSheet()+" "+backgroundcolor_none
|
|
360
|
+
b.initialFont=b.font()
|
|
361
|
+
b.font_changing=font_changing
|
|
362
|
+
b.styleFlag=True
|
|
363
|
+
#self.spinFontObj = self.findChildren(QtWidgets.QLineEdit)[0]
|
|
364
|
+
#self.spinFontObj.initialStyle=self.spinFontObj.styleSheet()+" "+backgroundcolor_none
|
|
365
|
+
#self.spinFontObj.font_changing=font_changing
|
|
366
|
+
|
|
367
|
+
def setFocus(self):
|
|
368
|
+
super().setFocus()
|
|
369
|
+
self.focusInFun()
|
|
370
|
+
|
|
371
|
+
def focusInEvent(self, event):
|
|
372
|
+
super().focusInEvent(event) #to preserve classical behaviour before adding the below
|
|
373
|
+
for f in self.addfuncin:
|
|
374
|
+
self.addfuncin[f]()
|
|
375
|
+
self.focusInFun()
|
|
376
|
+
|
|
377
|
+
def focusInFun(self):
|
|
378
|
+
if not self.FlagFocusIn:
|
|
379
|
+
self.FlagFocusIn=True
|
|
380
|
+
#self.spinFontObj.setStyleSheet(self.spinFontObj.initialStyle+" "+color_changing)
|
|
381
|
+
for b in self.bros:
|
|
382
|
+
b.setStyleSheet(setSS(b,b.initialStyle+" "+color_changing))
|
|
383
|
+
b.setFont(self.font_changing)
|
|
384
|
+
|
|
385
|
+
def clearFocus(self):
|
|
386
|
+
super().clearFocus()
|
|
387
|
+
self.setInitalStyle()
|
|
388
|
+
|
|
389
|
+
def focusOutEvent(self, event):
|
|
390
|
+
super().focusOutEvent(event) #to preserve classical behaviour before adding the below
|
|
391
|
+
for f in self.addfuncout:
|
|
392
|
+
self.addfuncout[f]()
|
|
393
|
+
self.setInitalStyle()
|
|
394
|
+
|
|
395
|
+
def setInitalStyle(self):
|
|
396
|
+
if self.FlagFocusIn:
|
|
397
|
+
self.FlagFocusIn=False
|
|
398
|
+
#self.spinFontObj.setStyleSheet(self.spinFontObj.initialStyle)
|
|
399
|
+
for b in self.bros:
|
|
400
|
+
b.setStyleSheet(setSS(b,b.initialStyle))
|
|
401
|
+
b.setFont(self.initialFont)
|
|
402
|
+
self.findChildren(QtWidgets.QLineEdit)[0].setFont(self.initialFont)
|
|
403
|
+
self.oldFont=None
|
|
404
|
+
self.oldStyle=None
|
|
405
|
+
|
|
406
|
+
def enterEvent(self, event):
|
|
407
|
+
super().enterEvent(event)
|
|
408
|
+
if not self.hasFocus() and self.isEnabled():
|
|
409
|
+
self.oldFont=self.font()
|
|
410
|
+
self.setFont(self.font_changing)
|
|
411
|
+
b=self #b=self.spinFontObj
|
|
412
|
+
self.oldStyle=b.styleSheet()
|
|
413
|
+
b.setStyleSheet(setSS(b,b.initialStyle+" "+backgroundcolor_hover+" "+border_hover))
|
|
414
|
+
|
|
415
|
+
def leaveEvent(self, event):
|
|
416
|
+
super().leaveEvent(event)
|
|
417
|
+
if not self.hasFocus() and self.oldFont is not None:
|
|
418
|
+
self.setFont(self.oldFont)
|
|
419
|
+
b=self #b=self.spinFontObj
|
|
420
|
+
b.setStyleSheet(self.oldStyle)
|
|
421
|
+
self.oldFont=None
|
|
422
|
+
self.oldStyle=None
|
|
423
|
+
|
|
424
|
+
def keyPressEvent(self, event):
|
|
425
|
+
super().keyPressEvent(event)
|
|
426
|
+
if event.key() in (Qt.Key.Key_Return,Qt.Key.Key_Enter) and self.hasFocus():
|
|
427
|
+
for f in self.addfuncreturn:
|
|
428
|
+
self.addfuncreturn[f]()
|
|
429
|
+
|
|
430
|
+
def wheelEvent(self, event):
|
|
431
|
+
event.ignore()
|
|
432
|
+
|
|
433
|
+
def textFromValue(self, value):
|
|
434
|
+
if Flag_GROUPSEPARATOR:
|
|
435
|
+
text=self.locale().toString(float(value), 'f', self.decimals())
|
|
436
|
+
else:
|
|
437
|
+
text=f"{value:f}"
|
|
438
|
+
return (text).rstrip('0').rstrip(curr_locale.decimalPoint())
|
|
439
|
+
#return ('%f' % value).rstrip('0').rstrip('.')
|
|
440
|
+
|
|
441
|
+
class CollapsibleBox(QtWidgets.QWidget):
|
|
442
|
+
def __init__(self, parent):
|
|
443
|
+
super().__init__(parent)
|
|
444
|
+
self.initFlag=False
|
|
445
|
+
self.FlagPush=False
|
|
446
|
+
self.dpix=5
|
|
447
|
+
self.toolMinimumWidth=400
|
|
448
|
+
self.toolHeight=20
|
|
449
|
+
self.content_area:QGroupBox=None
|
|
450
|
+
self.toggle_button:QPushButton=None
|
|
451
|
+
self.push_button:MyToolButton=None
|
|
452
|
+
|
|
453
|
+
def setup(self,*args):
|
|
454
|
+
if not self.initFlag:
|
|
455
|
+
if len(args):
|
|
456
|
+
self.ind=args[0]
|
|
457
|
+
self.stretch=args[1]
|
|
458
|
+
else:
|
|
459
|
+
self.ind=-1
|
|
460
|
+
self.stretch=0
|
|
461
|
+
self.initFlag=True
|
|
462
|
+
|
|
463
|
+
if self.content_area is None:
|
|
464
|
+
self.content_area=self.findChild(QtWidgets.QGroupBox)
|
|
465
|
+
self.content_area.setStyleSheet("QGroupBox{border: 1px solid gray; border-radius: 6px;}")
|
|
466
|
+
|
|
467
|
+
if self.toggle_button is None:
|
|
468
|
+
self.toggle_button=self.findChild(QtWidgets.QToolButton)
|
|
469
|
+
self.toggle_button.setObjectName("CollapsibleBox_toggle")
|
|
470
|
+
self.toggle_button.setChecked(InitCheck)
|
|
471
|
+
self.toggle_button.clicked.connect(self.on_click)
|
|
472
|
+
self.toggle_button.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
|
|
473
|
+
self.toggle_button.setMinimumWidth(self.toolMinimumWidth)
|
|
474
|
+
|
|
475
|
+
if self.push_button is None:
|
|
476
|
+
self.push_button=self.findChild(MyToolButton)
|
|
477
|
+
|
|
478
|
+
self.OpenStyle=\
|
|
479
|
+
"QToolButton { border: none; }\n"+\
|
|
480
|
+
"QToolButton::hover{color: rgba(0,0,255,200);}"+\
|
|
481
|
+
"QToolButton::focus{color: rgba(0,0,255,200);}"
|
|
482
|
+
#"QToolButton::hover{border: none; border-radius: 6px; background-color: rgba(0, 0,128,32); }"
|
|
483
|
+
self.ClosedStyle=\
|
|
484
|
+
"QToolButton { border: 1px solid lightgray; border-radius: 6px }\n"+\
|
|
485
|
+
"QToolButton::hover{ border: 1px solid rgba(0,0,255,200); border-radius: 6px; color: rgba(0,0,255,200);}"+\
|
|
486
|
+
"QToolButton::focus{ border: 1px solid rgba(0,0,255,200); border-radius: 6px; color: rgba(0,0,255,200);}" #background-color: rgba(0, 0,128,32); }"
|
|
487
|
+
|
|
488
|
+
self.heightToogle=self.toggle_button.minimumHeight()
|
|
489
|
+
self.heightOpened=self.minimumHeight()
|
|
490
|
+
self.heightArea=self.heightOpened-self.toolHeight
|
|
491
|
+
|
|
492
|
+
self.on_click()
|
|
493
|
+
|
|
494
|
+
#@QtCore.pyqtSlot()
|
|
495
|
+
def on_click(self):
|
|
496
|
+
checked = self.toggle_button.isChecked()
|
|
497
|
+
pri.Coding.yellow(f'>>>>> {self.objectName()} {"opening" if checked else "closing"}')
|
|
498
|
+
if self.objectName()=='CollapBox_ImSet' and checked:
|
|
499
|
+
pass
|
|
500
|
+
if self.FlagPush:
|
|
501
|
+
self.push_button.show()
|
|
502
|
+
else:
|
|
503
|
+
self.push_button.hide()
|
|
504
|
+
if checked:
|
|
505
|
+
self.content_area.show()
|
|
506
|
+
self.toggle_button.setArrowType(QtCore.Qt.ArrowType.DownArrow)
|
|
507
|
+
|
|
508
|
+
self.toggle_button.setMinimumHeight(self.heightToogle)
|
|
509
|
+
self.toggle_button.setMaximumHeight(self.heightToogle)
|
|
510
|
+
self.setMinimumHeight(self.heightOpened)
|
|
511
|
+
self.setMaximumHeight(int(self.heightOpened*1.5))
|
|
512
|
+
self.content_area.setMinimumHeight(self.heightArea)
|
|
513
|
+
self.content_area.setMaximumHeight(int(self.heightArea*1.5))
|
|
514
|
+
|
|
515
|
+
self.toggle_button.setSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
|
|
516
|
+
self.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Maximum)
|
|
517
|
+
self.content_area.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
|
|
518
|
+
|
|
519
|
+
self.toggle_button.setStyleSheet(self.OpenStyle)
|
|
520
|
+
if self.ind>0:
|
|
521
|
+
self.parent().layout().setStretch(self.ind,self.stretch)
|
|
522
|
+
else:
|
|
523
|
+
self.content_area.hide()
|
|
524
|
+
self.toggle_button.setArrowType(QtCore.Qt.ArrowType.RightArrow)
|
|
525
|
+
|
|
526
|
+
self.toggle_button.setMinimumHeight(self.heightToogle+self.dpix)
|
|
527
|
+
self.toggle_button.setMaximumHeight(self.heightToogle+self.dpix)
|
|
528
|
+
self.setMinimumHeight(self.heightToogle+self.dpix*2)
|
|
529
|
+
self.setMaximumHeight(self.heightToogle+self.dpix*2)
|
|
530
|
+
self.content_area.setMinimumHeight(0)
|
|
531
|
+
self.content_area.setMaximumHeight(0)
|
|
532
|
+
|
|
533
|
+
self.toggle_button.setSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Preferred)
|
|
534
|
+
self.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
|
|
535
|
+
self.content_area.setSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum)
|
|
536
|
+
|
|
537
|
+
self.toggle_button.setStyleSheet(self.ClosedStyle)
|
|
538
|
+
|
|
539
|
+
if self.ind>0:
|
|
540
|
+
self.parent().layout().setStretch(self.ind,0)
|
|
541
|
+
|
|
542
|
+
# Forza l'aggiornamento dei layout
|
|
543
|
+
self.updateGeometry()
|
|
544
|
+
self.parentWidget().updateGeometry()
|
|
545
|
+
self.parentWidget().adjustSize()
|
|
546
|
+
|
|
547
|
+
def openBox(self):
|
|
548
|
+
self.toggle_button.setChecked(True)
|
|
549
|
+
self.on_click()
|
|
550
|
+
|
|
551
|
+
def closeBox(self):
|
|
552
|
+
self.toggle_button.setChecked(False)
|
|
553
|
+
self.on_click()
|
|
554
|
+
|
|
555
|
+
class myQTreeWidget(QTreeWidget):
|
|
556
|
+
def __init__(self,parent):
|
|
557
|
+
super().__init__(parent)
|
|
558
|
+
self.FlagArrowKeysNormal=False
|
|
559
|
+
self.addfuncin={}
|
|
560
|
+
self.addfuncout={}
|
|
561
|
+
self.addfuncreturn={}
|
|
562
|
+
self.addfuncshift_pressed={}
|
|
563
|
+
self.addfuncshift_released={}
|
|
564
|
+
self.addfuncdel_pressed={}
|
|
565
|
+
self.addfuncarrows_pressed={}
|
|
566
|
+
self.addfuncarrows_released={}
|
|
567
|
+
self.addfunckey_pressed={}
|
|
568
|
+
#self.ui:Ui_TreeTab=None
|
|
569
|
+
self.ui=None
|
|
570
|
+
|
|
571
|
+
def focusInEvent(self, event):
|
|
572
|
+
super().focusInEvent(event) #to preserve classical behaviour before adding the below
|
|
573
|
+
for f in self.addfuncin:
|
|
574
|
+
self.addfuncin[f]()
|
|
575
|
+
|
|
576
|
+
def focusOutEvent(self, event):
|
|
577
|
+
super().focusOutEvent(event) #to preserve classical behaviour before adding the below
|
|
578
|
+
for f in self.addfuncout:
|
|
579
|
+
self.addfuncout[f]()
|
|
580
|
+
|
|
581
|
+
def keyPressEvent(self, event):
|
|
582
|
+
if event.key() == Qt.Key.Key_Shift:
|
|
583
|
+
super().keyPressEvent(event)
|
|
584
|
+
for f in self.addfuncshift_pressed:
|
|
585
|
+
self.addfuncshift_pressed[f]()
|
|
586
|
+
elif event.key() == Qt.Key.Key_Delete or event.key() == Qt.Key.Key_Backspace:
|
|
587
|
+
super().keyPressEvent(event)
|
|
588
|
+
for f in self.addfuncdel_pressed:
|
|
589
|
+
self.addfuncdel_pressed[f]()
|
|
590
|
+
elif event.key() == Qt.Key.Key_Up or event.key() == Qt.Key.Key_Down:
|
|
591
|
+
if self.FlagArrowKeysNormal:
|
|
592
|
+
return super().keyPressEvent(event)
|
|
593
|
+
else:
|
|
594
|
+
Flag=True
|
|
595
|
+
for f in self.addfuncarrows_pressed:
|
|
596
|
+
Flag=Flag and self.addfuncarrows_pressed[f](event.key())
|
|
597
|
+
#if Flag: super().keyPressEvent(event)
|
|
598
|
+
else:
|
|
599
|
+
super().keyPressEvent(event)
|
|
600
|
+
for f in self.addfunckey_pressed:
|
|
601
|
+
self.addfunckey_pressed[f](event.key())
|
|
602
|
+
|
|
603
|
+
def keyReleaseEvent(self, event):
|
|
604
|
+
super().keyReleaseEvent(event)
|
|
605
|
+
if event.key() == QtCore.Qt.Key_Shift:
|
|
606
|
+
for f in self.addfuncshift_released:
|
|
607
|
+
self.addfuncshift_released[f]()
|
|
608
|
+
elif event.key() == QtCore.Qt.Key_Up or event.key() == QtCore.Qt.Key_Down:
|
|
609
|
+
if self.FlagArrowKeysNormal:
|
|
610
|
+
return super().keyReleaseEvent(event)
|
|
611
|
+
else:
|
|
612
|
+
Flag=True
|
|
613
|
+
for f in self.addfuncarrows_released:
|
|
614
|
+
Flag=Flag and self.addfuncarrows_released[f](event.key())
|
|
615
|
+
#if Flag: super().keyPressEvent(event)
|
|
616
|
+
|
|
617
|
+
class ToggleSplitterHandle(QtWidgets.QSplitterHandle):
|
|
618
|
+
def mousePressEvent(self, event):
|
|
619
|
+
super().mousePressEvent(event)
|
|
620
|
+
for f in self.parent().addfuncin:
|
|
621
|
+
self.parent().addfuncin[f]()
|
|
622
|
+
|
|
623
|
+
def mouseReleaseEvent(self, event):
|
|
624
|
+
super().mouseReleaseEvent(event)
|
|
625
|
+
for f in self.parent().addfuncout:
|
|
626
|
+
self.parent().addfuncout[f]()
|
|
627
|
+
|
|
628
|
+
class myQSplitter(QSplitter):
|
|
629
|
+
def __init__(self,parent):
|
|
630
|
+
super().__init__(parent)
|
|
631
|
+
self.OpWidth=0
|
|
632
|
+
self.OpMaxWidth=0
|
|
633
|
+
self.addfuncin={}
|
|
634
|
+
self.addfuncout={}
|
|
635
|
+
self.addfuncreturn={}
|
|
636
|
+
|
|
637
|
+
def createHandle(self):
|
|
638
|
+
return ToggleSplitterHandle(self.orientation(), self)
|
|
639
|
+
|
|
640
|
+
class RichTextPushButton(QPushButton):
|
|
641
|
+
margin=0
|
|
642
|
+
spacing=0
|
|
643
|
+
|
|
644
|
+
def __init__(self, parent=None, text=None):
|
|
645
|
+
if parent is not None:
|
|
646
|
+
super().__init__(parent)
|
|
647
|
+
else:
|
|
648
|
+
super().__init__()
|
|
649
|
+
|
|
650
|
+
self.__lyt = QHBoxLayout()
|
|
651
|
+
self.__lyt.setContentsMargins(self.margin, 0, self.margin, 0)
|
|
652
|
+
self.__lyt.setSpacing(self.spacing)
|
|
653
|
+
self.setLayout(self.__lyt)
|
|
654
|
+
|
|
655
|
+
self.__icon= QLabel(self)
|
|
656
|
+
self.__icon.setSizePolicy(
|
|
657
|
+
QSizePolicy.Preferred,
|
|
658
|
+
QSizePolicy.Expanding,
|
|
659
|
+
)
|
|
660
|
+
self.__icon.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter)
|
|
661
|
+
|
|
662
|
+
self.__lbl = QLabel(self)
|
|
663
|
+
if text is not None:
|
|
664
|
+
self.__lbl.setText(text)
|
|
665
|
+
else:
|
|
666
|
+
self.__lbl.hide()
|
|
667
|
+
self.__lbl.setAttribute(Qt.WA_TranslucentBackground)
|
|
668
|
+
self.__lbl.setAttribute(Qt.WA_TransparentForMouseEvents)
|
|
669
|
+
self.__lbl.setSizePolicy(
|
|
670
|
+
QSizePolicy.Preferred,
|
|
671
|
+
QSizePolicy.Expanding,
|
|
672
|
+
)
|
|
673
|
+
self.__lbl.setTextFormat(Qt.RichText)
|
|
674
|
+
self.__lbl.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
|
675
|
+
|
|
676
|
+
self.__lyt.addWidget(self.__icon)
|
|
677
|
+
self.__lyt.addWidget(self.__lbl)
|
|
678
|
+
self.__lyt.setStretch(0,1)
|
|
679
|
+
self.__lyt.setStretch(1,2)
|
|
680
|
+
|
|
681
|
+
self.lyt=self.__lyt
|
|
682
|
+
self.lbl=self.__lbl
|
|
683
|
+
self.icnWidget=self.__icon
|
|
684
|
+
self.icn=None
|
|
685
|
+
return
|
|
686
|
+
|
|
687
|
+
def setText(self, text):
|
|
688
|
+
if text:
|
|
689
|
+
self.__lbl.show()
|
|
690
|
+
self.__lbl.setText(text)
|
|
691
|
+
else: self.__lbl.hide()
|
|
692
|
+
self.updateGeometry()
|
|
693
|
+
return
|
|
694
|
+
|
|
695
|
+
def setIcon(self, icon):
|
|
696
|
+
h=int(self.size().height()/2)
|
|
697
|
+
pixmap = icon.pixmap(QSize(h,h))
|
|
698
|
+
self.__icon.setPixmap(pixmap)
|
|
699
|
+
self.icn=icon
|
|
700
|
+
self.updateGeometry()
|
|
701
|
+
return
|
|
702
|
+
|
|
703
|
+
def setIconSize(self, size:QSize):
|
|
704
|
+
if self.icn: self.__icon.setPixmap(self.icn.pixmap(size))
|
|
705
|
+
self.updateGeometry()
|
|
706
|
+
return
|
|
707
|
+
|
|
708
|
+
def sizeHint(self):
|
|
709
|
+
s = QPushButton.sizeHint(self)
|
|
710
|
+
w_lbl = self.__lbl.sizeHint()
|
|
711
|
+
w_icon = self.__icon.sizeHint()
|
|
712
|
+
s.setWidth(w_lbl.width()+w_icon.width()
|
|
713
|
+
+self.margin*2+self.spacing)
|
|
714
|
+
s.setHeight(w_lbl.height())
|
|
715
|
+
return s
|
|
716
|
+
|
|
717
|
+
class myQTableWidget(QtWidgets.QTableWidget):
|
|
718
|
+
def __init__(self,parent):
|
|
719
|
+
super().__init__(parent)
|
|
720
|
+
self.RowInfo=[]
|
|
721
|
+
self.InfoLabel:QLabel=None
|
|
722
|
+
self.DeleteButton:QPushButton=None
|
|
723
|
+
self.addwid=[]
|
|
724
|
+
self.addfuncreturn={}
|
|
725
|
+
self.addfuncout={}
|
|
726
|
+
#self.itemSelectionChanged.connect(self.resizeInfoLabel)
|
|
727
|
+
|
|
728
|
+
def keyPressEvent(self, event):
|
|
729
|
+
#infoPrint.white(event.key())
|
|
730
|
+
super().keyPressEvent(event)
|
|
731
|
+
if event.key() in (Qt.Key.Key_Return,Qt.Key.Key_Enter): #return
|
|
732
|
+
for f in self.addfuncreturn:
|
|
733
|
+
self.addfuncreturn[f]()
|
|
734
|
+
|
|
735
|
+
def focusInEvent(self, event):
|
|
736
|
+
super().focusInEvent(event)
|
|
737
|
+
#if self.DeleteButton: #and self.currentItem():
|
|
738
|
+
# self.DeleteButton.setEnabled(True)
|
|
739
|
+
|
|
740
|
+
def focusOutEvent(self, event):
|
|
741
|
+
super().focusOutEvent(event)
|
|
742
|
+
for f in self.addfuncout:
|
|
743
|
+
self.addfuncout[f]()
|
|
744
|
+
#if self.InfoLabel:
|
|
745
|
+
# self.InfoLabel.hide()
|
|
746
|
+
# self.InfoLabel.setText('')
|
|
747
|
+
#if self.DeleteButton:
|
|
748
|
+
# self.DeleteButton.setEnabled(False)
|
|
749
|
+
|
|
750
|
+
def resizeEvent(self, event):
|
|
751
|
+
super().resizeEvent(event)
|
|
752
|
+
self.resizeInfoLabel()
|
|
753
|
+
|
|
754
|
+
def resizeInfoLabel(self):
|
|
755
|
+
if self.InfoLabel and (True if not self.addwid else not self.addwid[0].hasFocus()):
|
|
756
|
+
item=self.currentItem()
|
|
757
|
+
if item:
|
|
758
|
+
self.InfoLabel.show()
|
|
759
|
+
if self.RowInfo: rowInfo=self.RowInfo[self.currentRow()]
|
|
760
|
+
else: rowInfo=''
|
|
761
|
+
tip=item.toolTip()
|
|
762
|
+
if not "<br>" in tip:
|
|
763
|
+
fw=lambda t: QtGui.QFontMetrics(self.InfoLabel.font()).size(QtCore.Qt.TextSingleLine,t).width()
|
|
764
|
+
if fw(tip)>self.InfoLabel.width():
|
|
765
|
+
k=0
|
|
766
|
+
while fw(tip[:k])<self.InfoLabel.width():
|
|
767
|
+
k+=1
|
|
768
|
+
tip="<br>".join([tip[:k-1], tip[k-1:2*k]])
|
|
769
|
+
if rowInfo: tip="<br>".join([tip,rowInfo])
|
|
770
|
+
self.InfoLabel.setText(tip)
|
|
771
|
+
else:
|
|
772
|
+
self.InfoLabel.hide()
|
|
773
|
+
self.InfoLabel.setText('')
|
|
774
|
+
|
|
775
|
+
def isfloat(num):
|
|
776
|
+
try:
|
|
777
|
+
float(num)
|
|
778
|
+
return True
|
|
779
|
+
except ValueError:
|
|
780
|
+
return False
|
|
781
|
+
|
|
782
|
+
class ClickableLabel(QLabel):
|
|
783
|
+
pixmap_size=25
|
|
784
|
+
def __init__(self, *args):
|
|
785
|
+
super().__init__(*args)
|
|
786
|
+
|
|
787
|
+
self.default_stylesheet = self.styleSheet()
|
|
788
|
+
self.highlight_stylesheet = "background-color: rgba(0, 116, 255, 0.1); border-radius: 3px;"
|
|
789
|
+
|
|
790
|
+
self.timer = QTimer(self)
|
|
791
|
+
self.timer.timeout.connect(self.resetHighlight)
|
|
792
|
+
self.timer.setSingleShot(True)
|
|
793
|
+
|
|
794
|
+
self.moviePixmap=None
|
|
795
|
+
|
|
796
|
+
def mousePressEvent(self, event):
|
|
797
|
+
if event.button() == Qt.LeftButton and self.toolTip():
|
|
798
|
+
self.highlight()
|
|
799
|
+
self.showMessageBox()
|
|
800
|
+
self.resetHighlight()
|
|
801
|
+
|
|
802
|
+
def showMessageBox(self):
|
|
803
|
+
if self.moviePixmap: pixmap=self.moviePixmap
|
|
804
|
+
else: pixmap=self.pixmap()
|
|
805
|
+
warningDialog(self.window(),Message=self.toolTip(),pixmap=pixmap,title='Info')
|
|
806
|
+
|
|
807
|
+
def highlight(self):
|
|
808
|
+
self.default_stylesheet = self.styleSheet() # <-- capture current style
|
|
809
|
+
self.setStyleSheet(self.highlight_stylesheet)
|
|
810
|
+
self.repaint()
|
|
811
|
+
|
|
812
|
+
def resetHighlight(self):
|
|
813
|
+
self.setStyleSheet(self.default_stylesheet)
|
|
814
|
+
|
|
815
|
+
def setToolTip(self,arg__1):
|
|
816
|
+
QLabel.setToolTip(self,arg__1)
|
|
817
|
+
QLabel.setStatusTip(self,arg__1)
|
|
818
|
+
if arg__1:
|
|
819
|
+
self.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
|
|
820
|
+
else:
|
|
821
|
+
self.setCursor(QCursor(Qt.CursorShape.ArrowCursor))
|
|
822
|
+
|
|
823
|
+
class ClickableEditLabel(ClickableLabel):
|
|
824
|
+
def setup(self):
|
|
825
|
+
le = QLineEdit()
|
|
826
|
+
bg = le.palette().color(QPalette.Base)
|
|
827
|
+
bg_rgba = f"rgba({bg.red()}, {bg.green()}, {bg.blue()}, {bg.alpha()})"
|
|
828
|
+
|
|
829
|
+
self.default_stylesheet = self.styleSheet() + f"""
|
|
830
|
+
ClickableEditLabel {{
|
|
831
|
+
background-color: {bg_rgba};
|
|
832
|
+
}}
|
|
833
|
+
"""
|
|
834
|
+
self.setStyleSheet(self.default_stylesheet)
|
|
835
|
+
le.setParent(None)
|
|
836
|
+
|
|
837
|
+
class CustomLineEdit(QLineEdit):
|
|
838
|
+
cancelEditing = Signal()
|
|
839
|
+
|
|
840
|
+
def __init__(self, text, parent=None):
|
|
841
|
+
super().__init__(text, parent)
|
|
842
|
+
self.originalText = text
|
|
843
|
+
|
|
844
|
+
def focusOutEvent(self, event):
|
|
845
|
+
self.cancelEditing.emit()
|
|
846
|
+
super().focusOutEvent(event)
|
|
847
|
+
|
|
848
|
+
def keyPressEvent(self, event):
|
|
849
|
+
if event.key() == Qt.Key.Key_Escape:
|
|
850
|
+
self.cancelEditing.emit()
|
|
851
|
+
else:
|
|
852
|
+
super().keyPressEvent(event)
|
|
853
|
+
|
|
854
|
+
def keyReleaseEvent(self, event):
|
|
855
|
+
if event.key() == Qt.Key.Key_Escape:
|
|
856
|
+
self.cancelEditing.emit()
|
|
857
|
+
else:
|
|
858
|
+
super().keyReleaseEvent(event)
|
|
859
|
+
|
|
860
|
+
class ResizingLabel(QLabel):
|
|
861
|
+
def __init__(self,*args,**kwargs):
|
|
862
|
+
super().__init__(*args,**kwargs)
|
|
863
|
+
self.complete_text=self.text()
|
|
864
|
+
|
|
865
|
+
def setText(self,text):
|
|
866
|
+
self.complete_text=text
|
|
867
|
+
self.resizeText(text)
|
|
868
|
+
return
|
|
869
|
+
|
|
870
|
+
def resizeEvent(self, event: QResizeEvent) -> None:
|
|
871
|
+
super().resizeEvent(event)
|
|
872
|
+
self.resizeText(self.text())
|
|
873
|
+
return
|
|
874
|
+
|
|
875
|
+
def resizeText(self,text):
|
|
876
|
+
text=self.complete_text
|
|
877
|
+
metrics = QFontMetrics(self.font())
|
|
878
|
+
if self.alignment() & Qt.AlignmentFlag.AlignRight:
|
|
879
|
+
FlagRight=True
|
|
880
|
+
textElideMode=Qt.TextElideMode.ElideLeft
|
|
881
|
+
else:
|
|
882
|
+
FlagRight=False
|
|
883
|
+
textElideMode=Qt.TextElideMode.ElideRight
|
|
884
|
+
if "<span" in text:
|
|
885
|
+
match = re.search(r"<span(.*?)</span>", text)
|
|
886
|
+
html_part = "<span"+match.group(1)+"</span>"
|
|
887
|
+
index = match.start(1)-5
|
|
888
|
+
text_without_bullet=text.replace(html_part,'')
|
|
889
|
+
truncated_text=metrics.elidedText(text_without_bullet, textElideMode, self.width()-5)
|
|
890
|
+
if FlagRight:
|
|
891
|
+
index=len(truncated_text)-3*(int('...' in truncated_text))-len(text_without_bullet[index:])
|
|
892
|
+
if index>0:
|
|
893
|
+
truncated_text=truncated_text[:index]+html_part+truncated_text[index:]
|
|
894
|
+
elif index>len(truncated_text)-3:
|
|
895
|
+
truncated_text=truncated_text[:index]+html_part+truncated_text[index:]
|
|
896
|
+
else:
|
|
897
|
+
truncated_text = metrics.elidedText(text, textElideMode, self.width())
|
|
898
|
+
super().setText(truncated_text)
|
|
899
|
+
|
|
900
|
+
class EditableLabel(QWidget):
|
|
901
|
+
def __init__(self, parent=None):
|
|
902
|
+
super().__init__(parent)
|
|
903
|
+
|
|
904
|
+
self.main_layout = QVBoxLayout(self)
|
|
905
|
+
self.main_layout.setContentsMargins(0,0,0,0)
|
|
906
|
+
self.main_layout.setSpacing(0)
|
|
907
|
+
|
|
908
|
+
self.label = ResizingLabel(self)
|
|
909
|
+
self.label.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
|
910
|
+
self.label.mouseDoubleClickEvent = self.enable_editing
|
|
911
|
+
|
|
912
|
+
self.edit = CustomLineEdit(self)
|
|
913
|
+
self.edit.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
|
914
|
+
self.edit.hide()
|
|
915
|
+
self.edit.editingFinished.connect(self.disable_editing)
|
|
916
|
+
self.edit.cancelEditing.connect(self.disable_editing)
|
|
917
|
+
self.updateLabel=lambda: None
|
|
918
|
+
self.bullet=''
|
|
919
|
+
|
|
920
|
+
self.installEventFilter(self) # Installare il filtro eventi
|
|
921
|
+
|
|
922
|
+
self.main_layout.addWidget(self.label)
|
|
923
|
+
self.main_layout.addWidget(self.edit)
|
|
924
|
+
|
|
925
|
+
def setText(self,text):
|
|
926
|
+
self.label.setText(text)
|
|
927
|
+
self.edit.setText(text)
|
|
928
|
+
|
|
929
|
+
def setFont(self,font:QFont):
|
|
930
|
+
self.label.setFont(font)
|
|
931
|
+
self.edit.setFont(font)
|
|
932
|
+
|
|
933
|
+
def enable_editing(self, event):
|
|
934
|
+
self.label.hide()
|
|
935
|
+
self.edit.setGeometry(self.label.geometry()) # Assicurati che l'editor prenda la posizione della label
|
|
936
|
+
self.edit.setText(self.label.text().replace(self.bullet,'')) # Assicurati che il testo corrente venga impostato nell'editor
|
|
937
|
+
self.edit.selectAll()
|
|
938
|
+
self.edit.show()
|
|
939
|
+
self.window().setFocus()
|
|
940
|
+
self.edit.setFocus()
|
|
941
|
+
|
|
942
|
+
def disable_editing(self):
|
|
943
|
+
self.edit.hide()
|
|
944
|
+
self.label.setText(self.edit.text())
|
|
945
|
+
self.label.show()
|
|
946
|
+
self.updateLabel()
|
|
947
|
+
|
|
948
|
+
def setButtonHoverStyle(w:QWidget,FlagBorder=True,borderRadius=6,FlagCls=True):
|
|
949
|
+
if FlagCls:
|
|
950
|
+
cls = w.metaObject().className()
|
|
951
|
+
base = w.styleSheet() or ""
|
|
952
|
+
if cls not in base: base=f"{cls} {{" +f"{base}"+"}"
|
|
953
|
+
if base and not base.endswith("\n"):
|
|
954
|
+
base += "\n"
|
|
955
|
+
else: cls=base=''
|
|
956
|
+
|
|
957
|
+
""""
|
|
958
|
+
style = (
|
|
959
|
+
f"{cls}:hover {{"
|
|
960
|
+
"background: qlineargradient("
|
|
961
|
+
"x1:0, y1:0, x2:0, y2:1, "
|
|
962
|
+
"stop:0 rgba(0, 116, 255, 0.05), "
|
|
963
|
+
"stop:0.2 rgba(0, 116, 255, 0.15), "
|
|
964
|
+
"stop:0.8 rgba(0, 116, 255, 0.15), "
|
|
965
|
+
"stop:1 rgba(0, 116, 255, 0.05));"
|
|
966
|
+
f"border-radius: {borderRadius}px;"
|
|
967
|
+
f"{'border: 1px solid gray;' if FlagBorder else ''}"
|
|
968
|
+
"padding: 2px 2px;"
|
|
969
|
+
"}"
|
|
970
|
+
)
|
|
971
|
+
"""
|
|
972
|
+
|
|
973
|
+
style = (
|
|
974
|
+
f"{cls}:hover {{"
|
|
975
|
+
f"border-radius: {borderRadius}px;"
|
|
976
|
+
f"background-color: none;"
|
|
977
|
+
f"{'border: 1px solid gray;' if FlagBorder else ''}"
|
|
978
|
+
"padding: 2px 2px;"
|
|
979
|
+
"}"
|
|
980
|
+
)
|
|
981
|
+
|
|
982
|
+
w.setStyleSheet(base + style)
|
|
983
|
+
|
|
984
|
+
def apply_hover_glow_label(
|
|
985
|
+
w: QLabel,
|
|
986
|
+
*,
|
|
987
|
+
color="#0051FF",
|
|
988
|
+
blur=18,
|
|
989
|
+
max_alpha=170,
|
|
990
|
+
duration_ms=160,
|
|
991
|
+
):
|
|
992
|
+
if getattr(w, "_hoverGlowInstalled", False):
|
|
993
|
+
w._hoverGlowColor = QColor(color)
|
|
994
|
+
w._hoverGlowBlur = float(blur)
|
|
995
|
+
w._hoverGlowMaxAlpha = int(max_alpha)
|
|
996
|
+
w._hoverGlowDuration = int(duration_ms)
|
|
997
|
+
w._hoverGlowEffect.setBlurRadius(w._hoverGlowBlur)
|
|
998
|
+
return
|
|
999
|
+
|
|
1000
|
+
w._hoverGlowInstalled = True
|
|
1001
|
+
w._hoverGlowColor = QColor(color)
|
|
1002
|
+
w._hoverGlowBlur = float(blur)
|
|
1003
|
+
w._hoverGlowMaxAlpha = int(max_alpha)
|
|
1004
|
+
w._hoverGlowDuration = int(duration_ms)
|
|
1005
|
+
|
|
1006
|
+
eff = QGraphicsDropShadowEffect(w)
|
|
1007
|
+
eff.setOffset(0, 0)
|
|
1008
|
+
eff.setBlurRadius(w._hoverGlowBlur)
|
|
1009
|
+
|
|
1010
|
+
c = QColor(w._hoverGlowColor)
|
|
1011
|
+
c.setAlpha(0)
|
|
1012
|
+
eff.setColor(c)
|
|
1013
|
+
|
|
1014
|
+
w.setGraphicsEffect(eff)
|
|
1015
|
+
w._hoverGlowEffect = eff
|
|
1016
|
+
|
|
1017
|
+
def _set_alpha(val):
|
|
1018
|
+
col = QColor(w._hoverGlowColor)
|
|
1019
|
+
col.setAlpha(int(val))
|
|
1020
|
+
w._hoverGlowEffect.setColor(col)
|
|
1021
|
+
|
|
1022
|
+
# ✅ Animate a plain value (no Qt property needed)
|
|
1023
|
+
w._hoverGlowAnimAlpha = QVariantAnimation(w)
|
|
1024
|
+
w._hoverGlowAnimAlpha.setEasingCurve(QEasingCurve.OutCubic)
|
|
1025
|
+
w._hoverGlowAnimAlpha.valueChanged.connect(_set_alpha)
|
|
1026
|
+
|
|
1027
|
+
class _GlowFilter(QObject):
|
|
1028
|
+
def eventFilter(self, obj, ev):
|
|
1029
|
+
if obj is not w:
|
|
1030
|
+
return False
|
|
1031
|
+
|
|
1032
|
+
t = ev.type()
|
|
1033
|
+
if t in (QEvent.Enter, QEvent.HoverEnter):
|
|
1034
|
+
w._hoverGlowAnimAlpha.stop()
|
|
1035
|
+
w._hoverGlowAnimAlpha.setDuration(w._hoverGlowDuration)
|
|
1036
|
+
w._hoverGlowAnimAlpha.setStartValue(w._hoverGlowEffect.color().alpha())
|
|
1037
|
+
w._hoverGlowAnimAlpha.setEndValue(w._hoverGlowMaxAlpha)
|
|
1038
|
+
w._hoverGlowAnimAlpha.start()
|
|
1039
|
+
|
|
1040
|
+
elif t in (QEvent.Leave, QEvent.HoverLeave):
|
|
1041
|
+
w._hoverGlowAnimAlpha.stop()
|
|
1042
|
+
w._hoverGlowAnimAlpha.setDuration(w._hoverGlowDuration)
|
|
1043
|
+
w._hoverGlowAnimAlpha.setStartValue(w._hoverGlowEffect.color().alpha())
|
|
1044
|
+
w._hoverGlowAnimAlpha.setEndValue(0)
|
|
1045
|
+
w._hoverGlowAnimAlpha.start()
|
|
1046
|
+
|
|
1047
|
+
return False
|
|
1048
|
+
|
|
1049
|
+
w._hoverGlowFilter = _GlowFilter(w)
|
|
1050
|
+
w.installEventFilter(w._hoverGlowFilter)
|
|
1051
|
+
|
|
1052
|
+
w.setAttribute(Qt.WA_Hover, True)
|
|
1053
|
+
w.setMouseTracking(True)
|
|
1054
|
+
|
|
1055
|
+
def remove_hover_glow_label(w: QLabel):
|
|
1056
|
+
"""Removes the hover glow behavior and restores a clean state."""
|
|
1057
|
+
if not getattr(w, "_hoverGlowInstalled", False):
|
|
1058
|
+
return
|
|
1059
|
+
|
|
1060
|
+
# Stop animation cleanly
|
|
1061
|
+
anim = getattr(w, "_hoverGlowAnimAlpha", None)
|
|
1062
|
+
if anim is not None:
|
|
1063
|
+
anim.stop()
|
|
1064
|
+
|
|
1065
|
+
# Remove event filter
|
|
1066
|
+
filt = getattr(w, "_hoverGlowFilter", None)
|
|
1067
|
+
if filt is not None:
|
|
1068
|
+
try:
|
|
1069
|
+
w.removeEventFilter(filt)
|
|
1070
|
+
except RuntimeError:
|
|
1071
|
+
pass
|
|
1072
|
+
|
|
1073
|
+
# Remove graphics effect
|
|
1074
|
+
w.setGraphicsEffect(None)
|
|
1075
|
+
|
|
1076
|
+
# Restore hover-related flags (safe defaults)
|
|
1077
|
+
w.setAttribute(Qt.WA_Hover, False)
|
|
1078
|
+
w.setMouseTracking(False)
|
|
1079
|
+
|
|
1080
|
+
# Cleanup attributes
|
|
1081
|
+
for attr in (
|
|
1082
|
+
"_hoverGlowInstalled",
|
|
1083
|
+
"_hoverGlowColor",
|
|
1084
|
+
"_hoverGlowBlur",
|
|
1085
|
+
"_hoverGlowMaxAlpha",
|
|
1086
|
+
"_hoverGlowDuration",
|
|
1087
|
+
"_hoverGlowEffect",
|
|
1088
|
+
"_hoverGlowAnimAlpha",
|
|
1089
|
+
"_hoverGlowFilter",
|
|
1090
|
+
):
|
|
1091
|
+
if hasattr(w, attr):
|
|
1092
|
+
delattr(w, attr)
|
|
1093
|
+
|
|
1094
|
+
class SliderHandleCursorFilter(QObject):
|
|
1095
|
+
def eventFilter(self, obj, event):
|
|
1096
|
+
if isinstance(obj, QSlider) and event.type() == QEvent.MouseMove:
|
|
1097
|
+
|
|
1098
|
+
opt = QStyleOptionSlider()
|
|
1099
|
+
obj.initStyleOption(opt)
|
|
1100
|
+
|
|
1101
|
+
handle_rect = obj.style().subControlRect(
|
|
1102
|
+
QStyle.CC_Slider,
|
|
1103
|
+
opt,
|
|
1104
|
+
QStyle.SC_SliderHandle,
|
|
1105
|
+
obj
|
|
1106
|
+
)
|
|
1107
|
+
|
|
1108
|
+
if handle_rect.contains(event.position().toPoint()):
|
|
1109
|
+
obj.setCursor(QCursor(Qt.OpenHandCursor))
|
|
1110
|
+
else:
|
|
1111
|
+
obj.unsetCursor()
|
|
1112
|
+
|
|
1113
|
+
return False
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
def changes(self,TabType,filename,title=" Changes"):
|
|
1117
|
+
FlagShow=False
|
|
1118
|
+
if self.logChanges:
|
|
1119
|
+
if self.logChanges.isVisible():
|
|
1120
|
+
FlagShow=True
|
|
1121
|
+
if FlagShow:
|
|
1122
|
+
self.logChanges.hide()
|
|
1123
|
+
self.logChanges.show()
|
|
1124
|
+
else:
|
|
1125
|
+
self.logChanges=TabType(self,True)
|
|
1126
|
+
self.logChanges.resize(720,720)
|
|
1127
|
+
self.logChanges.show()
|
|
1128
|
+
self.logChanges.ui.progress_Proc.hide()
|
|
1129
|
+
self.logChanges.ui.button_close_tab.hide()
|
|
1130
|
+
icon=QPixmap(''+ icons_path +'news.png')
|
|
1131
|
+
self.logChanges.ui.icon.setPixmap(icon)
|
|
1132
|
+
apply_hover_glow_label(self.logChanges.ui.icon)
|
|
1133
|
+
self.logChanges.setWindowIcon(self.windowIcon())
|
|
1134
|
+
self.logChanges.setWindowTitle(title)
|
|
1135
|
+
self.logChanges.ui.name_tab.setText(title)
|
|
1136
|
+
|
|
1137
|
+
self.logChanges.ui.log.setLineWrapColumnOrWidth(self.logChanges.ui.log.width()-20)
|
|
1138
|
+
base="""
|
|
1139
|
+
QTextEdit {
|
|
1140
|
+
border: 1px solid #2a2a2a;
|
|
1141
|
+
border-radius: 6px;
|
|
1142
|
+
|
|
1143
|
+
padding: 2px;
|
|
1144
|
+
|
|
1145
|
+
selection-background-color: #0051FF;
|
|
1146
|
+
selection-color: #FFFFFF;
|
|
1147
|
+
}
|
|
1148
|
+
"""
|
|
1149
|
+
self.logChanges.ui.log.setStyleSheet(base+"\n"+gPaIRS_QMenu_style)
|
|
1150
|
+
|
|
1151
|
+
def setFontPixelSize(logChanges:type(self.logChanges),fPixSize):
|
|
1152
|
+
logfont=self.font()
|
|
1153
|
+
logfont.setFamily(fontName)
|
|
1154
|
+
logfont.setPixelSize(fPixSize+2)
|
|
1155
|
+
logChanges.ui.log.setFont(logfont)
|
|
1156
|
+
fPixSize_TabNames=min([fPixSize*2,30])
|
|
1157
|
+
lab=logChanges.ui.name_tab
|
|
1158
|
+
font=lab.font()
|
|
1159
|
+
font.setPixelSize(fPixSize_TabNames)
|
|
1160
|
+
lab.setFont(font)
|
|
1161
|
+
self.logChanges.setFontPixelSize=lambda fS: setFontPixelSize(self.logChanges,fS)
|
|
1162
|
+
self.logChanges.setFontPixelSize(self.TABpar.fontPixelSize)
|
|
1163
|
+
def logResizeEvent(logChanges:type(self.logChanges),e):
|
|
1164
|
+
super(type(logChanges),logChanges).resizeEvent(e)
|
|
1165
|
+
logChanges.ui.log.setLineWrapColumnOrWidth(logChanges.ui.log.width()-20)
|
|
1166
|
+
self.logChanges.ui.log.resizeEvent=lambda e: logResizeEvent(self.logChanges,e)
|
|
1167
|
+
|
|
1168
|
+
self.logChanges.ui.icon.addfuncclick['whatsnew']=self.whatsNew
|
|
1169
|
+
self.logChanges.ui.icon.setCustomCursor()
|
|
1170
|
+
|
|
1171
|
+
try:
|
|
1172
|
+
file = open(filename, "rb")
|
|
1173
|
+
content = file.read().decode("utf-8")
|
|
1174
|
+
self.logChanges.ui.log.setText(content)
|
|
1175
|
+
file.close()
|
|
1176
|
+
except Exception as inst:
|
|
1177
|
+
pri.Error.red(f'There was a problem while reading the file {filename}:\n{inst}')
|
|
1178
|
+
self.logChanges.ui.log.setText(f'No information about PaIRS-UniNa updates available!\n\nSorry for this, try to reinstall PaIRS-UniNa or alternatively contact the authors at {__mail__}.')
|
|
1179
|
+
return
|
|
1180
|
+
|
|
1181
|
+
#********************************************* Matplotlib
|
|
1182
|
+
import io
|
|
1183
|
+
import matplotlib as mpl
|
|
1184
|
+
mpl.use('Qt5Agg')
|
|
1185
|
+
import matplotlib.pyplot as pyplt
|
|
1186
|
+
import matplotlib.image as mplimage
|
|
1187
|
+
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT as NavigationToolbar
|
|
1188
|
+
from matplotlib.figure import Figure as mplFigure
|
|
1189
|
+
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
|
1190
|
+
|
|
1191
|
+
import matplotlib.style as mplstyle
|
|
1192
|
+
mplstyle.use('fast')
|
|
1193
|
+
#mplstyle.use(['dark_background', 'ggplot', 'fast'])
|
|
1194
|
+
|
|
1195
|
+
class MplCanvas(FigureCanvasQTAgg):
|
|
1196
|
+
def __init__(self, parent=None, width=8, height=8, dpi=100):
|
|
1197
|
+
self.inp_width=width
|
|
1198
|
+
self.inp_height=height
|
|
1199
|
+
self.inp_dpi=dpi
|
|
1200
|
+
self.fig = mplFigure(figsize=(width, height), dpi=dpi)
|
|
1201
|
+
self.fig2=[]
|
|
1202
|
+
self.axes = self.fig.gca() #self.fig.add_subplot(111)
|
|
1203
|
+
self.addfuncrelease={}
|
|
1204
|
+
mpl.rcParams["font.family"]=fontName
|
|
1205
|
+
#mpl.rcParams["font.size"]=12
|
|
1206
|
+
color_tuple=(0.95,0.95,0.95,0)
|
|
1207
|
+
#clrgb=[int(i*255) for i in color_tuple]
|
|
1208
|
+
self.fig.set_facecolor(color_tuple)
|
|
1209
|
+
|
|
1210
|
+
self.copyIcon=QIcon(icons_path+"copy.png")
|
|
1211
|
+
self.openNewWindowIcon=QIcon(icons_path+"open_new_window.png")
|
|
1212
|
+
self.scaleDownIcon=QIcon(icons_path+"scale_down.png")
|
|
1213
|
+
self.scaleUpIcon=QIcon(icons_path+"scale_up.png")
|
|
1214
|
+
self.scaleAllIcon=QIcon(icons_path+"scale_all.png")
|
|
1215
|
+
self.showAllIcon=QIcon(icons_path+"show_all.png")
|
|
1216
|
+
self.alignAllIcon=QIcon(icons_path+"align_all.png")
|
|
1217
|
+
self.closeAllIcon=QIcon(icons_path+"close_all.png")
|
|
1218
|
+
self.loadImageIcon=QIcon(icons_path+"open_image.png")
|
|
1219
|
+
self.loadResultIcon=QIcon(icons_path+"open_result.png")
|
|
1220
|
+
|
|
1221
|
+
super(MplCanvas, self).__init__(self.fig)
|
|
1222
|
+
|
|
1223
|
+
def mouseReleaseEvent(self, event):
|
|
1224
|
+
super().mouseReleaseEvent(event)
|
|
1225
|
+
if event.button() == Qt.LeftButton:
|
|
1226
|
+
for f in self.addfuncrelease:
|
|
1227
|
+
self.addfuncrelease[f]()
|
|
1228
|
+
|
|
1229
|
+
def copy2clipboard(self):
|
|
1230
|
+
with io.BytesIO() as buffer:
|
|
1231
|
+
self.fig.savefig(buffer)
|
|
1232
|
+
QApplication.clipboard().setImage(QImage.fromData(buffer.getvalue()))
|
|
1233
|
+
self.showTip(self,'Image copied to clipboard!')
|
|
1234
|
+
|
|
1235
|
+
def copy2newfig(self,text='Vis'):
|
|
1236
|
+
fig2=QMainWindow()
|
|
1237
|
+
fig2.setPalette(self.palette())
|
|
1238
|
+
fig2.setWindowTitle(text)
|
|
1239
|
+
fig2.setStyleSheet("background-color: white;")
|
|
1240
|
+
|
|
1241
|
+
wid=QWidget(fig2)
|
|
1242
|
+
fig2.setCentralWidget(wid)
|
|
1243
|
+
lay=QVBoxLayout(wid)
|
|
1244
|
+
|
|
1245
|
+
lbl=QLabel(fig2)
|
|
1246
|
+
lbl.setAlignment(QtCore.Qt.AlignCenter)
|
|
1247
|
+
with io.BytesIO() as buffer:
|
|
1248
|
+
self.fig.savefig(buffer)
|
|
1249
|
+
pixmap = QPixmap(QImage.fromData(buffer.getvalue()))
|
|
1250
|
+
lbl.setPixmap(pixmap)
|
|
1251
|
+
lbl.setScaledContents(False)
|
|
1252
|
+
lbl2=QLabel(text,fig2)
|
|
1253
|
+
lbl2.setWordWrap(True)
|
|
1254
|
+
lbl2.setStyleSheet("color: black;")
|
|
1255
|
+
|
|
1256
|
+
lay.setSpacing(0)
|
|
1257
|
+
lay.addWidget(lbl)
|
|
1258
|
+
lay.addWidget(lbl2)
|
|
1259
|
+
|
|
1260
|
+
self.fig2.append(fig2)
|
|
1261
|
+
|
|
1262
|
+
def closeFig2(event):
|
|
1263
|
+
type(fig2).closeEvent(fig2,event)
|
|
1264
|
+
self.fig2.pop(self.fig2.index(fig2))
|
|
1265
|
+
return
|
|
1266
|
+
fig2.closeEvent=lambda event: closeFig2(event)
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
def fCopy2clipboard():
|
|
1270
|
+
QApplication.clipboard().setImage(lbl.pixmap().toImage())
|
|
1271
|
+
self.showTip(fig2,'Image copied to clipboard!')
|
|
1272
|
+
return
|
|
1273
|
+
|
|
1274
|
+
fig2.scaleFactor=1
|
|
1275
|
+
def resizeFig2(scale):
|
|
1276
|
+
fig2.scaleFactor=fig2.scaleFactor*scale
|
|
1277
|
+
fig2.scaleFactor=min([fig2.scaleFactor,1.5])
|
|
1278
|
+
fig2.scaleFactor=max([fig2.scaleFactor,0.5])
|
|
1279
|
+
fig2.setFixedSize(s0*fig2.scaleFactor)
|
|
1280
|
+
lbl.setPixmap(pixmap.scaled(pixmap.size()*fig2.scaleFactor,mode=Qt.TransformationMode.SmoothTransformation))
|
|
1281
|
+
return
|
|
1282
|
+
fig2.resizeFig2=resizeFig2
|
|
1283
|
+
|
|
1284
|
+
sc0=QGuiApplication.primaryScreen().geometry()
|
|
1285
|
+
def shiftFig2(dir):
|
|
1286
|
+
dpix=10
|
|
1287
|
+
geo=fig2.geometry()
|
|
1288
|
+
if dir=='u':
|
|
1289
|
+
geo.setY(max([geo.y()-dpix,sc0.y()]))
|
|
1290
|
+
elif dir=='d':
|
|
1291
|
+
geo.setY(min([geo.y()+dpix,sc0.y()+sc0.height()-fig2.height()]))
|
|
1292
|
+
elif dir=='l':
|
|
1293
|
+
geo.setX(max([geo.x()-dpix,sc0.x()]))
|
|
1294
|
+
elif dir=='r':
|
|
1295
|
+
geo.setX(min([geo.x()+dpix,sc0.x()+sc0.width()-fig2.width()]))
|
|
1296
|
+
fig2.setGeometry(geo)
|
|
1297
|
+
return
|
|
1298
|
+
|
|
1299
|
+
QS_down=QShortcut(QKeySequence('Down'), fig2)
|
|
1300
|
+
QS_down.activated.connect(lambda: shiftFig2('d'))
|
|
1301
|
+
QS_up=QShortcut(QKeySequence('Up'), fig2)
|
|
1302
|
+
QS_up.activated.connect(lambda: shiftFig2('u'))
|
|
1303
|
+
QS_right=QShortcut(QKeySequence('Right'), fig2)
|
|
1304
|
+
QS_right.activated.connect(lambda: shiftFig2('r'))
|
|
1305
|
+
QS_left=QShortcut(QKeySequence('Left'), fig2)
|
|
1306
|
+
QS_left.activated.connect(lambda: shiftFig2('l'))
|
|
1307
|
+
|
|
1308
|
+
QS_copy2clipboard=QShortcut(QKeySequence('Ctrl+C'), fig2)
|
|
1309
|
+
QS_copy2clipboard.activated.connect(fCopy2clipboard)
|
|
1310
|
+
|
|
1311
|
+
fScaleDown=lambda: resizeFig2(0.9)
|
|
1312
|
+
QS_scaleDown=QShortcut(QKeySequence('Ctrl+Down'), fig2)
|
|
1313
|
+
QS_scaleDown.activated.connect(fScaleDown)
|
|
1314
|
+
fScaleUp=lambda: resizeFig2(1.1)
|
|
1315
|
+
QS_scaleUp=QShortcut(QKeySequence('Ctrl+Up'), fig2)
|
|
1316
|
+
QS_scaleUp.activated.connect(fScaleUp)
|
|
1317
|
+
fScaleAll=lambda: self.scaleAll(fig2.scaleFactor)
|
|
1318
|
+
QS_scaleAll=QShortcut(QKeySequence('Ctrl+Return'), fig2)
|
|
1319
|
+
QS_scaleAll.activated.connect(fScaleAll)
|
|
1320
|
+
|
|
1321
|
+
QS_showAll=QShortcut(QKeySequence('Ctrl+S'), fig2)
|
|
1322
|
+
QS_showAll.activated.connect(self.showAll)
|
|
1323
|
+
QS_alignAll=QShortcut(QKeySequence('Ctrl+A'), fig2)
|
|
1324
|
+
QS_alignAll.activated.connect(self.alignAll)
|
|
1325
|
+
QS_closeAll=QShortcut(QKeySequence('Ctrl+X'), fig2)
|
|
1326
|
+
QS_closeAll.activated.connect(self.closeAll)
|
|
1327
|
+
|
|
1328
|
+
fig2.lbl:QLabel=lbl
|
|
1329
|
+
def contextMenuEventFig2(event):
|
|
1330
|
+
contextMenu = QMenu()
|
|
1331
|
+
contextMenu.setStyleSheet(self.parent().parent().gui.ui.menu.styleSheet())
|
|
1332
|
+
copy2clipboard = contextMenu.addAction("Copy to clipboard ("+QS_copy2clipboard.key().toString(QKeySequence.NativeText)+")")
|
|
1333
|
+
contextMenu.addSeparator()
|
|
1334
|
+
scaleDown = contextMenu.addAction("Scale down ("+QS_scaleDown.key().toString(QKeySequence.NativeText)+")")
|
|
1335
|
+
scaleUp = contextMenu.addAction("Scale up ("+QS_scaleUp.key().toString(QKeySequence.NativeText)+")")
|
|
1336
|
+
scaleAll = contextMenu.addAction("Scale all ("+QS_scaleAll.key().toString(QKeySequence.NativeText)+")")
|
|
1337
|
+
contextMenu.addSeparator()
|
|
1338
|
+
showAll = contextMenu.addAction("Show all ("+QS_showAll.key().toString(QKeySequence.NativeText)+")")
|
|
1339
|
+
alignAll = contextMenu.addAction("Align all ("+QS_alignAll.key().toString(QKeySequence.NativeText)+")")
|
|
1340
|
+
closeAll = contextMenu.addAction("Close all ("+QS_closeAll.key().toString(QKeySequence.NativeText)+")")
|
|
1341
|
+
|
|
1342
|
+
copy2clipboard.setIcon(self.copyIcon)
|
|
1343
|
+
scaleDown.setIcon(self.scaleDownIcon)
|
|
1344
|
+
scaleUp.setIcon(self.scaleUpIcon)
|
|
1345
|
+
scaleAll.setIcon(self.scaleAllIcon)
|
|
1346
|
+
showAll.setIcon(self.showAllIcon)
|
|
1347
|
+
alignAll.setIcon(self.alignAllIcon)
|
|
1348
|
+
closeAll.setIcon(self.closeAllIcon)
|
|
1349
|
+
|
|
1350
|
+
action = contextMenu.exec(fig2.mapToGlobal(event.pos()))
|
|
1351
|
+
|
|
1352
|
+
if action == copy2clipboard:
|
|
1353
|
+
fCopy2clipboard()
|
|
1354
|
+
elif action == scaleDown:
|
|
1355
|
+
fScaleDown()
|
|
1356
|
+
elif action == scaleUp:
|
|
1357
|
+
fScaleUp()
|
|
1358
|
+
elif action == scaleAll:
|
|
1359
|
+
self.scaleAll(fig2.scaleFactor)
|
|
1360
|
+
elif action == showAll:
|
|
1361
|
+
self.showAll()
|
|
1362
|
+
elif action == alignAll:
|
|
1363
|
+
self.alignAll()
|
|
1364
|
+
elif action == closeAll:
|
|
1365
|
+
self.closeAll()
|
|
1366
|
+
|
|
1367
|
+
|
|
1368
|
+
fig2.contextMenuEvent=lambda event: contextMenuEventFig2(event)
|
|
1369
|
+
|
|
1370
|
+
fig2.show()
|
|
1371
|
+
fig2.setFixedSize(fig2.width(), fig2.height())
|
|
1372
|
+
s0=fig2.size()
|
|
1373
|
+
|
|
1374
|
+
self.posWindow(len(self.fig2)-1)
|
|
1375
|
+
"""
|
|
1376
|
+
fgeo = fig2.frameGeometry()
|
|
1377
|
+
centerPoint = QGuiApplication.primaryScreen().availableGeometry().center()
|
|
1378
|
+
fgeo.moveCenter(centerPoint)
|
|
1379
|
+
fig2.move(fgeo.topLeft())
|
|
1380
|
+
"""
|
|
1381
|
+
|
|
1382
|
+
def showTip(self,obj,message):
|
|
1383
|
+
show_mouse_tooltip(obj,message)
|
|
1384
|
+
|
|
1385
|
+
def posWindow(self,ind):
|
|
1386
|
+
w=h=0
|
|
1387
|
+
for f in self.fig2:
|
|
1388
|
+
f:QMainWindow
|
|
1389
|
+
w=max([w,f.frameGeometry().width()])
|
|
1390
|
+
h=max([h,f.frameGeometry().height()])
|
|
1391
|
+
geoS=QGuiApplication.primaryScreen().availableGeometry()
|
|
1392
|
+
ncol=int(geoS.width()/w)
|
|
1393
|
+
nrow=int(geoS.height()/h)
|
|
1394
|
+
ntot=ncol*nrow
|
|
1395
|
+
if ind<0: ind=range(len(self.fig2))
|
|
1396
|
+
else: ind=[ind]
|
|
1397
|
+
for kk in ind:
|
|
1398
|
+
k=kk%ntot
|
|
1399
|
+
k=kk
|
|
1400
|
+
i=int(k/ncol)
|
|
1401
|
+
j=k-i*ncol
|
|
1402
|
+
f=self.fig2[kk]
|
|
1403
|
+
fg=f.frameGeometry()
|
|
1404
|
+
fg.moveTopLeft(QPoint(j*w,i*h))
|
|
1405
|
+
f.move(fg.topLeft())
|
|
1406
|
+
|
|
1407
|
+
def scaleAll(self,scale):
|
|
1408
|
+
for f in self.fig2:
|
|
1409
|
+
f:QMainWindow
|
|
1410
|
+
f.scaleFactor=scale
|
|
1411
|
+
f.resizeFig2(1.0)
|
|
1412
|
+
|
|
1413
|
+
def showAll(self):
|
|
1414
|
+
for f in self.fig2:
|
|
1415
|
+
f:QMainWindow
|
|
1416
|
+
f.hide()
|
|
1417
|
+
f.show()
|
|
1418
|
+
|
|
1419
|
+
def closeAll(self):
|
|
1420
|
+
for f in range(len(self.fig2)):
|
|
1421
|
+
f:QMainWindow
|
|
1422
|
+
f=self.fig2[0]
|
|
1423
|
+
f.close()
|
|
1424
|
+
self.fig2=[]
|
|
1425
|
+
|
|
1426
|
+
def alignAll(self):
|
|
1427
|
+
self.posWindow(-1)
|
|
1428
|
+
self.showAll()
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
def setAppGuiPalette(self:QWidget,palette:QPalette=None):
|
|
1432
|
+
applic:QApplication
|
|
1433
|
+
if hasattr(self,'app'):
|
|
1434
|
+
applic=self.app
|
|
1435
|
+
else:
|
|
1436
|
+
return
|
|
1437
|
+
if palette==None:
|
|
1438
|
+
palette=applic.style().standardPalette()
|
|
1439
|
+
else:
|
|
1440
|
+
applic.setPalette(palette)
|
|
1441
|
+
|
|
1442
|
+
try:
|
|
1443
|
+
if self.focusWidget():
|
|
1444
|
+
self.focusWidget().clearFocus()
|
|
1445
|
+
widgets=[self]
|
|
1446
|
+
if hasattr(self,'FloatingTabs'): widgets+=self.FloatingTabs
|
|
1447
|
+
if hasattr(self,'FloatingWindows'): widgets+=self.FloatingWindows
|
|
1448
|
+
if hasattr(self,'aboutDialog'): widgets.append(self.aboutDialog)
|
|
1449
|
+
if hasattr(self,'logChanges'): widgets.append(self.logChanges)
|
|
1450
|
+
widgets+=self.findChildren(QDialog)
|
|
1451
|
+
for f in widgets:
|
|
1452
|
+
if f and isinstance(f, QWidget):
|
|
1453
|
+
f.setPalette(palette)
|
|
1454
|
+
for c in f.findChildren(QObject):
|
|
1455
|
+
if hasattr(c,'setPalette') and not isinstance(c, (MplCanvas, mplFigure, QStatusBar)):
|
|
1456
|
+
c.setPalette(palette)
|
|
1457
|
+
if hasattr(c,'initialStyle') and hasattr(c, 'setStyleSheet'):
|
|
1458
|
+
c.setStyleSheet(c.initialStyle)
|
|
1459
|
+
for c in f.findChildren(MyQLineEdit):
|
|
1460
|
+
c.initFlag=False
|
|
1461
|
+
c.styleFlag=False
|
|
1462
|
+
c.setup()
|
|
1463
|
+
for c in f.findChildren(ClickableEditLabel):
|
|
1464
|
+
c.setup()
|
|
1465
|
+
for c in f.findChildren(QObject):
|
|
1466
|
+
if hasattr(c,'setup2'):
|
|
1467
|
+
c.initFlag2=False
|
|
1468
|
+
c.setup2()
|
|
1469
|
+
if hasattr(self,'ResizePopup'):
|
|
1470
|
+
if self.ResizePopup is not None:
|
|
1471
|
+
self.ResizePopup=type(self.ResizePopup)(self.buttonSizeCallbacks) #non riesco a farlo come gli altri
|
|
1472
|
+
if hasattr(self,'w_Vis'): self.w_Vis.addPlotToolBar()
|
|
1473
|
+
except:
|
|
1474
|
+
pri.Error.red("***** Error while setting the application palette! *****")
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
class Toast(QFrame):
|
|
1478
|
+
"""
|
|
1479
|
+
Tooltip-like custom toast that appears at the current mouse cursor position.
|
|
1480
|
+
Non-native, does not steal focus. Auto-hides after timeout_ms.
|
|
1481
|
+
"""
|
|
1482
|
+
|
|
1483
|
+
def __init__(
|
|
1484
|
+
self,
|
|
1485
|
+
parent: QWidget,
|
|
1486
|
+
msg: str,
|
|
1487
|
+
*,
|
|
1488
|
+
timeout_ms: int = 2500,
|
|
1489
|
+
offset: QPoint = QPoint(10, 15), # offset from cursor
|
|
1490
|
+
min_width: int = 0,
|
|
1491
|
+
max_width: int = 460,
|
|
1492
|
+
fade_in_ms: int = 80,
|
|
1493
|
+
fade_out_ms: int = 130,
|
|
1494
|
+
):
|
|
1495
|
+
super().__init__(parent)
|
|
1496
|
+
|
|
1497
|
+
self.setObjectName("PaIRSToast")
|
|
1498
|
+
self.setWindowFlags(Qt.FramelessWindowHint | Qt.ToolTip)
|
|
1499
|
+
#self.setAttribute(Qt.WA_TranslucentBackground, True)
|
|
1500
|
+
self.setAttribute(Qt.WA_ShowWithoutActivating, True)
|
|
1501
|
+
|
|
1502
|
+
self._label = QLabel(msg, self)
|
|
1503
|
+
self._label.setObjectName("PaIRSToastLabel")
|
|
1504
|
+
self._label.setWordWrap(True)
|
|
1505
|
+
|
|
1506
|
+
lay = QHBoxLayout(self)
|
|
1507
|
+
lay.setContentsMargins(4,3,4,3)
|
|
1508
|
+
lay.addWidget(self._label)
|
|
1509
|
+
|
|
1510
|
+
# Classic tooltip-like styling
|
|
1511
|
+
self.setStyleSheet("""
|
|
1512
|
+
QFrame#PaIRSToast {
|
|
1513
|
+
background-color: #ffffdc; /* classic tooltip-ish */
|
|
1514
|
+
color: #000000;
|
|
1515
|
+
border: 1px solid rgba(0, 0, 0, 0.45);
|
|
1516
|
+
border-radius: 4px;
|
|
1517
|
+
}
|
|
1518
|
+
QLabel#PaIRSToastLabel {
|
|
1519
|
+
color: #000000;
|
|
1520
|
+
}
|
|
1521
|
+
""")
|
|
1522
|
+
|
|
1523
|
+
# Width clamp + nice wrapping
|
|
1524
|
+
# Reset any previous constraints (important if a previous tooltip was wider)
|
|
1525
|
+
self.setMinimumSize(min_width, 0)
|
|
1526
|
+
self.setMaximumSize(max_width, 16777215)
|
|
1527
|
+
|
|
1528
|
+
self._label.setMinimumSize(min_width, 0)
|
|
1529
|
+
self._label.setMaximumSize(max_width, 16777215)
|
|
1530
|
+
|
|
1531
|
+
# Make sure the label doesn't "expand"
|
|
1532
|
+
self._label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
|
1533
|
+
|
|
1534
|
+
font=self.window().font()
|
|
1535
|
+
self._label.setFont(font)
|
|
1536
|
+
self._apply_size(msg)
|
|
1537
|
+
|
|
1538
|
+
# Position at cursor (global)
|
|
1539
|
+
self._move_to_cursor(offset)
|
|
1540
|
+
|
|
1541
|
+
# Opacity animation
|
|
1542
|
+
self.setWindowOpacity(0.0)
|
|
1543
|
+
self._anim = QPropertyAnimation(self, b"windowOpacity", self)
|
|
1544
|
+
self._anim.setEasingCurve(QEasingCurve.OutCubic)
|
|
1545
|
+
|
|
1546
|
+
# Auto hide
|
|
1547
|
+
self._timer = QTimer(self)
|
|
1548
|
+
self._timer.setSingleShot(True)
|
|
1549
|
+
self._timer.timeout.connect(lambda: self.fade_out(duration_ms=fade_out_ms))
|
|
1550
|
+
|
|
1551
|
+
self.show()
|
|
1552
|
+
self.raise_()
|
|
1553
|
+
self.fade_in(duration_ms=fade_in_ms)
|
|
1554
|
+
self._timer.start(timeout_ms)
|
|
1555
|
+
|
|
1556
|
+
def _apply_size(self, msg: str):
|
|
1557
|
+
self._label.setText(msg)
|
|
1558
|
+
|
|
1559
|
+
# Let QLabel compute the correct wrapped size
|
|
1560
|
+
self._label.adjustSize()
|
|
1561
|
+
sh = self._label.sizeHint()
|
|
1562
|
+
|
|
1563
|
+
# Lock label to its real hint size
|
|
1564
|
+
self._label.setFixedSize(sh)
|
|
1565
|
+
|
|
1566
|
+
# Now shrink the frame to content + margins
|
|
1567
|
+
self.adjustSize()
|
|
1568
|
+
|
|
1569
|
+
# Lock the whole toaster too (prevents extra blank area)
|
|
1570
|
+
self.setFixedSize(self.sizeHint())
|
|
1571
|
+
|
|
1572
|
+
def _move_to_cursor(self, offset: QPoint):
|
|
1573
|
+
parent = self.parent()
|
|
1574
|
+
if hasattr(parent, "cursorRect"):
|
|
1575
|
+
rect = parent.cursorRect() # QRect in coordinate del widget
|
|
1576
|
+
p = parent.mapToGlobal(rect.bottomRight())
|
|
1577
|
+
else:
|
|
1578
|
+
p = QCursor.pos() + offset
|
|
1579
|
+
|
|
1580
|
+
# Keep inside the current screen geometry
|
|
1581
|
+
screen = self.screen()
|
|
1582
|
+
if screen is None:
|
|
1583
|
+
self.move(p)
|
|
1584
|
+
return
|
|
1585
|
+
|
|
1586
|
+
geo = screen.availableGeometry()
|
|
1587
|
+
self.adjustSize()
|
|
1588
|
+
w, h = self.width(), self.height()
|
|
1589
|
+
|
|
1590
|
+
x = p.x()
|
|
1591
|
+
y = p.y()
|
|
1592
|
+
|
|
1593
|
+
if x + w > geo.right():
|
|
1594
|
+
x = geo.right() - w
|
|
1595
|
+
if y + h > geo.bottom():
|
|
1596
|
+
y = geo.bottom() - h
|
|
1597
|
+
if x < geo.left():
|
|
1598
|
+
x = geo.left()
|
|
1599
|
+
if y < geo.top():
|
|
1600
|
+
y = geo.top()
|
|
1601
|
+
|
|
1602
|
+
self.move(QPoint(x, y))
|
|
1603
|
+
|
|
1604
|
+
def fade_in(self, *, duration_ms: int = 80):
|
|
1605
|
+
self._anim.stop()
|
|
1606
|
+
self._anim.setDuration(duration_ms)
|
|
1607
|
+
self._anim.setStartValue(self.windowOpacity())
|
|
1608
|
+
self._anim.setEndValue(1.0)
|
|
1609
|
+
self._anim.start()
|
|
1610
|
+
|
|
1611
|
+
def fade_out(self, *, duration_ms: int = 130):
|
|
1612
|
+
self._anim.stop()
|
|
1613
|
+
self._anim.setDuration(duration_ms)
|
|
1614
|
+
self._anim.setStartValue(self.windowOpacity())
|
|
1615
|
+
self._anim.setEndValue(0.0)
|
|
1616
|
+
self._anim.finished.connect(self.close)
|
|
1617
|
+
self._anim.start()
|
|
1618
|
+
|
|
1619
|
+
def show_mouse_tooltip(parent: QWidget, msg: str, *, timeout_ms: int = 2500):
|
|
1620
|
+
"""
|
|
1621
|
+
Convenience function: show a tooltip-like toaster at the mouse cursor.
|
|
1622
|
+
Keeps a reference on parent to avoid garbage collection.
|
|
1623
|
+
"""
|
|
1624
|
+
old = getattr(parent, "_pairs_mouse_toaster", None)
|
|
1625
|
+
if old is not None and old.isVisible():
|
|
1626
|
+
old.close()
|
|
1627
|
+
|
|
1628
|
+
if msg:
|
|
1629
|
+
t = Toast(parent, msg, timeout_ms=timeout_ms)
|
|
1630
|
+
else: t=None
|
|
1631
|
+
parent._pairs_mouse_toaster = t
|
|
1632
|
+
return t
|
|
1633
|
+
|