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