Wed 28 Aug 21:38:52 CEST 2024
This commit is contained in:
		
							parent
							
								
									420bca3be9
								
							
						
					
					
						commit
						e891f1b9fe
					
				
							
								
								
									
										367
									
								
								src/SimNDT/gui/treeWidget.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								src/SimNDT/gui/treeWidget.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,367 @@ | ||||||
|  | __author__ = 'Miguel Molero' | ||||||
|  | 
 | ||||||
|  | from PySide.QtCore import * | ||||||
|  | from PySide.QtGui import * | ||||||
|  | 
 | ||||||
|  | from SimNDT.gui.constants import * | ||||||
|  | import numpy as np | ||||||
|  | 
 | ||||||
|  | from SimNDT.core.constants import * | ||||||
|  | from SimNDT.gui import HelperMethods | ||||||
|  | 
 | ||||||
|  | from SimNDT.gui.Warnings import WarningParms | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class MySignal(QObject): | ||||||
|  |     sig = Signal() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TreeWidget(QTreeWidget): | ||||||
|  |     def __init__(self, parent=None): | ||||||
|  | 
 | ||||||
|  |         super(TreeWidget, self).__init__(parent) | ||||||
|  | 
 | ||||||
|  |         self.setGeometry(QRect(0, 0, 350, 840)) | ||||||
|  |         self.setHeaderLabels(["", ""]) | ||||||
|  |         self.setMaximumWidth(650) | ||||||
|  |         self.setMinimumWidth(150) | ||||||
|  |         # self.setRootIsDecorated(True) | ||||||
|  |         self.setAlternatingRowColors(True) | ||||||
|  |         self.setColumnCount(2) | ||||||
|  |         self.header().resizeSection(0, 300) | ||||||
|  | 
 | ||||||
|  |         self.setContextMenuPolicy(Qt.CustomContextMenu) | ||||||
|  |         self.customContextMenuRequested.connect(self.showContextMenu) | ||||||
|  | 
 | ||||||
|  |         self.doubleClicked.connect(self.onDoubleClick) | ||||||
|  |         self.itemChanged.connect(self.onItemChanged) | ||||||
|  |          | ||||||
|  |         self.actionDeleteObject = HelperMethods.createAction(self, "Delete Selected Object", self.deleteObject, | ||||||
|  |                                                              icon="delete.png") | ||||||
|  | 
 | ||||||
|  |         self.deleteDone = MySignal() | ||||||
|  | 
 | ||||||
|  |     def onDoubleClick(self, index): | ||||||
|  |         item = self.currentItem() | ||||||
|  |         item._editing=1 | ||||||
|  | 
 | ||||||
|  |     # Change od editable tree items (attributes, Geom. Objects)         | ||||||
|  |     def onItemChanged(self, item, col): | ||||||
|  |         if hasattr(item,'_editing') and item._editing==1: | ||||||
|  |           item._editing=0 | ||||||
|  |           label = item._userData[0] | ||||||
|  |           value = item._userData[1] | ||||||
|  |           obj   = item._userData[2] | ||||||
|  |           # alayws (re)select the item which was edited (TAB jumps to next row and we loose the _editing flag) | ||||||
|  |           self.setCurrentItem(item) | ||||||
|  |            | ||||||
|  |           if label == '# Cycles': | ||||||
|  |             if obj.N_Cycles is not None: | ||||||
|  |               obj.N_Cycles = int(item.text(1)) | ||||||
|  |               item._userData[1] = obj.N_Cycles             | ||||||
|  |           elif label == 'Angle':           | ||||||
|  |             obj.theta = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.theta | ||||||
|  |           elif label == 'Amplitude': | ||||||
|  |             obj.Amplitude = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.Amplitude            | ||||||
|  |           elif label == 'Border Offset': | ||||||
|  |             obj.BorderOffset = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.BorderOffset | ||||||
|  |           elif label == 'Center X': | ||||||
|  |             obj.x0 = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.x0 | ||||||
|  |           elif label == 'Center Y': | ||||||
|  |             obj.y0 = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.y0 | ||||||
|  |           elif label == 'Center Offset': | ||||||
|  |             obj.CenterOffset = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.CenterOffset | ||||||
|  |           elif label == 'Frequency (MHz)': | ||||||
|  |             obj.Frequency = float(item.text(1))/1e-6 | ||||||
|  |             item._userData[1] = obj.Frequency*1e-6 | ||||||
|  |           elif label == 'Label':           | ||||||
|  |             obj.Label = int(item.text(1)) | ||||||
|  |             item._userData[1] = obj.Label | ||||||
|  |           elif label == 'Radius': | ||||||
|  |             obj.r = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.r | ||||||
|  |           elif label == 'Semi-Major':           | ||||||
|  |             obj.a = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.a | ||||||
|  |           elif label == 'Semi-Minor':           | ||||||
|  |             obj.b = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.b | ||||||
|  |           elif label == 'Size':           | ||||||
|  |             obj.Size = float(item.text(1)) | ||||||
|  |             item._userData[1] = obj.Size | ||||||
|  |           elif label == 'Simulation Time': | ||||||
|  |             obj.SimulationTime = float(item.text(1))/1e6 | ||||||
|  |             item._userData[1] = obj.SimulationTime*1e6 | ||||||
|  |           else: | ||||||
|  |             msgbox=WarningParms("Parameter "+label+" cannot be modified") | ||||||
|  |             msgbox.exec_()  | ||||||
|  |          | ||||||
|  |     def deleteObject(self): | ||||||
|  | 
 | ||||||
|  |         print("delete", self.index) | ||||||
|  |         print | ||||||
|  |         self.SimNDT_ObjectList.pop(self.index) | ||||||
|  |         self.SimNDT_Scenario.resetImage() | ||||||
|  |         for obj in self.SimNDT_ObjectList: | ||||||
|  |             self.SimNDT_Scenario.addObject(obj) | ||||||
|  | 
 | ||||||
|  |         if len(self.SimNDT_ObjectList) == 0: | ||||||
|  |             self.SimNDT_ObjectList = None | ||||||
|  | 
 | ||||||
|  |         self.deleteDone.sig.emit() | ||||||
|  | 
 | ||||||
|  |     def showContextMenu(self, pos): | ||||||
|  |         item = self.itemAt(pos) | ||||||
|  |         menu = QMenu() | ||||||
|  |         it = QTreeWidgetItem.UserType + 1 | ||||||
|  |             | ||||||
|  |         if item.type() == it: # Object Item | ||||||
|  |             HelperMethods.addActions(menu, self.actionDeleteObject) | ||||||
|  |             self.index = item.parent().indexOfChild(item) | ||||||
|  |          | ||||||
|  |         menu.exec_(self.mapToGlobal(pos)) | ||||||
|  | 
 | ||||||
|  |     def update(self, SimNDT_Scenario, | ||||||
|  |                SimNDT_ObjectList, | ||||||
|  |                SimNDT_Materials, | ||||||
|  |                SimNDT_Boundaries, | ||||||
|  |                SimNDT_Inspection, | ||||||
|  |                SimNDT_Source, | ||||||
|  |                SimNDT_Transducers, | ||||||
|  |                SimNDT_Signal, | ||||||
|  |                SimNDT_Simulation): | ||||||
|  | 
 | ||||||
|  |         self.clear() | ||||||
|  |         # Scenario | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         if SimNDT_Scenario: | ||||||
|  |             self.SimNDT_Scenario = SimNDT_Scenario | ||||||
|  | 
 | ||||||
|  |             scenario_tree = QTreeWidgetItem(self) | ||||||
|  |             scenario_tree.setChildIndicatorPolicy(QTreeWidgetItem.DontShowIndicatorWhenChildless) | ||||||
|  | 
 | ||||||
|  |             scenario_tree.setText(0, "Scenario") | ||||||
|  |             scenario_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_1, QFont.Bold)) | ||||||
|  |             scenario_tree.setIcon(0, QIcon(":/newImage.png")) | ||||||
|  | 
 | ||||||
|  |             # Dimensions | ||||||
|  |             dimensions_tree = QTreeWidgetItem(scenario_tree) | ||||||
|  |             dimensions_tree.setText(0, "Dimensions") | ||||||
|  |             dimensions_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_2, QFont.Normal)) | ||||||
|  | 
 | ||||||
|  |             scenario_labels = ("Width", "Height", "Pixel/mm", "Label", "Geometric Model Size") | ||||||
|  |             modelSize = "%d x %d" % (SimNDT_Scenario.M, SimNDT_Scenario.N) | ||||||
|  |             print | ||||||
|  |             "SIZE Scenario", SimNDT_Scenario.I.shape | ||||||
|  |             scenario_values = (SimNDT_Scenario.Width, SimNDT_Scenario.Height, | ||||||
|  |                                SimNDT_Scenario.Pixel_mm, SimNDT_Scenario.Label, modelSize) | ||||||
|  |             self.populateTree(dimensions_tree, scenario_labels, scenario_values,None) | ||||||
|  | 
 | ||||||
|  |             labels_tree = QTreeWidgetItem(scenario_tree) | ||||||
|  |             numLabels = np.size(np.unique(SimNDT_Scenario.I)) | ||||||
|  |             labels_tree.setText(0, "Labels in Scenario") | ||||||
|  |             labels_labels = ("Total Number", "Labels") | ||||||
|  |             labels_values = (numLabels, str(np.unique(SimNDT_Scenario.I))) | ||||||
|  |             labels_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_2, QFont.Normal)) | ||||||
|  |             self.populateTree(labels_tree, labels_labels, labels_values,None) | ||||||
|  | 
 | ||||||
|  |             self.expandItem(scenario_tree) | ||||||
|  | 
 | ||||||
|  |         # Objects | ||||||
|  |         if SimNDT_ObjectList: | ||||||
|  | 
 | ||||||
|  |             ItemType1 = QTreeWidgetItem.UserType + 1 | ||||||
|  |             self.SimNDT_ObjectList = SimNDT_ObjectList | ||||||
|  | 
 | ||||||
|  |             objects_tree = QTreeWidgetItem(scenario_tree) | ||||||
|  |             objects_tree.setText(0, "Objects") | ||||||
|  |             objects_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_2, QFont.Normal)) | ||||||
|  |             for item in SimNDT_ObjectList: | ||||||
|  |                 objects_parent = QTreeWidgetItem(objects_tree, ItemType1) | ||||||
|  |                 objects_parent.setText(0, item.Name) | ||||||
|  |                 if item.Name == "ellipse": | ||||||
|  |                     objects_labels = ("Center X", "Center Y", "Semi-Major", "Semi-Minor", "Angle", "Label") | ||||||
|  |                     objects_values = (item.x0, item.y0, item.a, item.b, item.theta, item.Label) | ||||||
|  |                 if item.Name == "circle": | ||||||
|  |                     objects_labels = ("Center X", "Center Y", "Radius", "Label") | ||||||
|  |                     objects_values = (item.x0, item.y0, item.r, item.Label) | ||||||
|  |                 if item.Name == 'rectangle': | ||||||
|  |                     objects_labels = ("Center X", "Center Y", "Width", "Height", "Label") | ||||||
|  |                     objects_values = (item.x0, item.y0, item.W, item.H, item.Label) | ||||||
|  |                 if item.Name == 'square': | ||||||
|  |                     objects_labels = ("Center X", "Center Y", "Side", "Label") | ||||||
|  |                     objects_values = (item.x0, item.y0, item.L, item.Label) | ||||||
|  | 
 | ||||||
|  |                 self.populateTree(objects_parent, objects_labels, objects_values,item) | ||||||
|  |             self.expandItem(objects_tree) | ||||||
|  | 
 | ||||||
|  |         # Materials | ||||||
|  |         if SimNDT_Materials is not None: | ||||||
|  |             material_tree = QTreeWidgetItem(self) | ||||||
|  |             material_tree.setText(0, "Materials") | ||||||
|  |             material_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_1, QFont.Bold)) | ||||||
|  |             material_tree.setIcon(0, QIcon(":/material.png")) | ||||||
|  | 
 | ||||||
|  |             materials_label = (RHO, "VL", "VT", "H%s (GPa)" % LAMBDA, "H%s (GPa)" % MU, "Label") | ||||||
|  | 
 | ||||||
|  |             for item in SimNDT_Materials: | ||||||
|  |                 materials_parent = QTreeWidgetItem(material_tree) | ||||||
|  |                 materials_parent.setText(0, item.Name) | ||||||
|  |                 materials_parent.setFont(0, QFont(FONT_NAME, FONT_SIZE_2, QFont.Normal)) | ||||||
|  | 
 | ||||||
|  |                 materials_values = ("%0.2f" % (item.Rho), "%0.2f" % (item.VL), "%0.2f" % (item.VT), "%0.2f" % (item.Eta_v), "%0.2f" % (item.Eta_s), item.Label) | ||||||
|  |                 self.populateTree(materials_parent, materials_label, materials_values,None) | ||||||
|  | 
 | ||||||
|  |             self.expandItem(material_tree) | ||||||
|  | 
 | ||||||
|  |         # Boundaries | ||||||
|  |         if SimNDT_Boundaries is not None: | ||||||
|  |             boundaries_tree = QTreeWidgetItem(self) | ||||||
|  |             boundaries_tree.setText(0, "Boundaries") | ||||||
|  |             boundaries_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_1, QFont.Bold)) | ||||||
|  |             boundaries_tree.setIcon(0, QIcon(":/boundary.png")) | ||||||
|  | 
 | ||||||
|  |             for item in SimNDT_Boundaries: | ||||||
|  |                 boundaries_parent = QTreeWidgetItem(boundaries_tree) | ||||||
|  |                 boundaries_parent.setText(0, item.Name) | ||||||
|  |                 boundaries_parent.setFont(0, QFont(FONT_NAME, FONT_SIZE_2, QFont.Normal)) | ||||||
|  | 
 | ||||||
|  |                 boundaries_label = ("Layer", "Size") | ||||||
|  |                 size = item.Size if item.BC == BC.AbsorbingLayer else None | ||||||
|  |                 boundaries_values = (BC.keys[item.BC], size) | ||||||
|  |                 self.populateTree(boundaries_parent, boundaries_label, boundaries_values,None) | ||||||
|  |             self.expandItem(boundaries_tree) | ||||||
|  | 
 | ||||||
|  |         # Inspections | ||||||
|  |         if SimNDT_Inspection is not None: | ||||||
|  | 
 | ||||||
|  |             if SimNDT_Inspection.Name == "LinearScan": | ||||||
|  |                 method = SimNDT_Inspection | ||||||
|  |                 Name = SimNDT_Inspection.Name + ": " + SimNDT_Inspection.Method | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             else: | ||||||
|  |                 method = SimNDT_Inspection | ||||||
|  |                 Name = method.Name | ||||||
|  | 
 | ||||||
|  |             source = SimNDT_Source | ||||||
|  | 
 | ||||||
|  |             inspection_tree = QTreeWidgetItem(self) | ||||||
|  |             inspection_tree.setText(0, "Inspection Method") | ||||||
|  |             inspection_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_1, QFont.Bold)) | ||||||
|  | 
 | ||||||
|  |             if SimNDT_Inspection.Name == "LinearScan": | ||||||
|  |                 inspection_tree.setIcon(0, QIcon(":/linearScan.png")) | ||||||
|  |             elif SimNDT_Inspection.Name == "Tomography": | ||||||
|  |                 inspection_tree.setIcon(0, QIcon(":/tomoSetup.png")) | ||||||
|  |             else: | ||||||
|  |                 inspection_tree.setIcon(0, QIcon(":/singleLaunch.png")) | ||||||
|  | 
 | ||||||
|  |             inspection_parent = QTreeWidgetItem(inspection_tree) | ||||||
|  | 
 | ||||||
|  |             inspection_parent.setText(0, Name) | ||||||
|  |             inspection_parent.setFont(0, QFont(FONT_NAME, FONT_SIZE_2, QFont.Normal)) | ||||||
|  |             inspection_label = ("Longitudinal Source", "Shear Source") | ||||||
|  |             inspection_values = (bool(source.Longitudinal), bool(source.Shear)) | ||||||
|  |             self.populateTree(inspection_parent, inspection_label, inspection_values,None) | ||||||
|  | 
 | ||||||
|  |             transductor_tree = QTreeWidgetItem(inspection_parent) | ||||||
|  |             transductor_tree.setText(0, "Emisor Transducer") | ||||||
|  |             transductor_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_2, QFont.Normal)) | ||||||
|  |             if method.Name == "Tomography": | ||||||
|  |                 transductor_label = ("Size", "Point Source", "Windowed Source") | ||||||
|  |                 transductor_values = (SimNDT_Transducers[0].Size, | ||||||
|  |                                       bool(SimNDT_Transducers[0].PointSource), | ||||||
|  |                                       bool(SimNDT_Transducers[0].Window)) | ||||||
|  |             else: | ||||||
|  |                 transductor_label = ("Size", "Center Offset", "Border Offset", "Point Source", "Windowed Source") | ||||||
|  |                 transductor_values = (SimNDT_Transducers[0].Size, | ||||||
|  |                                       SimNDT_Transducers[0].CenterOffset, | ||||||
|  |                                       SimNDT_Transducers[0].BorderOffset, | ||||||
|  |                                       bool(SimNDT_Transducers[0].PointSource), | ||||||
|  |                                       bool(SimNDT_Transducers[0].Window)) | ||||||
|  |             self.populateTree(transductor_tree, transductor_label, transductor_values,SimNDT_Transducers[0]) | ||||||
|  | 
 | ||||||
|  |             signal_tree = QTreeWidgetItem(inspection_parent) | ||||||
|  |             signal_tree.setText(0, "Signal") | ||||||
|  |             signal_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_2, QFont.Normal)) | ||||||
|  |             signal_tree.setIcon(0, QIcon(":/signal.png")) | ||||||
|  | 
 | ||||||
|  |             if SimNDT_Signal.Name == "GaussianSine": | ||||||
|  |                 signal_label = ("Type", "Amplitude", "Frequency (MHz)", "# Cycles") | ||||||
|  |                 signal_values = (SimNDT_Signal.Name, SimNDT_Signal.Amplitude, | ||||||
|  |                                  SimNDT_Signal.Frequency * 1e-6, SimNDT_Signal.N_Cycles) | ||||||
|  |             else: | ||||||
|  |                 signal_label = ("Type", "Amplitude", "Frequency (MHz)", "# Cycles") | ||||||
|  |                 signal_values = (SimNDT_Signal.Name, SimNDT_Signal.Amplitude, | ||||||
|  |                                  SimNDT_Signal.Frequency * 1e-6) | ||||||
|  | 
 | ||||||
|  |             self.populateTree(signal_tree, signal_label, signal_values,SimNDT_Signal) | ||||||
|  | 
 | ||||||
|  |             self.expandItem(signal_tree) | ||||||
|  |             self.expandItem(inspection_tree) | ||||||
|  |             self.expandItem(inspection_parent) | ||||||
|  | 
 | ||||||
|  |         # Simulation | ||||||
|  |         if SimNDT_Simulation is not None: | ||||||
|  |             simulation_tree = QTreeWidgetItem(self) | ||||||
|  |             simulation_tree.setText(0, "Simulation Parameters") | ||||||
|  |             simulation_tree.setFont(0, QFont(FONT_NAME, FONT_SIZE_1, QFont.Bold)) | ||||||
|  |             simulation_tree.setIcon(0, QIcon(":/simModel.png")) | ||||||
|  | 
 | ||||||
|  |             simulation_label = ("Time Scale", "Max. Frequency (MHz)", "Points/Cycle", | ||||||
|  |                                 "Simulation Time (%ss)" % MU, "Device", "OpenCL", | ||||||
|  |                                 "dx (mm)", "dt (%ss)" % MU, "Numerical Model Size") | ||||||
|  | 
 | ||||||
|  |             freq = SimNDT_Simulation.MaxFreq * 1e-6 | ||||||
|  |             dx = "%.4f" % (SimNDT_Simulation.dx * 1e3) | ||||||
|  |             dt = "%.4f" % (SimNDT_Simulation.dt * 1e6) | ||||||
|  |             simTime = SimNDT_Simulation.SimulationTime * 1e6 | ||||||
|  |             modelSize = "%d x %d" % (SimNDT_Simulation.MRI, SimNDT_Simulation.NRI) | ||||||
|  | 
 | ||||||
|  |             Platform = False if SimNDT_Simulation.Platform == "Serial" else True | ||||||
|  | 
 | ||||||
|  |             simulation_values = (SimNDT_Simulation.TimeScale, freq, | ||||||
|  |                                  SimNDT_Simulation.PointCycle, simTime, | ||||||
|  |                                  SimNDT_Simulation.Device, Platform, | ||||||
|  |                                  dx, dt, modelSize) | ||||||
|  | 
 | ||||||
|  |             self.populateTree(simulation_tree, simulation_label, simulation_values,SimNDT_Simulation) | ||||||
|  | 
 | ||||||
|  |             self.expandItem(simulation_tree) | ||||||
|  | 
 | ||||||
|  |     def populateTree(self, parent, labels, values, obj): | ||||||
|  | 
 | ||||||
|  |         for i, j in zip(labels, values): | ||||||
|  |             if j is None: | ||||||
|  |                 continue | ||||||
|  |             item = QTreeWidgetItem(parent) | ||||||
|  |             if obj != None: | ||||||
|  |               item._userData = [ | ||||||
|  |                 i, | ||||||
|  |                 j, | ||||||
|  |                 obj | ||||||
|  |               ] | ||||||
|  |             item._editing=0 | ||||||
|  |             item.setText(0, i) | ||||||
|  |             item.setFont(0, QFont(FONT_NAME, FONT_SIZE_2, QFont.Normal)) | ||||||
|  |             if isinstance(j, bool): | ||||||
|  |                 if j is True: | ||||||
|  |                     item.setText(1, MARK) | ||||||
|  |                 else: | ||||||
|  |                     item.setText(1, CROSS) | ||||||
|  |             else: | ||||||
|  |                 item.setText(1, str(j)) | ||||||
|  |                 if obj != None: | ||||||
|  |                   item.setFlags(item.flags() | Qt.ItemIsEditable) | ||||||
|  | 
 | ||||||
|  |             item.setFont(1, QFont(FONT_NAME, FONT_SIZE_3, QFont.Normal)) | ||||||
|  | 
 | ||||||
|  |         self.expandItem(parent) | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user