PaIRS-UniNa 0.2.9__cp310-cp310-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.
Files changed (333) hide show
  1. PaIRS_UniNa/Calibration_Tab.py +346 -0
  2. PaIRS_UniNa/Changes.txt +162 -0
  3. PaIRS_UniNa/Custom_Top.py +303 -0
  4. PaIRS_UniNa/Explorer.py +3168 -0
  5. PaIRS_UniNa/FolderLoop.py +562 -0
  6. PaIRS_UniNa/Input_Tab.py +831 -0
  7. PaIRS_UniNa/Input_Tab_CalVi.py +786 -0
  8. PaIRS_UniNa/Input_Tab_tools.py +3022 -0
  9. PaIRS_UniNa/Log_Tab.py +110 -0
  10. PaIRS_UniNa/Output_Tab.py +922 -0
  11. PaIRS_UniNa/PaIRS.py +18 -0
  12. PaIRS_UniNa/PaIRS_PIV.py +873 -0
  13. PaIRS_UniNa/PaIRS_pypacks.py +1421 -0
  14. PaIRS_UniNa/Process_Tab.py +1757 -0
  15. PaIRS_UniNa/Process_Tab_CalVi.py +313 -0
  16. PaIRS_UniNa/Process_Tab_Disp.py +163 -0
  17. PaIRS_UniNa/Process_Tab_Min.py +120 -0
  18. PaIRS_UniNa/ResizePopup.py +55 -0
  19. PaIRS_UniNa/SPIVCalHelp.py +155 -0
  20. PaIRS_UniNa/Saving_tools.py +296 -0
  21. PaIRS_UniNa/TabTools.py +1254 -0
  22. PaIRS_UniNa/Vis_Tab.py +2169 -0
  23. PaIRS_UniNa/Vis_Tab_CalVi.py +983 -0
  24. PaIRS_UniNa/Whatsnew.py +130 -0
  25. PaIRS_UniNa/_PaIRS_PIV.so +0 -0
  26. PaIRS_UniNa/__init__.py +6 -0
  27. PaIRS_UniNa/__main__.py +45 -0
  28. PaIRS_UniNa/addwidgets_ps.py +1133 -0
  29. PaIRS_UniNa/calib.py +1488 -0
  30. PaIRS_UniNa/calibView.py +833 -0
  31. PaIRS_UniNa/gPaIRS.py +3914 -0
  32. PaIRS_UniNa/gPalette.py +189 -0
  33. PaIRS_UniNa/icons/abort.png +0 -0
  34. PaIRS_UniNa/icons/about.png +0 -0
  35. PaIRS_UniNa/icons/align_all.png +0 -0
  36. PaIRS_UniNa/icons/announcement.png +0 -0
  37. PaIRS_UniNa/icons/automatic_levels_off.png +0 -0
  38. PaIRS_UniNa/icons/automatic_levels_on.png +0 -0
  39. PaIRS_UniNa/icons/automatic_off.png +0 -0
  40. PaIRS_UniNa/icons/automatic_on.png +0 -0
  41. PaIRS_UniNa/icons/automatic_size_off.png +0 -0
  42. PaIRS_UniNa/icons/automatic_size_on.png +0 -0
  43. PaIRS_UniNa/icons/axes.png +0 -0
  44. PaIRS_UniNa/icons/background.png +0 -0
  45. PaIRS_UniNa/icons/background_vectors.png +0 -0
  46. PaIRS_UniNa/icons/bin_off.png +0 -0
  47. PaIRS_UniNa/icons/bin_on.png +0 -0
  48. PaIRS_UniNa/icons/browse_file_c.png +0 -0
  49. PaIRS_UniNa/icons/browse_folder_c.png +0 -0
  50. PaIRS_UniNa/icons/brush_cursor.png +0 -0
  51. PaIRS_UniNa/icons/bugfix.png +0 -0
  52. PaIRS_UniNa/icons/cal_proc.png +0 -0
  53. PaIRS_UniNa/icons/cal_proc_off.png +0 -0
  54. PaIRS_UniNa/icons/cal_step.png +0 -0
  55. PaIRS_UniNa/icons/cal_step_off.png +0 -0
  56. PaIRS_UniNa/icons/calibrate.png +0 -0
  57. PaIRS_UniNa/icons/calibration_logo.png +0 -0
  58. PaIRS_UniNa/icons/change_folder.png +0 -0
  59. PaIRS_UniNa/icons/change_folder_off.png +0 -0
  60. PaIRS_UniNa/icons/checklist.png +0 -0
  61. PaIRS_UniNa/icons/clean.png +0 -0
  62. PaIRS_UniNa/icons/clean_run.png +0 -0
  63. PaIRS_UniNa/icons/close.png +0 -0
  64. PaIRS_UniNa/icons/close_all.png +0 -0
  65. PaIRS_UniNa/icons/close_project.png +0 -0
  66. PaIRS_UniNa/icons/close_workspace.png +0 -0
  67. PaIRS_UniNa/icons/colormap.png +0 -0
  68. PaIRS_UniNa/icons/colormaps/Accent.png +0 -0
  69. PaIRS_UniNa/icons/colormaps/BrBG.png +0 -0
  70. PaIRS_UniNa/icons/colormaps/Dark2.png +0 -0
  71. PaIRS_UniNa/icons/colormaps/PRGn.png +0 -0
  72. PaIRS_UniNa/icons/colormaps/Paired.png +0 -0
  73. PaIRS_UniNa/icons/colormaps/Pastel1.png +0 -0
  74. PaIRS_UniNa/icons/colormaps/Pastel2.png +0 -0
  75. PaIRS_UniNa/icons/colormaps/PiYG.png +0 -0
  76. PaIRS_UniNa/icons/colormaps/PuOr.png +0 -0
  77. PaIRS_UniNa/icons/colormaps/RdBu.png +0 -0
  78. PaIRS_UniNa/icons/colormaps/RdGy.png +0 -0
  79. PaIRS_UniNa/icons/colormaps/RdYlBu.png +0 -0
  80. PaIRS_UniNa/icons/colormaps/RdYlGn.png +0 -0
  81. PaIRS_UniNa/icons/colormaps/Set1.png +0 -0
  82. PaIRS_UniNa/icons/colormaps/Set2.png +0 -0
  83. PaIRS_UniNa/icons/colormaps/Set3.png +0 -0
  84. PaIRS_UniNa/icons/colormaps/Spectral.png +0 -0
  85. PaIRS_UniNa/icons/colormaps/Wistia.png +0 -0
  86. PaIRS_UniNa/icons/colormaps/afmhot.png +0 -0
  87. PaIRS_UniNa/icons/colormaps/autumn.png +0 -0
  88. PaIRS_UniNa/icons/colormaps/binary.png +0 -0
  89. PaIRS_UniNa/icons/colormaps/blackVector.png +0 -0
  90. PaIRS_UniNa/icons/colormaps/blueVector.png +0 -0
  91. PaIRS_UniNa/icons/colormaps/bone.png +0 -0
  92. PaIRS_UniNa/icons/colormaps/brg.png +0 -0
  93. PaIRS_UniNa/icons/colormaps/bwr.png +0 -0
  94. PaIRS_UniNa/icons/colormaps/cividis.png +0 -0
  95. PaIRS_UniNa/icons/colormaps/cool.png +0 -0
  96. PaIRS_UniNa/icons/colormaps/coolwarm.png +0 -0
  97. PaIRS_UniNa/icons/colormaps/copper.png +0 -0
  98. PaIRS_UniNa/icons/colormaps/cubehelix.png +0 -0
  99. PaIRS_UniNa/icons/colormaps/cyanVector.png +0 -0
  100. PaIRS_UniNa/icons/colormaps/flag.png +0 -0
  101. PaIRS_UniNa/icons/colormaps/gist_heat.png +0 -0
  102. PaIRS_UniNa/icons/colormaps/gray.png +0 -0
  103. PaIRS_UniNa/icons/colormaps/greenVector.png +0 -0
  104. PaIRS_UniNa/icons/colormaps/hot.png +0 -0
  105. PaIRS_UniNa/icons/colormaps/hsv.png +0 -0
  106. PaIRS_UniNa/icons/colormaps/inferno.png +0 -0
  107. PaIRS_UniNa/icons/colormaps/jet.png +0 -0
  108. PaIRS_UniNa/icons/colormaps/magentaVector.png +0 -0
  109. PaIRS_UniNa/icons/colormaps/magma.png +0 -0
  110. PaIRS_UniNa/icons/colormaps/ocean.png +0 -0
  111. PaIRS_UniNa/icons/colormaps/pink.png +0 -0
  112. PaIRS_UniNa/icons/colormaps/plasma.png +0 -0
  113. PaIRS_UniNa/icons/colormaps/prism.png +0 -0
  114. PaIRS_UniNa/icons/colormaps/rainbow.png +0 -0
  115. PaIRS_UniNa/icons/colormaps/redVector.png +0 -0
  116. PaIRS_UniNa/icons/colormaps/seismic.png +0 -0
  117. PaIRS_UniNa/icons/colormaps/spring.png +0 -0
  118. PaIRS_UniNa/icons/colormaps/summer.png +0 -0
  119. PaIRS_UniNa/icons/colormaps/tab10.png +0 -0
  120. PaIRS_UniNa/icons/colormaps/tab20.png +0 -0
  121. PaIRS_UniNa/icons/colormaps/tab20b.png +0 -0
  122. PaIRS_UniNa/icons/colormaps/tab20c.png +0 -0
  123. PaIRS_UniNa/icons/colormaps/terrain.png +0 -0
  124. PaIRS_UniNa/icons/colormaps/twilight.png +0 -0
  125. PaIRS_UniNa/icons/colormaps/viridis.png +0 -0
  126. PaIRS_UniNa/icons/colormaps/whiteVector.png +0 -0
  127. PaIRS_UniNa/icons/colormaps/winter.png +0 -0
  128. PaIRS_UniNa/icons/colormaps/yellowVector.png +0 -0
  129. PaIRS_UniNa/icons/common_region.png +0 -0
  130. PaIRS_UniNa/icons/common_region_off.png +0 -0
  131. PaIRS_UniNa/icons/completed.png +0 -0
  132. PaIRS_UniNa/icons/contourf_off.png +0 -0
  133. PaIRS_UniNa/icons/contourf_on.png +0 -0
  134. PaIRS_UniNa/icons/copy.png +0 -0
  135. PaIRS_UniNa/icons/copy_process.png +0 -0
  136. PaIRS_UniNa/icons/copy_process_off.png +0 -0
  137. PaIRS_UniNa/icons/copygrid.png +0 -0
  138. PaIRS_UniNa/icons/cursor_lamp.png +0 -0
  139. PaIRS_UniNa/icons/cut.png +0 -0
  140. PaIRS_UniNa/icons/cut_warnings.png +0 -0
  141. PaIRS_UniNa/icons/darkmode.png +0 -0
  142. PaIRS_UniNa/icons/debug_run.png +0 -0
  143. PaIRS_UniNa/icons/delete.png +0 -0
  144. PaIRS_UniNa/icons/deleteErr.png +0 -0
  145. PaIRS_UniNa/icons/disp_step.png +0 -0
  146. PaIRS_UniNa/icons/disp_step_off.png +0 -0
  147. PaIRS_UniNa/icons/down.png +0 -0
  148. PaIRS_UniNa/icons/edit_list.png +0 -0
  149. PaIRS_UniNa/icons/editing.png +0 -0
  150. PaIRS_UniNa/icons/example_list.png +0 -0
  151. PaIRS_UniNa/icons/find_all_planes.png +0 -0
  152. PaIRS_UniNa/icons/find_plane.png +0 -0
  153. PaIRS_UniNa/icons/flaticon_PaIRS.png +0 -0
  154. PaIRS_UniNa/icons/flaticon_PaIRS_beta.png +0 -0
  155. PaIRS_UniNa/icons/flaticon_PaIRS_download.png +0 -0
  156. PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
  157. PaIRS_UniNa/icons/flip_y_off.png +0 -0
  158. PaIRS_UniNa/icons/flip_y_on.png +0 -0
  159. PaIRS_UniNa/icons/focusErrr.png +0 -0
  160. PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
  161. PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
  162. PaIRS_UniNa/icons/gear.gif +0 -0
  163. PaIRS_UniNa/icons/gear.png +0 -0
  164. PaIRS_UniNa/icons/ger.png +0 -0
  165. PaIRS_UniNa/icons/greenv.png +0 -0
  166. PaIRS_UniNa/icons/guide.png +0 -0
  167. PaIRS_UniNa/icons/icon_CalVi.png +0 -0
  168. PaIRS_UniNa/icons/icon_PaIRS.png +0 -0
  169. PaIRS_UniNa/icons/import.png +0 -0
  170. PaIRS_UniNa/icons/import_set.png +0 -0
  171. PaIRS_UniNa/icons/information.png +0 -0
  172. PaIRS_UniNa/icons/information2.png +0 -0
  173. PaIRS_UniNa/icons/input_logo.png +0 -0
  174. PaIRS_UniNa/icons/issue.png +0 -0
  175. PaIRS_UniNa/icons/laser_NTR.png +0 -0
  176. PaIRS_UniNa/icons/laser_TR_double.png +0 -0
  177. PaIRS_UniNa/icons/laser_TR_single.png +0 -0
  178. PaIRS_UniNa/icons/link.png +0 -0
  179. PaIRS_UniNa/icons/linked.png +0 -0
  180. PaIRS_UniNa/icons/loaded.png +0 -0
  181. PaIRS_UniNa/icons/loading_2.gif +0 -0
  182. PaIRS_UniNa/icons/log_logo.png +0 -0
  183. PaIRS_UniNa/icons/logo_CalVi.png +0 -0
  184. PaIRS_UniNa/icons/logo_CalVi_completo.png +0 -0
  185. PaIRS_UniNa/icons/logo_CalVi_party.png +0 -0
  186. PaIRS_UniNa/icons/logo_PaIRS.png +0 -0
  187. PaIRS_UniNa/icons/logo_PaIRS_completo.png +0 -0
  188. PaIRS_UniNa/icons/logo_PaIRS_download.png +0 -0
  189. PaIRS_UniNa/icons/logo_PaIRS_party_rect.png +0 -0
  190. PaIRS_UniNa/icons/logo_PaIRS_rect.png +0 -0
  191. PaIRS_UniNa/icons/logo_opaco.png +0 -0
  192. PaIRS_UniNa/icons/mask.png +0 -0
  193. PaIRS_UniNa/icons/measure.png +0 -0
  194. PaIRS_UniNa/icons/measure_off.png +0 -0
  195. PaIRS_UniNa/icons/min_proc.png +0 -0
  196. PaIRS_UniNa/icons/min_proc_off.png +0 -0
  197. PaIRS_UniNa/icons/min_step.png +0 -0
  198. PaIRS_UniNa/icons/min_step_off.png +0 -0
  199. PaIRS_UniNa/icons/minus.png +0 -0
  200. PaIRS_UniNa/icons/mirror_u.png +0 -0
  201. PaIRS_UniNa/icons/mirror_v.png +0 -0
  202. PaIRS_UniNa/icons/mirror_x.png +0 -0
  203. PaIRS_UniNa/icons/mirror_y.png +0 -0
  204. PaIRS_UniNa/icons/mtplt.png +0 -0
  205. PaIRS_UniNa/icons/new.png +0 -0
  206. PaIRS_UniNa/icons/new_workspace.png +0 -0
  207. PaIRS_UniNa/icons/news.png +0 -0
  208. PaIRS_UniNa/icons/normal_run.png +0 -0
  209. PaIRS_UniNa/icons/open.png +0 -0
  210. PaIRS_UniNa/icons/open_image.png +0 -0
  211. PaIRS_UniNa/icons/open_new_window.png +0 -0
  212. PaIRS_UniNa/icons/open_result.png +0 -0
  213. PaIRS_UniNa/icons/open_workspace.png +0 -0
  214. PaIRS_UniNa/icons/output_logo.png +0 -0
  215. PaIRS_UniNa/icons/paste_above.png +0 -0
  216. PaIRS_UniNa/icons/paste_below.png +0 -0
  217. PaIRS_UniNa/icons/pause.png +0 -0
  218. PaIRS_UniNa/icons/paused.png +0 -0
  219. PaIRS_UniNa/icons/pencil_bw.png +0 -0
  220. PaIRS_UniNa/icons/piv_proc.png +0 -0
  221. PaIRS_UniNa/icons/piv_proc_off.png +0 -0
  222. PaIRS_UniNa/icons/piv_step.png +0 -0
  223. PaIRS_UniNa/icons/piv_step_off.png +0 -0
  224. PaIRS_UniNa/icons/plane.png +0 -0
  225. PaIRS_UniNa/icons/play.png +0 -0
  226. PaIRS_UniNa/icons/plus.png +0 -0
  227. PaIRS_UniNa/icons/process_logo.png +0 -0
  228. PaIRS_UniNa/icons/process_loop.png +0 -0
  229. PaIRS_UniNa/icons/project.png +0 -0
  230. PaIRS_UniNa/icons/pylog.png +0 -0
  231. PaIRS_UniNa/icons/python_warning.png +0 -0
  232. PaIRS_UniNa/icons/queue.png +0 -0
  233. PaIRS_UniNa/icons/quit.png +0 -0
  234. PaIRS_UniNa/icons/read.png +0 -0
  235. PaIRS_UniNa/icons/read_list.png +0 -0
  236. PaIRS_UniNa/icons/redo.png +0 -0
  237. PaIRS_UniNa/icons/redx.png +0 -0
  238. PaIRS_UniNa/icons/reset.png +0 -0
  239. PaIRS_UniNa/icons/reset_levels.png +0 -0
  240. PaIRS_UniNa/icons/resize_icon.png +0 -0
  241. PaIRS_UniNa/icons/restore.png +0 -0
  242. PaIRS_UniNa/icons/restore_undo.png +0 -0
  243. PaIRS_UniNa/icons/rotate_clock.png +0 -0
  244. PaIRS_UniNa/icons/rotate_counter.png +0 -0
  245. PaIRS_UniNa/icons/rotate_v_clock.png +0 -0
  246. PaIRS_UniNa/icons/rotate_v_counter.png +0 -0
  247. PaIRS_UniNa/icons/running.gif +0 -0
  248. PaIRS_UniNa/icons/running.png +0 -0
  249. PaIRS_UniNa/icons/running_warn.png +0 -0
  250. PaIRS_UniNa/icons/sandglass.png +0 -0
  251. PaIRS_UniNa/icons/save.png +0 -0
  252. PaIRS_UniNa/icons/save_and_stop.png +0 -0
  253. PaIRS_UniNa/icons/save_cfg.png +0 -0
  254. PaIRS_UniNa/icons/saveas.png +0 -0
  255. PaIRS_UniNa/icons/saveas_workspace.png +0 -0
  256. PaIRS_UniNa/icons/scale_all.png +0 -0
  257. PaIRS_UniNa/icons/scale_down.png +0 -0
  258. PaIRS_UniNa/icons/scale_up.png +0 -0
  259. PaIRS_UniNa/icons/scan_list.png +0 -0
  260. PaIRS_UniNa/icons/scan_path.png +0 -0
  261. PaIRS_UniNa/icons/scan_path_loop.png +0 -0
  262. PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
  263. PaIRS_UniNa/icons/search.png +0 -0
  264. PaIRS_UniNa/icons/showIW_off.png +0 -0
  265. PaIRS_UniNa/icons/showIW_on.png +0 -0
  266. PaIRS_UniNa/icons/show_all.png +0 -0
  267. PaIRS_UniNa/icons/sort.png +0 -0
  268. PaIRS_UniNa/icons/sort_reversed.png +0 -0
  269. PaIRS_UniNa/icons/spiv_proc.png +0 -0
  270. PaIRS_UniNa/icons/spiv_proc_off.png +0 -0
  271. PaIRS_UniNa/icons/spiv_setup_no.png +0 -0
  272. PaIRS_UniNa/icons/spiv_setup_ok.png +0 -0
  273. PaIRS_UniNa/icons/star.png +0 -0
  274. PaIRS_UniNa/icons/step_inheritance.png +0 -0
  275. PaIRS_UniNa/icons/subMIN_off.png +0 -0
  276. PaIRS_UniNa/icons/subMIN_on.png +0 -0
  277. PaIRS_UniNa/icons/tom.png +0 -0
  278. PaIRS_UniNa/icons/trash.png +0 -0
  279. PaIRS_UniNa/icons/undo.png +0 -0
  280. PaIRS_UniNa/icons/unedited.png +0 -0
  281. PaIRS_UniNa/icons/unina_dii.png +0 -0
  282. PaIRS_UniNa/icons/uninitialized.png +0 -0
  283. PaIRS_UniNa/icons/unlink.png +0 -0
  284. PaIRS_UniNa/icons/unwrap_items.png +0 -0
  285. PaIRS_UniNa/icons/up.png +0 -0
  286. PaIRS_UniNa/icons/updating_import.gif +0 -0
  287. PaIRS_UniNa/icons/updating_pairs.gif +0 -0
  288. PaIRS_UniNa/icons/vectorColor.png +0 -0
  289. PaIRS_UniNa/icons/vettore.png +0 -0
  290. PaIRS_UniNa/icons/view.png +0 -0
  291. PaIRS_UniNa/icons/view_off.png +0 -0
  292. PaIRS_UniNa/icons/vis_logo.png +0 -0
  293. PaIRS_UniNa/icons/waiting_circle.png +0 -0
  294. PaIRS_UniNa/icons/warning.png +0 -0
  295. PaIRS_UniNa/icons/warning_circle.png +0 -0
  296. PaIRS_UniNa/icons/window.png +0 -0
  297. PaIRS_UniNa/icons/workspace.png +0 -0
  298. PaIRS_UniNa/icons/wrap_items.png +0 -0
  299. PaIRS_UniNa/icons/write_list.png +0 -0
  300. PaIRS_UniNa/listLib.py +303 -0
  301. PaIRS_UniNa/mtfPIV.py +256 -0
  302. PaIRS_UniNa/parForMulti.py +435 -0
  303. PaIRS_UniNa/parForWorkers.py +593 -0
  304. PaIRS_UniNa/pivParFor.py +235 -0
  305. PaIRS_UniNa/plt_util.py +141 -0
  306. PaIRS_UniNa/preProcParFor.py +155 -0
  307. PaIRS_UniNa/procTools.py +1439 -0
  308. PaIRS_UniNa/readcfg.py +52 -0
  309. PaIRS_UniNa/rqrdpckgs.txt +9 -0
  310. PaIRS_UniNa/stereoPivParFor.py +227 -0
  311. PaIRS_UniNa/tAVarie.py +215 -0
  312. PaIRS_UniNa/tabSplitter.py +612 -0
  313. PaIRS_UniNa/ui_Calibration_Tab.py +578 -0
  314. PaIRS_UniNa/ui_Custom_Top.py +296 -0
  315. PaIRS_UniNa/ui_Input_Tab.py +1101 -0
  316. PaIRS_UniNa/ui_Input_Tab_CalVi.py +1283 -0
  317. PaIRS_UniNa/ui_Log_Tab.py +263 -0
  318. PaIRS_UniNa/ui_Output_Tab.py +2362 -0
  319. PaIRS_UniNa/ui_Process_Tab.py +3810 -0
  320. PaIRS_UniNa/ui_Process_Tab_CalVi.py +1549 -0
  321. PaIRS_UniNa/ui_Process_Tab_Disp.py +1141 -0
  322. PaIRS_UniNa/ui_Process_Tab_Min.py +437 -0
  323. PaIRS_UniNa/ui_ResizePopup.py +204 -0
  324. PaIRS_UniNa/ui_Vis_Tab.py +1628 -0
  325. PaIRS_UniNa/ui_Vis_Tab_CalVi.py +1251 -0
  326. PaIRS_UniNa/ui_Whatsnew.py +132 -0
  327. PaIRS_UniNa/ui_gPairs.py +877 -0
  328. PaIRS_UniNa/ui_infoPaIRS.py +551 -0
  329. PaIRS_UniNa/whatsnew.txt +6 -0
  330. pairs_unina-0.2.9.dist-info/METADATA +166 -0
  331. pairs_unina-0.2.9.dist-info/RECORD +333 -0
  332. pairs_unina-0.2.9.dist-info/WHEEL +5 -0
  333. pairs_unina-0.2.9.dist-info/top_level.txt +2 -0
@@ -0,0 +1,1254 @@
1
+
2
+ from .PaIRS_pypacks import *
3
+ from .addwidgets_ps import *
4
+
5
+ Num_Prevs_Max=100
6
+ Num_Prevs_back_forw=10
7
+
8
+ FlagAsyncCallbacks=True
9
+ FlagSimulateError=False
10
+ globExecutor = concurrent.futures.ThreadPoolExecutor(max_workers=10)
11
+
12
+ indParGlob=0
13
+ class TABpar:
14
+ #indParGlob=0
15
+ FlagSettingPar=False
16
+ FlagInit=False
17
+
18
+ def __init__(self,name=str(uuid.uuid4())[:8],surname=str(uuid.uuid4())[:8]):
19
+ self.uiFields=[f for f,_ in self.__dict__.items()]
20
+
21
+ self.name=name
22
+ self.surname=surname
23
+ self.ind=[0,0,0,0,0] #project, tree, item, subitem, do/undo
24
+ self.tip='...'
25
+ self.parentTab=None
26
+ self.FlagNone=False
27
+ self.flagRun=0 #0:not launched yet, 1:completed, -1:interrupted, -2:running
28
+ self.link=[]
29
+
30
+ self.parFields=[f for f,_ in self.__dict__.items() if f not in self.uiFields ]
31
+ self.uncopied_fields=['tip']
32
+ self.unchecked_fields=['name','surname','parentTab']+self.uncopied_fields
33
+
34
+ self.OptionDone=1
35
+ self.warningMessage=''
36
+
37
+ self.fields=[f for f,_ in self.__dict__.items()]
38
+ pass
39
+
40
+ def setNone(self):
41
+ for f in self.fields:
42
+ setattr(self,f,None)
43
+
44
+ def printPar(self,before='',after=''):
45
+ before=after=''
46
+ print(before+str(self.__dict__)+after)
47
+
48
+ def duplicate(self):
49
+ if hasattr(self,'Process') and hasattr(self,'Step'):
50
+ newist=type(self)(Process=self.Process,Step=self.Step)
51
+ else:
52
+ newist=type(self)()
53
+ for f in self.fields:
54
+ if f in self.uncopied_fields: continue
55
+ a=getattr(self,f)
56
+ if hasattr(a,'duplicate'): #type(a)==patternInfoList:
57
+ setattr(newist,f,a.duplicate())
58
+ else:
59
+ setattr(newist,f,copy.deepcopy(a))
60
+ return newist
61
+
62
+ def copyfromdiz(self,diz:dict):
63
+ for f,a in diz.items():
64
+ if hasattr(a,'duplicate'):
65
+ if hasattr(a,'isDifferentFrom') and hasattr(self,f):
66
+ b=getattr(self,f)
67
+ flag=a.isDifferentFrom(b,FlagPrint=False)
68
+ else: flag=True
69
+ if flag: setattr(self,f,a.duplicate())
70
+ else:
71
+ setattr(self,f,copy.deepcopy(a))
72
+
73
+ def copyfrom(self,newist,exceptions=None):
74
+ if newist is None:
75
+ self.FlagNone=True
76
+ else:
77
+ self.copyfromfields(newist,self.fields,exceptions)
78
+
79
+ def copyfromfields(self,newist,fields=None,exceptions=None):
80
+ """
81
+ exceptions=[] --> no exceptions
82
+ """
83
+ newist:TABpar
84
+ if exceptions is None:
85
+ exceptions=self.uncopied_fields
86
+ for f in fields:
87
+ if f in exceptions: continue
88
+ if not hasattr(self,f):
89
+ pri.Error.red(f'copyfromdiz: field <{f}> is missing in {self.name} par structure!')
90
+ continue
91
+ if not hasattr(newist,f):
92
+ pri.Error.red(f'copyfromdiz: field <{f}> is missing in {newist.name} par structure!')
93
+ continue
94
+ a=getattr(newist,f)
95
+ if hasattr(a,'duplicate'): #type(a)==patternInfoList:
96
+ if hasattr(a,'isDifferentFrom') and hasattr(self,f):
97
+ b=getattr(self,f)
98
+ flag=a.isDifferentFrom(b,FlagPrint=False)
99
+ else: flag=True
100
+ if flag: setattr(self,f,a.duplicate())
101
+ else:
102
+ setattr(self,f,copy.deepcopy(a))
103
+
104
+ def isDifferentFrom(self,v,exceptions:list=[],fields:list=[],FlagStrictDiff=False,FlagPrint=True):
105
+ if not FlagStrictDiff:
106
+ exceptions+=self.unchecked_fields
107
+ exceptions=list(set(exceptions))
108
+ if not fields:
109
+ fields=self.fields
110
+ else:
111
+ [exceptions.remove(f) for f in fields if f in exceptions]
112
+
113
+ Flag=False
114
+ for f in fields:
115
+ if f in exceptions: continue
116
+ else:
117
+ if not hasattr(self,f):
118
+ pri.Error.red(f'isDifferentFrom: field <{f}> is missing in {self.name} par structure!')
119
+ continue
120
+ if not hasattr(v,f):
121
+ pri.Error.red(f'isDifferentFrom: field <{f}> is missing in {v.name} par structure!')
122
+ continue
123
+ a=getattr(self,f)
124
+ b=getattr(v,f)
125
+ if f=='Vect':
126
+ Flag=not all([np.array_equal(a[i],b[i]) for i in range(4)])
127
+ if Flag:
128
+ break
129
+ else:
130
+ if hasattr(a,'isDifferentFrom'): #in ('Pinfo','pinfo'):
131
+ Flag=a.isDifferentFrom(b,exceptions,FlagStrictDiff=FlagStrictDiff)
132
+ if Flag: break
133
+ else:
134
+ if a!=b:
135
+ Flag=True
136
+ break
137
+ if FlagPrint:
138
+ if Flag:
139
+ pri.TABparDiff.red(f'{self.name} is different in {f}:\t {b} --> {a}')
140
+ else:
141
+ pri.TABparDiff.green(f'{self.name} is unchanged')
142
+ return Flag
143
+
144
+ def isEqualTo(self,v,exceptions=[],fields=[],FlagStrictDiff=False,FlagPrint=False):
145
+ Flag=bool(not self.isDifferentFrom(v,exceptions,fields,FlagStrictDiff,FlagPrint))
146
+ return Flag
147
+
148
+ def printDifferences(self,v,exceptions=[],fields=[],FlagStrictDiff=False):
149
+ if FlagStrictDiff: exceptions+=self.unchecked_fields
150
+ if not fields:
151
+ fields=self.fields
152
+ else:
153
+ [exceptions.remove(f) for f in fields if f in exceptions]
154
+ printing=''
155
+ df=[]
156
+ for f in fields:
157
+ if f in exceptions: continue
158
+ if not hasattr(self,f):
159
+ pri.Error.red(f'printDifferences: field <{f}> is missing in {self.name} par structure!')
160
+ continue
161
+ if not hasattr(v,f):
162
+ pri.Error.red(f'printDifferences: field <{f}> is missing in {v.name} par structure!')
163
+ continue
164
+ a=getattr(self,f)
165
+ b=getattr(v,f)
166
+ Flag=False
167
+ if f=='Vect':
168
+ Flag=not all([np.array_equal(a[i],b[i]) for i in range(4)])
169
+ else:
170
+ if hasattr(a,'isDifferentFrom'): #in ('Pinfo','pinfo'):
171
+ if hasattr(a,'fields'):
172
+ Flag=a.isDifferentFrom(b,[],a.fields,FlagStrictDiff,FlagPrint=False)
173
+ if Flag:
174
+ a.printDifferences(b,[],a.fields,FlagStrictDiff)
175
+ else:
176
+ Flag=a.isDifferentFrom(b,[],FlagPrint=False)
177
+ else:
178
+ if a!=b: Flag=True
179
+ if Flag:
180
+ df.append(f)
181
+ if not printing: printing=f'{self.name} differences in:'
182
+ printing=printing+f'\n*\t{f}:\t {str(a)[:100]} --> {str(b)[:100]}'
183
+ if not printing: printing=f'{self.name} no differences!'
184
+ pri.Info.magenta(printing)
185
+ return df
186
+
187
+ def hasIndexOf(self,d):
188
+ """ check if the indexes are the same """
189
+ return self.ind==d.ind
190
+
191
+ class gPaIRS_Tab(QWidget):
192
+ indGlob=(0,0,0,0)
193
+ FlagGlob=False
194
+
195
+ class Tab_Signals(QObject):
196
+ callback2_end=Signal(str,bool,bool)
197
+
198
+ def __init__(self, parent):
199
+ super().__init__(parent)
200
+ self.callback2_end.connect(parent.callback2_end)
201
+
202
+ def __init__(self,parent=None,UiClass=None,ParClass=TABpar):
203
+ super().__init__()
204
+ from .gPaIRS import gPaIRS
205
+ if parent is None:
206
+ self.gui=self.window()
207
+ else:
208
+ if hasattr(parent,'gui'):
209
+ self.gui:gPaIRS=parent.gui
210
+ else:
211
+ self.gui:gPaIRS=parent.window()
212
+
213
+ self.TABname='Tab'
214
+ self.signals=self.Tab_Signals(self)
215
+ self.father=parent
216
+
217
+ self.ParClass=ParClass
218
+ self.TABpar=self.ParClass() #current configuration
219
+ self.TABpar_old=self.ParClass() #last configuration in the current tab
220
+ self.TABpar_prev=[]
221
+ self.gen_TABpar(self.TABpar.ind,FlagEmptyPrev=True) #queue of previous configurations, alias undos/redos (indTree,indItem,ind)
222
+ self.Num_Prevs_Max=Num_Prevs_Max
223
+
224
+ self.FlagAddPrev=True #if False, no further par are added to the queue of undos/redos "prev"
225
+ self.FlagBridge=True #if False, no bridge is executed during setting of parameters
226
+ self.FlagPrevPropagation=False
227
+
228
+ #self.setTABpar_prev=lambda itree,iitem,i,flagBridge: None
229
+ self.TABsettings=[]
230
+
231
+ self.FlagSettingPar=False
232
+ self.FlagAsyncCallEvaluation=False
233
+ self.disableTab=lambda flag: None
234
+
235
+ self.adjustTABpar=lambda: None
236
+ self.setTABlayout=lambda: None
237
+ self.checkTABpar=lambda ind: None
238
+ self.setTABwarn=lambda ind: None
239
+ self.setTABpar_bridge=lambda fLagAdjustPar, flagCallback: None
240
+ self.add_TABpar_bridge=lambda tip, ind: None
241
+
242
+ self.buttonTab=None
243
+
244
+ #Controls
245
+ if UiClass!=None:
246
+ self.ui=UiClass()
247
+ if not hasattr(self,'ui'):
248
+ self.ui=self
249
+ if hasattr(self.ui,'setupUi'):
250
+ self.ui.setupUi(self)
251
+ if hasattr(self.ui,'name_tab'):
252
+ self.name_tab=self.ui.name_tab.text().replace(' ','')
253
+ else:
254
+ self.name_tab=''
255
+
256
+
257
+ #------------------------------------- Graphical interface: miscellanea
258
+ self.pixmap_warnc = QPixmap(u""+ icons_path +"warning_circle.png")
259
+ self.pixmap_done = QPixmap(u""+ icons_path +"completed.png")
260
+
261
+ self.undo_icon=QIcon()
262
+ self.undo_icon.addFile(u""+ icons_path +"undo.png", QSize(), QIcon.Normal, QIcon.Off)
263
+ self.redo_icon=QIcon()
264
+ self.redo_icon.addFile(u""+ icons_path +"redo.png", QSize(), QIcon.Normal, QIcon.Off)
265
+ if not hasattr(self.ui,'button_back'):
266
+ setattr(self.ui,'button_back',QPushButton(self))
267
+ else:
268
+ self.ui.button_back.contextMenuEvent=lambda e: self.bfContextMenu(-1,e)
269
+ if not hasattr(self.ui,'button_forward'):
270
+ setattr(self.ui,'button_forward',QPushButton(self))
271
+ else:
272
+ self.ui.button_forward.contextMenuEvent=lambda e: self.bfContextMenu(+1,e)
273
+ if not hasattr(self.ui,'button_restore_undo'):
274
+ setattr(self.ui,'button_restore_undo',QPushButton(self))
275
+ if not hasattr(self.ui,'label_number'):
276
+ setattr(self.ui,'label_number',QLabel(self))
277
+ if hasattr(self.ui,'button_close_tab'):
278
+ b:QPushButton=self.ui.button_close_tab
279
+ b.setCursor(Qt.CursorShape.PointingHandCursor)
280
+ self.onlyReadLabel:QLabel=None
281
+ self.button_reset_step:QPushButton=None
282
+ self.button_step_inherit:QPushButton=None
283
+ self.button_copy_step:QPushButton=None
284
+ self.button_link_step:QPushButton=None
285
+
286
+ self.FlagDisplayControls=True #if False, undo and redo buttons are hidden and so not usable
287
+ self.ui.button_forward.hide()
288
+ self.ui.button_back.hide()
289
+ self.ui.button_restore_undo.hide()
290
+ self.ui.button_back.clicked.connect(self.button_back_action)
291
+ self.ui.button_forward.clicked.connect(self.button_forward_action)
292
+ self.ui.label_number.setText('')
293
+ self.ui.label_number.hide()
294
+
295
+ if hasattr(self.ui,'spin_x'):
296
+ self.ui.spin_x.valueChanged.connect(self.spin_x_changing)
297
+ if hasattr(self.ui,'spin_y'):
298
+ self.ui.spin_y.valueChanged.connect(self.spin_y_changing)
299
+
300
+ self.spins_valueChanged=[]
301
+
302
+ self.nullCallback=lambda f='Null Callback': self.wrappedCallback(f,lambda: True)()
303
+ self.fullCallback=lambda f='Full Callback': self.wrappedCallback(f,lambda: None)()
304
+
305
+ #*************************************************** Widgets
306
+ def defineWidgets(self):
307
+ def wDict(types,signals):
308
+ l=[]
309
+ for t in types:
310
+ for c in self.findChildren(t): l.append(c) if c not in l else None
311
+ d={'widgets': l, 'signals': signals}
312
+ return d
313
+
314
+ widgets={
315
+ 'spin': wDict([MyQSpin,MyQDoubleSpin],['addfuncout','addfuncreturn']),
316
+ 'check': wDict([QCheckBox],['toggled']),
317
+ 'radio': wDict([QRadioButton],['toggled']),
318
+ 'line_edit': wDict([QLineEdit,MyQLineEdit,MyQLineEditNumber],['addfuncout','returnPressed']),
319
+ 'button' : wDict([QPushButton,QToolButton,MyToolButton],['clicked']),
320
+ 'combo' : wDict([QComboBox],['activated']),
321
+ }
322
+ self.widgetTypes=list(widgets)
323
+ self.widgets=[]
324
+ self.widgetSignals=[]
325
+ for w in self.widgetTypes:
326
+ self.widgets.append(widgets[w]['widgets'])
327
+ self.widgetSignals.append(widgets[w]['signals'])
328
+ self.widgetsOfType=lambda t: self.widgets[self.widgetTypes.index(t)]
329
+
330
+ for c in self.widgetsOfType('combo'):
331
+ c:QComboBox
332
+ nameCombo=c.objectName().split('combo_')[-1]
333
+ if hasattr(self,nameCombo+'_items'):
334
+ itemsCombo=getattr(self,nameCombo+'_items')
335
+ else: continue
336
+ if hasattr(self,nameCombo+'_order'):
337
+ orderCombo=getattr(self,nameCombo+'_order')
338
+ else: orderCombo=[i for i in range(len(itemsCombo))]
339
+ c.clear()
340
+ for i in orderCombo:
341
+ c.addItem(itemsCombo[i])
342
+
343
+ #*************************************************** Widget callbacks
344
+ def defaultCallback(self,wName,wtype):
345
+ widget=getattr(self.ui,wtype+'_'+wName)
346
+ if wName=='x_min':
347
+ pass
348
+ if wtype=='spin':
349
+ def callbackSpin(s:MyQSpin):
350
+ setattr(self.TABpar,wName,s.value())
351
+ default_callback=lambda: callbackSpin(widget)
352
+ elif (wtype=='check' or wtype=='radio') and hasattr(self.TABpar,'Flag'+wName):
353
+ def callbackCheck(c:QCheckBox):
354
+ setattr(self.TABpar,'Flag'+wName,c.isChecked())
355
+ default_callback=lambda: callbackCheck(widget)
356
+ elif wtype=='combo':
357
+ def callbackCombo(c:QComboBox):
358
+ if hasattr(self,wName+'_items'):
359
+ itemsCombo:list=getattr(self,wName+'_items')
360
+ else:
361
+ itemsCombo=[c.itemText(i) for i in range(c.count())]
362
+ if len(itemsCombo):
363
+ setattr(self.TABpar,wName,itemsCombo.index(c.currentText()))
364
+ else:
365
+ setattr(self.TABpar,wName,-1)
366
+ default_callback=lambda: callbackCombo(widget)
367
+ elif wtype=='line_edit':
368
+ def callbackLineEdit(l:MyQLineEdit):
369
+ setattr(self.TABpar,wName,l.text())
370
+ default_callback=lambda: callbackLineEdit(widget)
371
+ else:
372
+ default_callback=None
373
+ return default_callback
374
+
375
+ def defineCallbacks(self):
376
+ def buildCallback(wName,wtype,tip):
377
+ if not hasattr(self.ui,wtype+'_'+wName): return
378
+ callback01=callback02=callback03=callback1=callback2=None
379
+
380
+ #callback01: _preaction method in the class: particular callback that is fast and can be executed on the main thread instead of as concurrent future before the default callback
381
+ a=wtype+'_'+wName+'_preaction'
382
+ if hasattr(self,a): callback01=getattr(self,a)
383
+
384
+ #callback02: callback common to all widgets of the same type (avoid code repetition)
385
+ if hasattr(self.TABpar,wName) or ((wtype=='check' or wtype=='radio') and hasattr(self.TABpar,'Flag'+wName)):
386
+ callback02=self.defaultCallback(wName,wtype)
387
+
388
+ #callback03: _action method in the class: particular callback that is fast and can be executed on the main thread instead of as concurrent future after the default callback
389
+ a=wtype+'_'+wName+'_action'
390
+ if hasattr(self,a): callback03=getattr(self,a)
391
+
392
+ if callback01 or callback02 or callback03:
393
+ def callback1():
394
+ name=wName
395
+ flag=None
396
+ if callback01: callback01()
397
+ if callback02: callback02()
398
+ if callback03: flag=callback03()
399
+ return flag
400
+ else: callback1=None
401
+
402
+ #callback1: _action_future method in the class: particular callback that is fast and can be executed on the main thread instead of as concurrent future
403
+ a=wtype+'_'+wName+'_action_future'
404
+ if hasattr(self,a):
405
+ callback2=getattr(self,a)
406
+
407
+ if callback1 or callback2:
408
+ callback=self.wrappedCallback(tip,callback1,callback2)
409
+ setattr(self,wtype+'_'+wName+'_callback',callback)
410
+ else:
411
+ callback=None
412
+ return callback
413
+
414
+ self.widgetCallbacks=[]
415
+ for l,wtype in zip(self.widgets,self.widgetTypes):
416
+ missing_tips=[]
417
+ if hasattr(self,wtype+'_tips'):
418
+ d=getattr(self,wtype+'_tips')
419
+ else:
420
+ d=None
421
+ pri.Coding.red(f'*** [{self.TABname}] - {wtype}_tips - missing dictionary!')
422
+ widgetCallbacks=[]
423
+ for c in l:
424
+ c:QObject
425
+ if c.objectName() in ('button_back','button_forward','button_close_tab'):
426
+ callback=None
427
+ widgetCallbacks.append(callback)
428
+ continue
429
+ if '_' in c.objectName(): wName=c.objectName().split(wtype+'_')[-1]
430
+ else: wName=c.objectName()
431
+ if d!=None:
432
+ if wName in list(d): tip=d[wName]
433
+ else:
434
+ tip=f"{wtype} {wName}"
435
+ if wName and not (wtype=='line_edit' and wName in ('qt_spinbox_lineedit') ) and \
436
+ not (wtype=='button' and wName in ('back','forward','close_tab') ):
437
+ missing_tips.append(f"'{wName}'")
438
+ else: tip=f"{wtype} {wName}"
439
+ callback=buildCallback(wName,wtype,tip)
440
+ widgetCallbacks.append(callback)
441
+ if len(missing_tips):
442
+ pri.Coding.blue(f'*** [{self.TABname}] - {wtype}_tips - missing tips:\n\t'+"\n\t".join(missing_tips))
443
+ elif d:
444
+ pri.Coding.green(f'✔️ [{self.TABname}] - {wtype}_tips - complete dictionary!')
445
+ self.widgetCallbacks.append(widgetCallbacks)
446
+
447
+ def wrappedCallback(self,tip='',callback1=None,callback2=None):
448
+ def debugFun(fun,message=''):
449
+ try:
450
+ out=fun()
451
+ except Exception as inst:
452
+ out=None
453
+ pri.Error.red(f"{'!'*100}\n{message}:\n{traceback.format_exc()}\n{'!'*100}")
454
+ printException()
455
+ #if Flag_DEBUG: raise Exception("!!! Debug stop !!!")
456
+ return out
457
+ async def callback2_async(fun2):
458
+ if Flag_DEBUG: timesleep(time_callback2_async)
459
+ if fun2: debugFun(fun2,f'Asyncronus function error callback2 ({tip}): ')
460
+ return
461
+ def callback():
462
+ FlagSettingPar=self.FlagSettingPar or TABpar.FlagSettingPar
463
+ if FlagSettingPar:
464
+ return
465
+ else:
466
+ self.FlagSettingPar=True
467
+ try:
468
+ FlagPreventAddPrev=False
469
+ if callback1: FlagPreventAddPrev=debugFun(callback1,f'Error callback1 ({tip}): ')
470
+ if callback2:
471
+ self.FlagAsyncCallEvaluation=True
472
+ self.disableTab(True)
473
+
474
+ if FlagAsyncCallbacks:
475
+ f3=globExecutor.submit(asyncio.run,callback2_async(callback2))
476
+ def f3callback(_f3):
477
+ self.signals.callback2_end.emit(tip,FlagSettingPar,FlagPreventAddPrev)
478
+ f3.add_done_callback(f3callback)
479
+ else:
480
+ debugFun(callback2,f'Error callback2 ({tip}): ')
481
+ self.callback2_end(tip,FlagSettingPar,FlagPreventAddPrev)
482
+ else:
483
+ self.callback2_end(tip,FlagSettingPar,FlagPreventAddPrev)
484
+ except Exception as inst:
485
+ pri.Error.red(f"Error in wrapped callback ({tip}):\n{traceback.format_exc()}")
486
+ printException()
487
+ self.FlagSettingPar=FlagSettingPar
488
+ return
489
+ return callback
490
+
491
+ @Slot(str)
492
+ def callback2_end(self,tip,FlagSettingPar,FlagPreventAddPrev):
493
+ pri.Coding.green(f'{"*"*50}\nCallback <{self.TABname}>: {tip}')
494
+ if tip=='Null Callback':
495
+ pass
496
+ try:
497
+ if self.FlagAsyncCallEvaluation==True:
498
+ self.FlagAsyncCallEvaluation=False
499
+ self.disableTab(False)
500
+ try:
501
+ TABpar_ind=self.TABpar_at(self.TABpar.ind)
502
+ if TABpar_ind and self.TABpar.isEqualTo(TABpar_ind,FlagStrictDiff=True): return
503
+ FlagNewPar=self.isNewPar()
504
+ flagRun=self.TABpar_at(self.TABpar.ind).flagRun
505
+ if FlagNewPar and (flagRun!=0 or len(self.TABpar.link)>0):
506
+ #FlagNewPar=not self.FlagAddPrev
507
+ if len(self.TABpar.link)>0:
508
+ ITE0_master=self.gui.ui.Explorer.ITEsfromInd(self.TABpar.link)[0]
509
+ linkInfo=f'{ITE0_master.ind[2]+1}: {ITE0_master.name}'
510
+ Messagge=f'This process step is linked to process {linkInfo}. To modify it, you need to unlink the process step.'
511
+ if flagRun!=0 or ITE0_master.flagRun!=0:
512
+ Messagge+=' After unlinking the process will be reset!'
513
+ def unlink_pars_online():
514
+ TABpar_ind.copyfrom(self.TABpar)
515
+ self.gui.unlink_pars(self.TABpar.ind)
516
+ if self.TABpar.flagRun!=0 or ITE0_master.flagRun!=0:
517
+ self.gui.reset_step(self.TABpar.ind)
518
+ warningDialog(self.gui,Messagge,addButton={'Unlink step!': unlink_pars_online})
519
+ elif flagRun==-10:
520
+ Messagge='This process step is in the queue for process execution. To modify it, you need to stop processing and then reset it and all the subsequent steps.'
521
+ warningDialog(self.gui,Messagge)
522
+ elif flagRun==-2:
523
+ Messagge='This process step is currently in execution. To modify it, you need to stop processing and then reset it and all the subsequent steps.'
524
+ warningDialog(self.gui,Messagge)
525
+ elif flagRun!=0:
526
+ if self.gui.FlagRun:
527
+ Messagge='This process step has already been executed. To modify it, you need to stop processing and then reset it and all the subsequent steps.'
528
+ warningDialog(self.gui,Messagge)
529
+ else:
530
+ Messagge='This process step has already been executed. To modify it, you need to reset the current step and all the subsequent ones.'
531
+ def reset_step_online():
532
+ TABpar_ind.copyfrom(self.TABpar)
533
+ self.gui.reset_step(self.TABpar.ind)
534
+ return
535
+ warningDialog(self.gui,Messagge,addButton={'Reset step!': reset_step_online})
536
+
537
+
538
+ if flagRun!=0 or len(self.TABpar.link)>0:
539
+ self.TABpar.copyfrom(TABpar_ind)
540
+ originalStyleSheet=self.gui.styleSheet()
541
+ self.gui.setStyleSheet(f'background: {self.palette().color(QPalette.ColorRole.Text).name()} ;') #dcdcdc
542
+ self.repaint()
543
+ try:
544
+ self.setTABpar(FlagAdjustPar=False,FlagBridge=False,FlagCallback=False)
545
+ finally:
546
+ timesleep(.01)
547
+ self.gui.setStyleSheet(originalStyleSheet)
548
+ else:
549
+ return
550
+ else:
551
+ self.setTABpar(FlagAdjustPar=True,FlagBridge=self.FlagBridge,FlagCallback=True)
552
+ except:
553
+ pri.Error.red(f'Error in callback2_end ({tip}):\n |-> Error in setting the parameters')
554
+ pri.Error.red(f'{traceback.format_exc()}')
555
+ printException()
556
+ else:
557
+ try:
558
+ FlagNewPar=FlagNewPar and not FlagPreventAddPrev and self.TABpar.flagRun==0 and len(self.TABpar.link)==0
559
+ self.add_TABpar(tip,FlagNewPar)
560
+ except:
561
+ pri.Error.red(f'Error in callback2_end ({tip}):\n |-> Error in adding parameters to redos/undos {tip}')
562
+ printException()
563
+ except Exception as inst:
564
+ pri.Error.red(f"Error in callback2_end ({tip}):\n{traceback.format_exc()}")
565
+ printException()
566
+ finally:
567
+ self.FlagSettingPar=FlagSettingPar
568
+ pri.Coding.green(f'Callback <{self.TABname}>: {tip}\n{"*"*50}\n')
569
+
570
+ def connectCallbacks(self):
571
+ for W,S,CB in zip(self.widgets,self.widgetSignals,self.widgetCallbacks):
572
+ for w,cb in zip(W,CB):
573
+ if cb==None: continue
574
+ for s in S:
575
+ sig=getattr(w,s)
576
+ if hasattr(sig,'connect'):
577
+ sig.connect(cb)
578
+ elif s in ('addfuncout','addfuncreturn'):
579
+ if w in self.spins_valueChanged:
580
+ if s=='addfuncout': w.valueChanged.connect(cb)
581
+ else:
582
+ sig['callback']=cb
583
+
584
+ #*************************************************** Setting parameters to widgets
585
+ def defaultSetting(self,wName,wtype):
586
+ if not hasattr(self.ui,wtype+'_'+wName): return
587
+ widget=getattr(self.ui,wtype+'_'+wName)
588
+ if wtype=='spin':
589
+ def settingSpinValue(s:MyQSpin):
590
+ s.setValue(getattr(self.TABpar,wName))
591
+ default_setting=lambda: settingSpinValue(widget)
592
+ elif (wtype=='check' or wtype=='radio') and hasattr(self.TABpar,'Flag'+wName):
593
+ def settingChecked(c:QCheckBox):
594
+ try:
595
+ c.setChecked(getattr(self.TABpar,'Flag'+wName))
596
+ except:
597
+ pass
598
+ default_setting=lambda: settingChecked(widget)
599
+ elif wtype=='combo':
600
+ widget:QComboBox
601
+ def settingComboIndex(c:QComboBox):
602
+ items=[c.itemText(i) for i in range(c.count())]
603
+ if hasattr(self,wName+'_items'):
604
+ itemsCombo:list=getattr(self,wName+'_items')
605
+ else:
606
+ itemsCombo=items
607
+ ind=getattr(self.TABpar,wName)
608
+ if ind>-1: c.setCurrentIndex(items.index(itemsCombo[ind]))
609
+ default_setting=lambda: settingComboIndex(widget)
610
+ elif wtype=='line_edit':
611
+ def settingText(l:MyQLineEdit):
612
+ l.setText(getattr(self.TABpar,wName))
613
+ default_setting=lambda: settingText(widget)
614
+ else:
615
+ default_setting=None
616
+ return default_setting
617
+
618
+ def defineSettings(self):
619
+ def buildSetting(wName,wtype):
620
+ setting0=default_setting=setting2=None
621
+ #setting0: _preset method in the class: setting to be done before standard setting (0)
622
+ a=wtype+'_'+wName+'_preset'
623
+ if hasattr(self,a): setting0=getattr(self,a)
624
+
625
+ #setting1: setting common to all widgets of the same type (avoid code repetition)
626
+ if hasattr(self.TABpar,wName) or ((wtype=='check' or wtype=='radio') and hasattr(self.TABpar,'Flag'+wName)):
627
+ default_setting=self.defaultSetting(wName,wtype)
628
+
629
+ #callback2: _set method in the class: setting to be done before standard setting (1)
630
+ a=wtype+'_'+wName+'_set'
631
+ if hasattr(self,a): setting2=getattr(self,a)
632
+
633
+ def setting():
634
+ name=wName
635
+ if setting0: setting0()
636
+ if default_setting: default_setting()
637
+ if setting2: setting2()
638
+ return
639
+ setattr(self,wtype+'_'+wName+'_setting',setting)
640
+ self.TABsettings.append(setting)
641
+ return
642
+
643
+ self.TABsettings=[]
644
+ for l,wtype in zip(self.widgets,self.widgetTypes):
645
+ for c in l:
646
+ wName=c.objectName().split(wtype+'_')[-1]
647
+ buildSetting(wName,wtype)
648
+ if wtype=='line_edit':
649
+ if hasattr(c,'addfuncout'):
650
+ c.addfuncout['setting']=self.TABsettings[-1]
651
+ else:
652
+ def focusOutEvent(obj, event):
653
+ type(obj).focusOutEvent(obj,event) #to preserve classical behaviour before adding the below
654
+ self.TABsettings[-1]()
655
+ c.focusOutEvent=focusOutEvent
656
+
657
+ def setTABpar(self,FlagAdjustPar=True,FlagBridge=True,FlagCallback=False,FlagDisplayControls=None):
658
+ if self.TABpar.FlagNone and self.TABpar_at(self.TABpar.ind) is None: return
659
+ pri.Coding.magenta(f' --- setting {self.TABpar.name} {self.TABpar.ind}')
660
+
661
+ self.FlagSettingPar=True
662
+ FlagSettingPar=TABpar.FlagSettingPar
663
+ TABpar.FlagSettingPar=True
664
+
665
+ if FlagAdjustPar:
666
+ self.adjustTABpar()
667
+
668
+ self.setTABlayout()
669
+ for f in self.TABsettings:
670
+ f()
671
+ #self.TABpar_old.copyfrom(self.TABpar)
672
+ self.TABpar.FlagInit=True
673
+
674
+ if FlagBridge:
675
+ self.setTABpar_bridge(FlagAdjustPar,FlagCallback)
676
+
677
+ self.TABpar_old.copyfrom(self.TABpar)
678
+
679
+ if FlagDisplayControls is None: FlagDisplayControls=not FlagBridge
680
+ if FlagDisplayControls:
681
+ self.display_controls()
682
+
683
+ TABpar.FlagSettingPar=FlagSettingPar
684
+ self.FlagSettingPar=False
685
+
686
+ if not FlagCallback:
687
+ self.adjustTABparInd()
688
+
689
+ def setTABpar_at(self,ind,FlagAdjustPar=False,FlagBridge=False):
690
+ pri.Coding.green(f'{":"*50}\nSetting previous par <{self.TABname}>: {ind}')
691
+ TABpar_ind:TABpar=self.TABpar_at(ind)
692
+ if not TABpar_ind.FlagNone:
693
+ self.TABpar.copyfrom(TABpar_ind)
694
+ self.setTABpar(FlagAdjustPar,FlagBridge)
695
+ pri.Coding.green(f'Setting previous par <{self.TABname}>: {ind}\n{":"*50}\n')
696
+
697
+ def setupWid(self):
698
+ setupWid(self)
699
+ fPixSize_TabNames=30
700
+ qlabels=self.findChildren(QLabel)
701
+ labs=[l for l in qlabels if 'name_tab' in l.objectName()]
702
+ for lab in labs:
703
+ lab:QLabel #=self.ui.name_tab
704
+ font=lab.font()
705
+ font.setPixelSize(fPixSize_TabNames)
706
+ lab.setFont(font)
707
+
708
+ def setTABWarnLabel(self):
709
+ self.ui.name_tab.setFixedWidth(self.ui.name_tab.sizeHint().width())
710
+ self.ui.label_done.setPixmap(self.pixmap_done if self.TABpar.OptionDone==1 else self.pixmap_warnc)
711
+ self.ui.label_done.setToolTip(self.TABpar.warningMessage)
712
+
713
+ #*************************************************** Undo/redo
714
+ def adjustTABparInd(self):
715
+ TABpar_ind=self.TABpar_at(self.TABpar.ind)
716
+ if TABpar_ind:
717
+ TABpar_ind.copyfrom(self.TABpar)
718
+
719
+ def gen_TABpar(self,ind,FlagSet=True,FlagEmptyPrev=False,FlagNone=False,FlagInsert=-1,Process=None,Step=None):
720
+ Prev=prev=self.TABpar_prev if FlagSet else []
721
+
722
+ for i in range(len(ind)):
723
+ if i<len(ind)-1:
724
+ if i==FlagInsert:
725
+ prev.insert(ind[i],[])
726
+ else:
727
+ while ind[i]>len(prev)-1:
728
+ prev.append([])
729
+ prev=prev[ind[i]]
730
+ else:
731
+ if not FlagEmptyPrev:
732
+ if i==FlagInsert:
733
+ if ind[i]<len(prev):
734
+ if FlagNone:
735
+ prev[ind[i]]=None
736
+ else:
737
+ if Process is not None and Step is not None:
738
+ par=self.ParClass(Process=Process,Step=Step)
739
+ else:
740
+ par=self.ParClass()
741
+ par.ind=ind
742
+ prev[ind[i]]=par
743
+ pri.Coding.cyan(f'[gen_TABpar] {par.surname} {par.ind} ---> {self.TABpar_at(ind).ind}')
744
+ else:
745
+ if FlagNone:
746
+ prev.insert(ind[i],None)
747
+ else:
748
+ if Process is not None and Step is not None:
749
+ par=self.ParClass(Process=Process,Step=Step)
750
+ else:
751
+ par=self.ParClass()
752
+ par.ind=ind
753
+ prev.insert(ind[i],par)
754
+ pri.Coding.cyan(f'[gen_TABpar] {par.surname} {par.ind} ---> {self.TABpar_at(ind).ind}')
755
+ else:
756
+ while ind[i]>len(prev)-1:
757
+ if FlagNone:
758
+ prev.append(None)
759
+ else:
760
+ if Process is not None and Step is not None:
761
+ par=self.ParClass(Process=Process,Step=Step)
762
+ else:
763
+ par=self.ParClass()
764
+ par.ind=ind
765
+ prev.append(par)
766
+ pri.Coding.cyan(f'[gen_TABpar] {par.surname} {par.ind} ---> {self.TABpar_at(ind).ind}')
767
+ return Prev
768
+
769
+ def TABpar_at(self,ind):
770
+ if ind[0]<len(self.TABpar_prev):
771
+ p:TABpar=self.TABpar_prev[ind[0]]
772
+ else:
773
+ p=None
774
+ if p:
775
+ for i in range(1,len(ind)):
776
+ if ind[i]<len(p):
777
+ p=p[ind[i]]
778
+ else:
779
+ p=None
780
+ break
781
+ return p
782
+
783
+ def TABpar_prev_at(self,ind):
784
+ if len(self.TABpar_prev)-1<ind[0]:
785
+ return []
786
+ else:
787
+ p:TABpar=self.TABpar_prev[ind[0]]
788
+ for i in range(1,len(ind)-1):
789
+ if len(p)-1<ind[i]:
790
+ p=[]
791
+ break
792
+ else:
793
+ p=p[ind[i]]
794
+ return p
795
+
796
+ def isNewPar(self):
797
+ ind=self.TABpar.ind
798
+ TABpar_prev=self.TABpar_prev_at(ind)
799
+ if len(TABpar_prev)>0:
800
+ FlagNewPar=self.FlagAddPrev and self.TABpar.isDifferentFrom(TABpar_prev[-1],exceptions=self.TABpar.unchecked_fields+['ind']) #see below
801
+ self.TABpar.printDifferences(TABpar_prev[-1],exceptions=self.TABpar.unchecked_fields+['ind'])
802
+ else:
803
+ FlagNewPar=self.FlagAddPrev
804
+ return FlagNewPar
805
+
806
+ def add_TABpar(self,tip,FlagNewPar=True):
807
+ ind=self.TABpar.ind
808
+ TABpar_prev=self.TABpar_prev_at(ind)
809
+ if (FlagNewPar or len(TABpar_prev)==0) and self.FlagAddPrev: #something changed
810
+ if len(TABpar_prev): TABpar_prev[-1].printDifferences(self.TABpar,self.TABpar.unchecked_fields+['ind'])
811
+ self.add_TABpar_copy(tip,ind)
812
+ self.add_TABpar_bridge(tip,ind) #should create a copy of the other tabs' parameters (see gPaIRS)
813
+ ind[-1]=TABpar_prev[-1].ind[-1]
814
+ else:
815
+ self.adjustTABparInd()
816
+
817
+ if self.FlagPrevPropagation:
818
+ #pri.Time.blue('Propagation par init')
819
+ TABpar_prev=self.TABpar_prev_at(self.TABpar.ind)
820
+ for p in TABpar_prev:
821
+ p:TABpar
822
+ p.copyfrom(TABpar_prev[self.TABpar.ind[-1]],exceptions=['ind','tip'])
823
+ #pri.Time.blue('Propagation par end')
824
+ return ind
825
+
826
+ def add_TABpar_copy(self,name,ind):
827
+ TABpar_prev:list=self.TABpar_prev_at(ind)
828
+ if not self.TABpar.FlagNone:
829
+ TABpar_new=self.TABpar.duplicate()
830
+ if len(TABpar_prev)>self.Num_Prevs_Max:
831
+ TABpar_prev.pop(0)
832
+ for k,p in enumerate(TABpar_prev):
833
+ p.ind[-1]=k
834
+ else:
835
+ TABpar_new.ind[-1]=len(TABpar_prev)
836
+ TABpar_new.tip=name
837
+ self.TABpar.ind=copy.deepcopy(TABpar_new.ind) #in this way, we move to the last added par in the "prev"
838
+ pri.Coding.yellow(f' |-> +++ {self.TABpar.name}: new par {TABpar_new.ind} <{name}>')
839
+ else:
840
+ TABpar_new=None
841
+ TABpar_prev.append(TABpar_new)
842
+ self.display_controls()
843
+ ind_new=[i for i in ind]
844
+ ind_new[-1]=len(TABpar_prev)-1
845
+ return ind_new
846
+
847
+ def display_controls(self):
848
+ if not self.FlagDisplayControls: return
849
+ FlagVisible=self.TABpar.flagRun==0 and len(self.TABpar.link)==0
850
+ self.ui.button_restore_undo.setVisible(FlagVisible)
851
+ self.ui.button_back.setVisible(FlagVisible)
852
+ self.ui.button_forward.setVisible(FlagVisible)
853
+ lprev=len(self.TABpar_prev_at(self.TABpar.ind))
854
+ if self.onlyReadLabel:
855
+ if len(self.TABpar.link)==0:
856
+ if lprev:
857
+ ITE0=self.gui.ui.Explorer.ITEsfromInd(self.TABpar.ind)[0]
858
+ if ITE0.flagRun==0:
859
+ self.onlyReadLabel.setText('')
860
+ else:
861
+ self.onlyReadLabel.setText('read-only')
862
+ else:
863
+ self.onlyReadLabel.setText('')
864
+ self.button_link_step.setToolTip('Link current process step to another in the same project')
865
+ self.button_link_step.setIcon(self.icon_link)
866
+ self.gui.RCLbar.buttonData[3]['name']='Link step to...'
867
+ else:
868
+ if hasattr(self.gui,'ui') and hasattr(self.gui.ui,'Explorer'):
869
+ ITE0_master=self.gui.ui.Explorer.ITEsfromInd(self.TABpar.link)[0]
870
+ linkInfo=f'linked to {ITE0_master.ind[2]+1}: {ITE0_master.name}'
871
+ self.onlyReadLabel.setText(linkInfo)
872
+ else:
873
+ self.onlyReadLabel.setText('')
874
+ self.button_link_step.setToolTip('Unlink current process step')
875
+ self.button_link_step.setIcon(self.icon_unlink)
876
+ self.gui.RCLbar.buttonData[3]['name']='Unlink step'
877
+ self.button_link_step.setStatusTip(self.button_link_step.toolTip())
878
+ self.button_link_step.setChecked(len(self.TABpar.link)!=0)
879
+
880
+ if self.gui.ui.Explorer.TREpar.step is None:
881
+ FlagProcessTree=False
882
+ else:
883
+ FlagProcessTree=self.gui.ui.Explorer.currentTree==self.gui.ui.Explorer.processTree and self.gui.ui.Explorer.TREpar.step>0
884
+ FlagLabel=(self.TABpar.flagRun!=0 and len(self.TABpar.link)==0) or len(self.TABpar.link)>0
885
+ FlagReset=self.TABpar.flagRun!=0 and len(self.TABpar.link)==0
886
+ FlagInherit=self.TABpar.flagRun==0 and len(self.TABpar.link)==0 and len(self.gui.IOVheritableSteps())>0
887
+ FlagCopy=self.TABpar.flagRun==0 and len(self.TABpar.link)==0 and len(self.gui.linkableSteps(FlagExcludeLinked=True))>0
888
+ FlagLink=(len(self.TABpar.link)==0 and self.TABpar.flagRun==0 and len(self.gui.linkableSteps(FlagExcludeLinked=True))>0) or len(self.TABpar.link)>0
889
+ if FlagProcessTree and (FlagLabel or FlagReset or FlagInherit or FlagCopy or FlagLink):
890
+ self.gui.w_RCL.setVisible(True)
891
+ self.onlyReadLabel.setVisible(FlagLabel)
892
+ self.button_reset_step.setVisible(FlagReset)
893
+ self.button_step_inherit.setVisible(FlagInherit)
894
+ self.button_copy_step.setVisible(FlagCopy)
895
+ self.button_link_step.setVisible(FlagLink)
896
+ else:
897
+ self.gui.w_RCL.setVisible(False)
898
+ FlagEnabled = not self.gui.FlagRun
899
+ self.button_reset_step.setEnabled(FlagEnabled)
900
+ self.button_step_inherit.setEnabled(FlagEnabled)
901
+ self.button_copy_step.setEnabled(FlagEnabled)
902
+ self.button_link_step.setEnabled(FlagEnabled)
903
+
904
+ if self.TABpar.flagRun or len(self.TABpar.link)>0: return
905
+
906
+ i=self.TABpar.ind[-1]
907
+ self.ui.button_restore_undo.setVisible(lprev>1)
908
+ self.ui.button_forward.setVisible(lprev>1)
909
+ self.ui.button_back.setVisible(lprev>1)
910
+ self.ui.button_restore_undo.setEnabled(not (i==lprev-1 or i==-1))
911
+ self.ui.button_forward.setEnabled(not (i==lprev-1 or i==-1))
912
+ self.ui.button_back.setEnabled(i!=0)
913
+ if self.ui.label_number.isVisible():
914
+ if i==lprev-1 or i==-1:
915
+ self.ui.label_number.setText('')
916
+ elif i>=0:
917
+ self.ui.label_number.setText("(-"+str(lprev-1-i)+")")
918
+ else:
919
+ self.ui.label_number.setText("(-"+str(i+1)+")")
920
+
921
+ def button_back_action(self):
922
+ ind=self.TABpar.ind
923
+ ind[-1]-=1
924
+ self.FlagSettingPar=True
925
+ self.setFocus()
926
+ self.FlagSettingPar=False
927
+ self.setTABpar_at(ind,FlagAdjustPar=ind[-1]==0,FlagBridge=True) #True=with bridge
928
+ return False
929
+
930
+ def button_forward_action(self):
931
+ ind=self.TABpar.ind
932
+ ind[-1]+=1
933
+ self.FlagSettingPar=True
934
+ self.setFocus()
935
+ self.FlagSettingPar=False
936
+ self.setTABpar_at(ind,FlagAdjustPar=ind[-1]==0,FlagBridge=True) #True=with bridge
937
+ return False
938
+
939
+ def bfContextMenu(self,bf,event):
940
+ i=self.TABpar.ind[-1]
941
+ TABpar_prev=self.TABpar_prev_at(self.TABpar.ind)
942
+
943
+ if bf==-1:
944
+ b=self.ui.button_back
945
+ f=self.button_back_action
946
+ kin=max([0,i-Num_Prevs_back_forw])
947
+ krange=[k for k in range(i-1,kin,-1)]+[0]
948
+ icon=self.undo_icon
949
+ d=1
950
+ elif bf==1:
951
+ b=self.ui.button_forward
952
+ f=self.button_forward_action
953
+ kfin=min([len(TABpar_prev)-1,i+Num_Prevs_back_forw])
954
+ krange=[k for k in range(i+1,kfin)]+[len(TABpar_prev)-1]
955
+ icon=self.redo_icon
956
+ d=0
957
+
958
+ menu=QMenu(b)
959
+ act=[]
960
+ nur=len(krange)
961
+ flag=nur==Num_Prevs_back_forw
962
+ for j,k in enumerate(krange):
963
+ if j==nur-1:
964
+ if flag: menu.addSeparator()
965
+ if k==0: s=' (first)'
966
+ else: s=' (current)'
967
+ else:
968
+ if j==nur-2 and flag:
969
+ s=' (...)'
970
+ else:
971
+ s=''
972
+ n=f"{k-i:+d}: "
973
+ name=n+TABpar_prev[k+d].tip+s
974
+ act.append(QAction(icon,name,b))
975
+ menu.addAction(act[-1])
976
+
977
+ action = menu.exec_(b.mapToGlobal(event.pos()))
978
+ for k,a in zip(krange,act):
979
+ if a==action:
980
+ self.TABpar.ind[-1]=k-bf
981
+ f()
982
+
983
+ def cleanPrevs(self,ind,FlagAllPrev=False):
984
+ TABpar_prev=self.TABpar_prev_at(ind)
985
+ for _ in range(len(TABpar_prev)-1*int(not FlagAllPrev)):
986
+ TABpar_prev.pop(0)
987
+ if not FlagAllPrev:
988
+ TABpar_prev[0].ind[-1]=0
989
+ if self.TABpar.ind[:-1]==ind[:-1]:
990
+ self.TABpar.ind[-1]=0
991
+
992
+
993
+ #*************************************************** Special spin boxes (x,y,w,h)
994
+ def setMinMaxSpinxywh(self):
995
+ self.ui.spin_x.setMinimum(0)
996
+ self.ui.spin_x.setMaximum(self.TABpar.W-1)
997
+ self.ui.spin_y.setMinimum(0)
998
+ self.ui.spin_y.setMaximum(self.TABpar.H-1)
999
+ self.ui.spin_w.setMinimum(1)
1000
+ self.ui.spin_w.setMaximum(self.TABpar.W)
1001
+ self.ui.spin_h.setMinimum(1)
1002
+ self.ui.spin_h.setMaximum(self.TABpar.H)
1003
+ for field in ('spin_x','spin_y','spin_w','spin_h'):
1004
+ s:MyQSpin=getattr(self.ui,field)
1005
+ tip=getattr(self,"tip_"+field)
1006
+ stringa=". Image size: "+str(self.TABpar.W)+"x"+str(self.TABpar.H)
1007
+ newtip=tip+stringa
1008
+ s.setToolTip(newtip)
1009
+ s.setStatusTip(newtip)
1010
+ self.check_resize()
1011
+
1012
+ def check_resize(self):
1013
+ if self.TABpar.W!=self.TABpar.w or \
1014
+ self.TABpar.H!=self.TABpar.h:
1015
+ self.ui.button_resize.show()
1016
+ else:
1017
+ self.ui.button_resize.hide()
1018
+
1019
+ def button_resize_action(self):
1020
+ self.TABpar.x=self.TABpar.y=0
1021
+ self.TABpar.w=self.TABpar.W
1022
+ self.TABpar.h=self.TABpar.H
1023
+ self.ui.spin_w.setMaximum(self.TABpar.W)
1024
+ self.ui.spin_h.setMaximum(self.TABpar.H)
1025
+ return
1026
+
1027
+ def spin_x_changing(self):
1028
+ wmax=self.TABpar.W-self.ui.spin_x.value()
1029
+ self.ui.spin_w.setMaximum(wmax)
1030
+ w=min([self.TABpar.w,wmax])
1031
+ self.ui.spin_w.setValue(w)
1032
+
1033
+ def spin_x_action(self):
1034
+ self.TABpar.w=self.ui.spin_w.value()
1035
+
1036
+ def spin_y_changing(self):
1037
+ hmax=self.TABpar.H-self.ui.spin_y.value()
1038
+ self.ui.spin_h.setMaximum(hmax)
1039
+ h=min([self.TABpar.h,hmax])
1040
+ self.ui.spin_h.setValue(h)
1041
+
1042
+ def spin_y_action(self):
1043
+ self.TABpar.h=self.ui.spin_h.value()
1044
+
1045
+ #*************************************************** Widget setup
1046
+ def newTip(self,field):
1047
+ s: MyQSpin
1048
+ if field=='spin_range_from': #INPpar
1049
+ s=self.ui.spin_range_from
1050
+ stringa=". Range: "+str(s.minimum())+'-'+str(s.maximum())
1051
+ newtip=self.tip_spin_range_from+stringa
1052
+ elif field=='spin_range_to': #INPpar
1053
+ s=self.ui.spin_range_to
1054
+ stringa=". Max.: "+str(s.maximum())
1055
+ newtip=self.tip_spin_range_to+stringa
1056
+ s.setToolTip(newtip)
1057
+ s.setStatusTip(newtip)
1058
+
1059
+ #*************************************************** Widget setup
1060
+ def setupWid(self:gPaIRS_Tab,FlagFontSize=True):
1061
+ if FlagFontSize: setFontPixelSize(self,fontPixelSize)
1062
+
1063
+ if hasattr(self,'widgets'): widgets=self.widgets
1064
+ else: widgets=self.findChildren(QWidget)
1065
+ widgets+=self.findChildren(CollapsibleBox)
1066
+ for w in widgets:
1067
+ w:QToolButton
1068
+ if hasattr(w,'toolTip'):
1069
+ tooltip=toPlainText(w.toolTip())
1070
+ if hasattr(w,'shortcut'):
1071
+ scut=w.shortcut().toString(QKeySequence.NativeText)
1072
+ if scut:
1073
+ scut=toPlainText('('+scut+')')
1074
+ if scut not in tooltip:
1075
+ tooltip+=' '+scut
1076
+ w.setToolTip(tooltip)
1077
+ #if hasattr(w,'statusTip'):
1078
+ w.setStatusTip(tooltip)
1079
+
1080
+ if hasattr(w,'setup'):
1081
+ w.setup()
1082
+ if hasattr(w,'setup2'):
1083
+ w.setup2()
1084
+
1085
+ if isinstance(w,QToolButton) or isinstance(w,QPushButton):
1086
+ if w.cursor().shape()==Qt.CursorShape.ArrowCursor:
1087
+ w.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
1088
+
1089
+ for sname in ('range_from','range_to','x','y','w','h'):
1090
+ if hasattr(self.ui,"spin_"+sname):
1091
+ sp=getattr(self.ui,"spin_"+sname)
1092
+ setattr(self,"tip_spin_"+sname,sp.toolTip())
1093
+
1094
+ def setFontPixelSize(self,fPixSize):
1095
+ font=self.font()
1096
+ font.setFamily(fontName)
1097
+ font.setPixelSize(fPixSize)
1098
+ self.setFont(font)
1099
+ c=self.findChildren(QWidget)
1100
+ for w in c:
1101
+ w:QWidget
1102
+ if w.objectName()=='title_project' and hasattr(self,'projectTree'):
1103
+ self.projectTree.titleFont(w,fPixSize)
1104
+ elif w.objectName()=='subtitle_project' and hasattr(self,'projectTree'):
1105
+ self.projectTree.subTitleFont(w,fPixSize)
1106
+ elif w.objectName()=='title_process' and hasattr(self,'processTree'):
1107
+ self.processTree.titleFont(w,fPixSize)
1108
+ elif w.objectName()=='subtitle_process' and hasattr(self,'processTree'):
1109
+ self.processTree.subTitleFont(w,fPixSize)
1110
+ elif w.objectName()=='title_step':
1111
+ w.parent().stepTitleFont(w,fPixSize)
1112
+ elif hasattr(w,'setFont'):
1113
+ font=w.font()
1114
+ font.setFamily(fontName)
1115
+ t=type(w)
1116
+ if issubclass(t,QLabel):
1117
+ setFontSizeText(w,[fPixSize-1])
1118
+ elif issubclass(t,QPushButton) or issubclass(t,QToolButton):
1119
+ font.setPixelSize(fPixSize+1)
1120
+ w.setFont(font)
1121
+ adjustFont(w)
1122
+ else:
1123
+ font.setPixelSize(fPixSize)
1124
+ w.setFont(font)
1125
+ adjustFont(w)
1126
+ c=self.findChildren(RichTextPushButton)
1127
+ for w in c:
1128
+ font=w.font()
1129
+ font.setFamily(fontName)
1130
+ font.setPixelSize(fPixSize+3)
1131
+ w.lbl.setFont(font)
1132
+
1133
+ def setFontSizeText(lab:QLabel,fPixSizes):
1134
+ text=lab.text()
1135
+ text=re.sub(r"font-size:\d+pt",f"font-size:{fPixSizes[0]}px",text)
1136
+ text=re.sub(r"font-size:\d+px",f"font-size:{fPixSizes[0]}px",text)
1137
+ if len(fPixSizes)>1:
1138
+ for k in range(len(fPixSizes)-1,0,-1):
1139
+ text=re.sub(r"font-size:\d+px",f"font-size:{fPixSizes[k]}px",text,k)
1140
+ lab.setText(text)
1141
+ font=lab.font()
1142
+ font.setPixelSize(fPixSizes[0])
1143
+ lab.setFont(font)
1144
+ adjustFont(lab)
1145
+
1146
+ def adjustFont(self:QLabel):
1147
+ if not hasattr(self,'geometry'): return
1148
+ if not hasattr(self,'text') and not hasattr(self,'currentText'): return
1149
+ flagParent=self.isVisible() and bool(self.parent())
1150
+ font = self.font()
1151
+ if hasattr(self,'text'):
1152
+ text = self.text()
1153
+ elif hasattr(self,'currentText'):
1154
+ text = self.currentText()
1155
+ else: return
1156
+ if 'Parallel' in text:
1157
+ pass
1158
+
1159
+ if hasattr(self,'text'):
1160
+ if 'Find' in self.text():
1161
+ pass
1162
+
1163
+ S=self.geometry()
1164
+ maxS = QRect(self.pos(),self.maximumSize())
1165
+ minS = QRect(self.pos(),self.minimumSize())
1166
+ if flagParent:
1167
+ r=self.parent().rect()
1168
+ S&= r
1169
+ maxS&= QRect(QPoint(r.x(),r.y()),self.parent().maximumSize())
1170
+ minS&= QRect(QPoint(r.x(),r.y()),self.parent().minimumSize())
1171
+
1172
+ textSize=QtGui.QFontMetrics(font).size(QtCore.Qt.TextSingleLine, text)
1173
+ if (textSize.height()<=S.height()) and (textSize.width()<=S.width()):
1174
+ return
1175
+ while True:
1176
+ if font.pixelSize()<=fontPixelSize_lim[0]:
1177
+ font.setPixelSize(fontPixelSize_lim[0])
1178
+ break
1179
+ if (textSize.height()<=S.height()):
1180
+ break
1181
+ font.setPixelSize(font.pixelSize()-1)
1182
+ textSize=QtGui.QFontMetrics(font).size(QtCore.Qt.TextSingleLine, text)
1183
+
1184
+ textWidth=min([textSize.width(),maxS.width()])
1185
+ textWidth=max([textWidth,minS.width()])
1186
+ if S.width()<textWidth:
1187
+ s=self.geometry()
1188
+ s.setWidth(textWidth)
1189
+ self.setGeometry(s)
1190
+ if flagParent:
1191
+ S=s&self.parent().rect()
1192
+ else:
1193
+ S=s
1194
+ while True:
1195
+ if font.pixelSize()<=fontPixelSize_lim[0]:
1196
+ font.setPixelSize(fontPixelSize_lim[0])
1197
+ break
1198
+ if (textSize.width()<=S.width()):
1199
+ break
1200
+ font.setPixelSize(font.pixelSize()-1)
1201
+ textSize=QtGui.QFontMetrics(font).size(QtCore.Qt.TextSingleLine, text)
1202
+
1203
+ self.setFont(font)
1204
+
1205
+ #*************************************************** Other
1206
+ def iterateList(l,value):
1207
+ if type(l)==list:
1208
+ if len(l):
1209
+ if type(l[0])==list:
1210
+ for m in l:
1211
+ iterateList(m,value)
1212
+ else:
1213
+ for k in range(len(l)):
1214
+ l[k]=value
1215
+
1216
+ def funexample():
1217
+ def fun2(i):
1218
+ if FlagSimulateError:
1219
+ raise Exception("funexample: the requested exception!")
1220
+ pri.Info.cyan('funexample: Hello, sir!')
1221
+ return [1,fun2]
1222
+
1223
+ if __name__ == "__main__":
1224
+ a=TABpar()
1225
+ b=TABpar()
1226
+
1227
+ a.printPar('a: ')
1228
+ c=a.duplicate()
1229
+ b.printPar('b: ')
1230
+
1231
+ a.copyfrom(b)
1232
+ a.printPar('a: ',' copied from b')
1233
+ c.printPar('c: ')
1234
+ c.copyfromfields(b,['surname'])
1235
+ c.printPar('c: ', ' surname copied from b')
1236
+
1237
+ print(f'Is a different from b? {a.isDifferentFrom(b)}')
1238
+ print(f'Is a equal to b? {a.isEqualTo(b)}')
1239
+ print(f'Is c different from b? {c.isDifferentFrom(b)}')
1240
+ print(f'Is c equal to b? {c.isEqualTo(b)}')
1241
+ print(f'Is c different from b except surname? {c.isDifferentFrom(b,["surname"])}')
1242
+ print(f'Is c equal to b except name? {c.isEqualTo(b,["name"])}')
1243
+
1244
+ """
1245
+ app=QApplication.instance()
1246
+ if not app:app = QApplication(sys.argv)
1247
+ app.setStyle('Fusion')
1248
+ TAB = gPaIRS_Tab(None,QWidget)
1249
+ callbackfun=TAB.addParWrapper(funexample,'example')
1250
+ callbackfun()
1251
+ app.exec()
1252
+ app.quit()
1253
+ app=None
1254
+ """