Files
bdbase/guiframe.py

3129 lines
118 KiB
Python

""" Base frame
"""
from datetime import datetime
from decimal import Decimal
import inspect
import os
import re
#import matplotlib
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg, NavigationToolbar2QT as NavigationToolbar)
#matplotlib.use('Agg')
from qtpy.QtCore import QSize, Qt, Slot
from qtpy.QtGui import (
QColor, QDoubleValidator, QFont, QFontMetricsF, QIcon, QIntValidator,
QPainter, QPixmap)
from qtpy.QtWidgets import (
QCheckBox, QComboBox, QDoubleSpinBox, QFrame, QGridLayout, QGroupBox,
QHBoxLayout, QLabel, QLineEdit, QPushButton, QRadioButton, QSpinBox,
QStackedWidget, QTabBar, QTabWidget, QToolButton, QVBoxLayout, QWidget)
from caqtwidgets.pvwidgets import (
CAQLabel, CAQTableWidget, QMessageWidget, QHLine, QVLine)
from apps4ops.bdbase.enumkind import Facility, MsgSeverity, UserMode
_pymodule = os.path.basename(__file__)
_appversion = "1.0.0"
INPUT_PARAMETERS_HEIGHT = 200
EXPERT_PARAMETERS_HEIGHT = 200
def _line():
"""Macro to return the current line number.
The current line number within the file is used when
reporting messages to the message logging window.
Returns:
int: Current line number.
"""
return inspect.currentframe().f_back.f_lineno
class GUIFrame(QWidget):
""" GUI Class
"""
def __init__(self, parent, has_optics=True, has_procedure="Vertical"):
#super(GUIFrame, self).__init__()
super().__init__()
self.parent = parent
self.has_optics = has_optics
if isinstance(has_procedure, bool):
self.has_procedure = has_procedure
self.orientation_procedure = 'Vertical'
else:
self.has_procedure = True
self.orientation_procedure = has_procedure
self.appname = parent.appname
self.facility = parent.facility
self.settings = parent.settings
self.cafe = parent.cafe
self.cyca = parent.cyca
self.input_parameters = parent.input_parameters
self.input_labels = parent.input_labels
self.expert_parameters = parent.expert_parameters
self.expert_labels = parent.expert_labels
self.all_input_parameters = parent.all_input_parameters
self.all_input_labels = parent.all_input_labels
self.all_expert_parameters = parent.all_expert_parameters
self.all_expert_labels = parent.all_expert_labels
self.results_output_wgt_dict = {}
self.results_output_wgt_dict_2 = {}
try:
self.widget_height = self.settings.data["StyleGuide"][
"widgetHeight"]
except KeyError as error:
print("KeyError in guiframe.py, init:", error)
self.widget_height = 25
self.autopost_elog = parent.autopost_elog
self.autopost_epics = parent.autopost_epics
self.autopost_hdf = parent.autopost_hdf
self.autopost_save = None
self.expert_parameters_group = None
self.operator_parameters_group = None
self.output_parameters_wgt = None
self.optics_group = None
self.energy_stacked_widget = None
self.phase_stacked_widget = None
self.table_tab_wgt = None
self.radiobutton = None
self.multiple_figure_dict = None
self.pipeline_group_box = None
self.line_sender_dict = {}
self.radio_stack_dict = {}
self.stack_radiolist_dict = {}
self.stacked_wgt_dict = {}
self.current_stacked_wgt_dict = {}
self.msg_severity_qcolor = parent.msg_severity_qcolor
self.msg_severity = MsgSeverity
self.font_gui = QFont("sans serif")
self.font_gui.setPointSize(10)
self.font_pts10 = QFont("sans serif")
self.font_pts10.setPointSize(10)
self.central_tab_widget = QTabWidget()
self.measurement_wgt = QWidget()
#self.measurement_layout = QHBoxLayout(self.measurement_wgt)
self.measurement_layout = QGridLayout(self.measurement_wgt)
self.measurement_layout.setAlignment(
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignTop))
self.measurement_layout.setSpacing(50)
self.measurement_tab_wgt = QTabWidget(self.measurement_wgt)
self.measurement_tab_wgt.setMinimumWidth(480)
self.operator_wgt = QWidget() #(self.measurement_tab_wgt)
self.expert_wgt = QWidget(self.measurement_tab_wgt)
self.results_wgt = QWidget()
if "GUI" in self.settings.data:
self.results_layout = QHBoxLayout(self.results_wgt)
self.results_tab_wgt = QTabWidget(self.results_wgt)
else:
self.results_layout = QGridLayout()
self.results_tab_wgt = QTabWidget()
self.results_wgt_2 = QWidget()
if "GUI2" in self.settings.data:
self.results_layout_2 = QHBoxLayout(self.results_wgt_2)
self.results_tab_wgt_2 = QTabWidget(self.results_wgt_2)
else:
self.results_layout_2 = QGridLayout()
self.results_tab_wgt_2 = QTabWidget()
self.slicing_group = QGroupBox("Screen: Slicing")
self.good_region_group = QGroupBox("Good Region")
self.canvas_fig_dict = {}
self.canvas_fig_dict_2 = {}
self.left_arrow_dict = {}
self.right_arrow_dict = {}
self.analysis_wgt = QWidget()
self.abort_wgt = QWidget()
self.start_wgt = QWidget()
self.start_wgt_text = "Start"
self.save_all_wgt = QWidget()
if "GUI" in self.settings.data:
if "subResultsTabTitle" in self.settings.data["GUI"]:
self.results_tab_wgt_titles = self.settings.data[
"GUI"]["subResultsTabTitle"]
self.sub_results_wgt = [None] * len(self.results_tab_wgt_titles)
self.sub_results_layout = [None] * len(
self.results_tab_wgt_titles)
for i in range(0, len(self.results_tab_wgt_titles)):
self.sub_results_wgt[i] = QWidget(self.results_tab_wgt)
self.canvas = [None] * len(self.results_tab_wgt_titles)
self.nav = [None] * len(self.results_tab_wgt_titles)
self.arrow_button_widget = [None] * len(
self.results_tab_wgt_titles)
self.canvas_current_idx = [0] * len(self.results_tab_wgt_titles)
self.init_results_tab_wgt()
if "GUI2" in self.settings.data:
if "subResultsTabTitle" in self.settings.data["GUI2"]:
self.results_tab_wgt_titles_2 = self.settings.data[
"GUI2"]["subResultsTabTitle"]
self.sub_results_wgt_2 = [None] * len(
self.results_tab_wgt_titles_2)
self.sub_results_layout_2 = [None] * len(
self.results_tab_wgt_titles_2)
for i in range(0, len(self.results_tab_wgt_titles_2)):
self.sub_results_wgt_2[i] = QWidget() #self.results_tab_wgt_2)
self.canvas_2 = [None] * len(self.results_tab_wgt_titles_2)
self.nav_2 = [None] * len(self.results_tab_wgt_titles_2)
self.arrow_button_widget_2 = [None] * len(
self.results_tab_wgt_titles_2)
self.canvas_current_idx_2 = [0] * len(
self.results_tab_wgt_titles_2)
self.init_results_tab_wgt_2()
self.slice_orientation = "vertical" #horizontal/vertical for SATMA02
self.init_measurement_tab_wgt()
self.log_wgt = QMessageWidget()
self.log_layout = QVBoxLayout(self.log_wgt)
#self.show_log_message(MsgSeverity.INFO, _pymodule, _line(),
# "Application started")
self.input_wgt_grid = QGridLayout()
self.input_wgt_grid.setHorizontalSpacing(0)
self.input_wgt_grid.setVerticalSpacing(2)
self.expert_wgt_grid = QGridLayout()
self.expert_wgt_grid.setHorizontalSpacing(0)
self.expert_wgt_grid.setVerticalSpacing(2)
if "GUITree" in self.settings.data:
self.init_central_tab_widget_tree()
else:
self.init_central_tab_widget()
self.enter_input_parameters()
def init_central_tab_widget_tree(self): #_from_config(self):
self.central_tab_widget.setFont(self.font_gui)
_margin = 4
destination_index = []
try:
idx = self.settings.data["GUI"]["destinationTreeIndex"]
destination_index.append(idx)
except KeyError:
pass
try:
idx = self.settings.data["GUI2"]["destinationTreeIndex"]
destination_index.append(idx)
except KeyError:
pass
def is_destination(a, b, c):
for item in destination_index:
if len(item) != 3:
continue
if item[0] == a and item[1] == b and item[2] == c:
return True
return False
if "GUITree" in self.settings.data:
key_list = list(self.settings.data["GUITree"].keys())
self.level1_wgt = [None] * len(key_list)
self.level1_tab_wgt = [None] * len(key_list)
self.level2_wgt = {}
self.level2_tab_wgt = {}
self.level3_wgt = {}
self.level3_tab_wgt = {}
#qwgt2 = {}
#qwgt2_tab = {}
for i, title in enumerate(key_list):
print(i, title, flush=True)
self.level1_wgt[i] = QWidget()
self.level1_wgt[i].title = title
self.level1_tab_wgt[i] = QTabWidget() #self.level1_wgt[i])
self.level1_tab_wgt[i].setMinimumWidth(480)
self.level1_tab_wgt[i].setFont(self.font_gui)
key_list2 = list(self.settings.data["GUITree"][title])
self.level2_wgt[i] = [None] * len(key_list2)
self.level2_tab_wgt[i] = [None] * len(key_list2)
#qwgt2[i] = [None] * len(key_list2)
#qwgt2_tab[i] = [None] * len(key_list2)
self.level3_wgt[i] = [None] * len(key_list2)
self.level3_tab_wgt[i] = [None] * len(key_list2)
for j, title2 in enumerate(key_list2):
print(j, title2, flush=True)
key_list3 = (self.settings.data["GUITree"][title][title2])
is_plot = False
if isinstance(key_list3, list):
#if "Plots" in key_list3:
# is_plot = True
len_key_list3 = len(key_list3)
self.level3_wgt[i][j] = [None] * len_key_list3
self.level3_tab_wgt[i][j] = [None] * len_key_list3
elif isinstance(key_list3, dict):
if 'link' in key_list3:
#get link
link = key_list3['link']
key_list3 = (self.settings.data[link]["subResultsTabTitle"])
if isinstance(key_list3, list):
is_plot = True
len_key_list3 = len(key_list3)
self.level3_wgt[i][j] = [None] * len_key_list3
self.level3_tab_wgt[i][j] = [None] * len_key_list3
else:
len_key_list3 = 0
else:
len_key_list3 = 0
else:
len_key_list3 = 0
self.level2_wgt[i][j] = QWidget() #self.level1_wgt[i])
self.level2_wgt[i][j].title = title2
self.level2_wgt[i][j].setFont(self.font_gui)
#Attaching the correct object to QTabWidget is crucuial!
if not is_plot:
self.level2_tab_wgt[i][j] = QTabWidget(self.level2_wgt[i][j])
else:
if i == 1:
print("///", i, j, flush=True)
self.level2_tab_wgt[i][j] = QTabWidget() #self.results_wgt_2)
else:
print("//", i, j, flush=True)
self.level2_tab_wgt[i][j] = QTabWidget() #self.results_wgt)
self.level2_tab_wgt[i][j].setMinimumWidth(480)
self.level2_tab_wgt[i][j].setFont(self.font_gui)
for k in range (0, len_key_list3):
print("tilt3", key_list3[k], flush=True)
self.level3_tab_wgt[i][j][k] = QTabWidget()
#if "Plots" in key_list3[k]:
# is_plot = True
#if not is_plot:
title3 = key_list3[k]
self.level3_wgt[i][j][k] = QWidget() #self.level2_wgt[i][j])
self.level3_wgt[i][j][k].title = title3
self.level3_wgt[i][j][k].setFont(self.font_gui)
if is_destination(i, j, k):
#is_plot = True
#if i==1 and j==0 and k==1:
print("LEVEL2=============>", i, j, k, title3)
self.level2_tab_wgt[i][j].addTab(self.results_wgt_2, title3)
else:
print("LEVEL2/3=============>", i, j, k, title3)
self.level2_tab_wgt[i][j].addTab(self.level3_wgt[i][j][k], title3)
if not is_plot:
self.level1_tab_wgt[i].addTab(self.level2_wgt[i][j], title2)
else:
#if i == 1 and j==0:
# print("////", i, flush=True)
# self.level1_tab_wgt[i].addTab(self.results_wgt_2, title2)
#else:
# print("//=", i, flush=True)
self.level1_tab_wgt[i].addTab(self.results_wgt, title2)
layout2 = QGridLayout() #self.level1_wgt[i])
layout2.addWidget(self.level2_tab_wgt[i][j])
layout2.addWidget(QFrame()) #Add to stop streching of Measurement Tab
layout2.setContentsMargins(_margin, _margin, _margin, _margin)
self.level2_wgt[i][j].setLayout(layout2)
layout = QGridLayout() #self.level1_wgt[i])
layout.addWidget(self.level1_tab_wgt[i], 1, 0, 1, 20)
self.level1_wgt[i].setLayout(layout)
layout.setContentsMargins(_margin, _margin, _margin, _margin)
self.central_tab_widget.addTab(self.level1_wgt[i], title)
#***How to get to the widgets within the lowest level tabs***
#lo = QHBoxLayout()
#lo.addWidget(QLabel('TEST'))
#self.gui_frame.level2_tab_wgt[1][0].widget(0).setLayout(lo)
#self.gui_frame.level3_wgt[1][0][0].setLayout(lo)
#if "GUI" in self.settings.data:
#self.central_tab_widget.addTab(
## self.level1_tab_wgt[1].addTab(
## self.results_wgt, self.settings.data["GUI"]["resultsTabTitle"])
self.central_tab_widget.addTab(self.log_wgt, "Log")
self.operator_wgt = self.level3_wgt[0][0][0]
self.expert_wgt = self.level3_wgt[0][0][1]
self.measurement_tab_wgt = self.level2_tab_wgt[0][0]
self.measurement_wgt = self.level2_wgt[0][0]
def init_central_tab_widget(self):
""" Add tabs to central widget
"""
self.central_tab_widget.setFont(self.font_gui)
self.central_tab_widget.addTab(self.measurement_wgt, "Measurement")
#if "GUITree" in self.settings.data:
# tab = list(self.settings.data["GUITree"].keys())[0]
# self.central_tab_widget.addTab(self.measurement_wgt, tab)
if "GUI" in self.settings.data:
self.central_tab_widget.addTab(
self.results_wgt, self.settings.data["GUI"]["resultsTabTitle"])
elif "IOC" in self.settings.data:
self.central_tab_widget.addTab(
self.results_wgt, self.settings.data["IOC"]["resultsTabTitle"])
self.central_tab_widget.addTab(self.log_wgt, "Log")
def init_measurement_tab_wgt(self):
""" Add tabs to measurement widget
"""
row_idx = 0
column_idx = 0
no_rows = 1
no_columns = 1
try:
layout_parameters = self.settings.data["MeasurementGridLayout"]
row_idx = layout_parameters[0]
column_idx = layout_parameters[1]
no_rows = layout_parameters[2]
no_columns = layout_parameters[3]
except KeyError:
pass
self.measurement_tab_wgt.setFont(self.font_gui)
self.measurement_tab_wgt.addTab(self.operator_wgt, "Operator")
self.measurement_tab_wgt.addTab(self.expert_wgt, "Expert")
self.measurement_layout.addWidget(
self.measurement_tab_wgt, row_idx, column_idx, no_rows, no_columns)
def init_results_tab_wgt(self):
""" Add canvas tabs for plots/results
"""
self.results_tab_wgt.setFont(self.font_gui)
for i, (wgt, subtitle) in enumerate(zip(self.sub_results_wgt,
self.results_tab_wgt_titles)):
top_widget = QWidget(self.results_tab_wgt)
top_layout = QVBoxLayout()
self.sub_results_layout[i] = QVBoxLayout()
if self.settings.data["GUI"]["resultsSeq"][i] > 1:
top_layout.addWidget(self.get_arrow_button_widget(i))
wgt.setLayout(self.sub_results_layout[i])
top_layout.addWidget(wgt)
#top_layout.addWidget(QLabel("HERE"))
top_widget.setLayout(top_layout)
self.results_tab_wgt.addTab(top_widget, subtitle)
self.results_layout.addWidget(self.results_tab_wgt)
def init_results_tab_wgt_2(self):
""" Add canvas tabs for plots/results
"""
self.results_tab_wgt_2.setFont(self.font_gui)
for i, (wgt, subtitle) in enumerate(zip(self.sub_results_wgt_2,
self.results_tab_wgt_titles_2)):
top_widget = QWidget(self.results_tab_wgt_2)
top_layout = QVBoxLayout()
self.sub_results_layout_2[i] = QVBoxLayout()
if self.settings.data["GUI2"]["resultsSeq"][i] > 1:
top_layout.addWidget(self.get_arrow_button_widget(i))
wgt.setLayout(self.sub_results_layout_2[i])
top_layout.addWidget(wgt)
#top_layout.addWidget(QLabel("THERE"))
top_widget.setLayout(top_layout)
self.results_tab_wgt_2.addTab(top_widget, subtitle)
self.results_layout_2.addWidget(self.results_tab_wgt_2)
def show_log_message(self, severity=None, pymodule="", lineno=0, message="",
options=None):
""" Post to log window
"""
source = "{0}:{1:d} ".format(pymodule, lineno)
#datetime.utcnow()
message_to_send = datetime.now().strftime(
"%Y-%m-%d %H:%M:%S.%f")[:-5]
message_to_send += " "
if isinstance(severity, self.msg_severity):
message_to_send += severity.name
elif severity in self.msg_severity_qcolor.keys():
message_to_send += str(severity)
elif str(severity) == "WARNING":
message_to_send += "WARN"
message_to_send += (" {" + source + message + "} ")
if options:
for k, v in options.items():
message_to_send += (" [" + str(k) + ": " + str(v) + "]")
self.log_wgt.insertItem(0, message_to_send)
self.log_wgt.item(0).setFlags(
Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled |
Qt.NoItemFlags)
self.log_wgt.item(0).setForeground(
self.msg_severity_qcolor.get(severity, QColor(8, 8, 8)))
#Top level groups
def analysis_procedure_group(self):
""" Procedure group box
"""
if 'V' in self.orientation_procedure.upper():
_width = 208
_height = 196
else:
_width = 508
_height = 106
group_box = QGroupBox("Procedure")
group_box.setObjectName("OUTER")
vbox = QVBoxLayout()
vbox.addLayout(self.create_analysis_wgt())
vbox.setContentsMargins(9, 19, 9, 9)
vbox.setSpacing(5)
vbox.setAlignment(Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignHCenter))
group_box.setMaximumWidth(_width)
group_box.setMinimumHeight(_height)
group_box.setFont(self.font_gui)
group_box.setAlignment(Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignHCenter))
group_box.setLayout(vbox)
return group_box
def optics_groupbox(self):
""" Optice set and restore group box
"""
self.optics_group = QGroupBox("Optics")
self.optics_group.setObjectName("OUTER")
self.optics_group.setMaximumWidth(208)
self.optics_group.setMaximumHeight(220)
self.optics_group.setFont(self.font_gui)
self.optics_group.setAlignment(
Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignHCenter))
self.optics_group.setAlignment(Qt.AlignCenter)
self.optics_group.setLayout(self.create_optics_layout())
self.optics_group.table = None
self.optics_group.deflector = None
self.optics_group.profile_monitor = None
self.optics_group.quads = None
self.optics_group.cycle_quads = None
return self.optics_group
def output_parameters_group(self, title="Results Output"):
""" Generic group box for user supplied input
"""
self.output_parameters_wgt = QWidget()
qtop = QVBoxLayout()
self.output_parameters_group_box = QGroupBox(title)
self.output_parameters_group_box.setObjectName("OUTER")
vbox = QVBoxLayout()
vbox.setContentsMargins(9, 19, 9, 9)
vbox.setAlignment(Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignHCenter))
keys = self.settings.data["Results"].keys()
max_str_len = 4
for key in keys:
if len(key) > max_str_len:
max_str_len = len(key)
for key in keys:
ikey = self.settings.data["Results"][key]
if ikey['flag']:
_widget = ikey["data"]["widget"].upper()
_text = ikey["data"]["text"]
_value = str(ikey["data"]["value"])
_width = int(ikey["data"]["width"])
if _widget == "QLINEEDIT":
ql = QLabel(str(_text))
_label_width = (ql.fontMetrics().averageCharWidth() *
max_str_len+2)
ql.setMinimumWidth(_label_width)
ql.setFixedHeight(self.widget_height)
ql.setFont(self.font_pts10)
wgt = QLineEdit()
wgt.setFixedWidth(_width)
wgt.setObjectName("ReadRight")
wgt.setFixedHeight(self.widget_height)
wgt.setFont(self.font_pts10)
wgt.setAlignment(Qt.AlignRight)
self.results_output_wgt_dict[key] = wgt
if "NONE" not in _value.upper():
self.results_output_wgt_dict[key].setText(_value)
hbox = QHBoxLayout()
hbox.setContentsMargins(0, 0, 0, 0)
hbox.addWidget(ql)
hbox.addWidget(wgt)
hbox.setAlignment(Qt.AlignLeft)
vbox.addLayout(hbox)
self.output_parameters_group_box.setContentsMargins(9, 19, 9, 9)
self.output_parameters_group_box.setMinimumWidth(140)
self.output_parameters_group_box.setMaximumWidth(300)
#self.output_parameters_group_box.setMaximumHeight(400)
self.output_parameters_group_box.setFont(self.font_gui)
self.output_parameters_group_box.setAlignment(
Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignHCenter))
qf = QFrame()
qf.setFixedHeight(35)
self.output_parameters_group_box.setLayout(vbox)
qtop.addWidget(qf)
qtop.addWidget(self.output_parameters_group_box)
self.output_parameters_wgt.setLayout(qtop)
return self.output_parameters_wgt
def send_to_results_output_wgt(self, results_data):
for key, value in results_data.items():
self.results_output_wgt_dict[key].setText(str(value))
def input_parameters_group(self, title="Input Parameters"):
""" Generic group box for user supplied input
"""
group_box = QGroupBox(title)
group_box.setObjectName("OUTER")
hbox = QVBoxLayout()
hbox.setContentsMargins(9, 19, 9, 9)
hbox.setAlignment(Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignHCenter))
group_box.setContentsMargins(0, 0, 0, 0)
group_box.setMinimumWidth(200)
group_box.setMaximumHeight(400)
group_box.setFont(self.font_gui)
group_box.setAlignment(Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignHCenter))
group_box.setLayout(hbox)
return group_box
def operator_parameters_groupbox(self, title="Input Parameters"):
""" Operator input parameters group box
"""
self.operator_parameters_group = self.input_parameters_group(title)
return self.operator_parameters_group
def expert_parameters_groupbox(self, title="Expert Parameters"):
""" Expert input parameters group box
"""
self.expert_parameters_group = self.input_parameters_group(title)
return self.expert_parameters_group
def create_checkbox(self, top_key, key, text="", tip="",
default_value=Qt.Unchecked):
""" Generic check box
"""
def on_checkbox_change(value):
self.input_parameters[key] = bool(value)
#print("CB fired")
#print(self.input_parameters[key])
#print(self.input_parameters)
if key == "goodRegion":
self.good_region_group.setEnabled(value)
checkbox = QCheckBox(text)
checkbox.setToolTip(tip)
checkbox.setFont(self.font_gui)
checkbox.stateChanged.connect(on_checkbox_change)
#checkbox.setFixedHeight(30)
#checkbox.setLayoutDirection(Qt.RightToLeft)
checked_value = default_value
if key in self.parent.input_parameters.keys():
if "data" in self.settings.data[top_key][key].keys():
if "value" in self.settings.data[top_key][key]["data"].keys():
if self.settings.data[top_key][key]["data"]["value"]:
checked_value = Qt.Checked
else:
checked_value = Qt.Unchecked
checkbox.setCheckState(checked_value)
checkbox.stateChanged.emit(checked_value)
self.line_sender_dict[key] = checkbox
return checkbox
def create_label_qdoublespinbox(self, key, label="", min_val=0, max_val=1,
step=0.1, start_val=0.5, digits=1):
""" Generic QDoubleSpinbox with buddy label
"""
def callback(value):
self.input_parameters[key] = round(value, digits)
widget_height = 24
suggested = "WWW"
lab = QLabel(label)
lab.setFixedHeight(widget_height)
lab.setFont(self.font_pts10)
lab.setContentsMargins(5, 0, 0, 0)
wgt = QDoubleSpinBox()
wgt.setObjectName("Write")
wgt.setFixedHeight(widget_height)
wgt.setFont(self.font_pts10)
wgt.setContentsMargins(5, 0, 0, 0)
decimal = Decimal(str(step))
wgt.setDecimals(abs(decimal.as_tuple().exponent)) #precision
wgt.setRange(min_val, max_val)
wgt.setSingleStep(step)
fm = QFontMetricsF(wgt.font())
param_width = max(fm.width(str(decimal)), fm.width(suggested))
wgt.setMaximumWidth(int(param_width + 40))
wgt.valueChanged.connect(callback)
wgt.setValue(start_val)
wgt.valueChanged.emit(start_val)
self.line_sender_dict[key] = wgt
return lab, wgt
def create_label_qspinbox(self, key, label="", min_val=0, max_val=100,
step=1, start_val=5):
""" Generic QSpinbox with buddy label
"""
def cb(value):
self.input_parameters[key] = value
widget_height = 24
suggested = "WWW"
lab = QLabel(label)
lab.setFixedHeight(widget_height)
lab.setFont(self.font_pts10)
lab.setContentsMargins(5, 0, 0, 0)
wgt = QSpinBox()
wgt.setObjectName("Write")
wgt.setFixedHeight(widget_height)
wgt.setFont(self.font_pts10)
wgt.setContentsMargins(5, 0, 0, 0)
decimal = Decimal(str(step))
wgt.setRange(min_val, max_val)
wgt.setSingleStep(step)
fm = QFontMetricsF(wgt.font())
param_width = max(fm.width(str(decimal)), fm.width(suggested))
wgt.setMaximumWidth(int(param_width + 40))
wgt.valueChanged.connect(cb)
wgt.setValue(start_val)
wgt.valueChanged.emit(start_val)
self.line_sender_dict[key] = wgt
return lab, wgt
def create_label_qcombobox(self, key, label="", values: list = [],
start_val: str =""):
""" Generic QCombobox with buddy label
"""
def cb(new_text):
self.input_parameters[key] = new_text
#print( self.input_parameters)
widget_height = 26
suggested = "WWW"
lab = QLabel(label)
lab.setFixedHeight(widget_height)
lab.setFont(self.font_pts10)
lab.setContentsMargins(5, 0, 0, 0)
wgt = QComboBox()
wgt.clear()
if values:
wgt.addItems(values)
wgt.setObjectName("Write")
wgt.setFixedHeight(widget_height)
wgt.setFont(self.font_pts10)
wgt.setContentsMargins(5, 0, 0, 0)
wgt.currentTextChanged.connect(cb)
start_idx = wgt.findText(start_val)
start_idx = start_idx if start_idx > 0 else 0
wgt.setCurrentIndex(start_idx)
wgt.currentTextChanged.emit(values[start_idx])
value_for_width = max(values, key=len)
fm = QFontMetricsF(wgt.font())
param_width = max(fm.width(str(value_for_width)), fm.width(suggested))
wgt.setFixedWidth(int(param_width + 50))
self.line_sender_dict[key] = wgt
return lab, wgt
def create_analysis_wgt(
self, start_title="Start", start_action=None,
start_tooltip="Start measurement and analysis procedure",
abort_title="Abort", abort_action=None,
abort_tooltip="Abort procedure at next break point",
orientation="Vertical"):
if start_action is None:
start_action = self.parent.start_analysis_thread
if abort_action is None:
abort_action = self.parent.receive_abort_analysis
self.start_wgt = self.create_start_wgt(start_title, start_action,
start_tooltip)
self.abort_wgt = self.create_abort_wgt(abort_title, abort_action,
abort_tooltip)
self.save_all_wgt = self.save_all_group()
grid = QVBoxLayout() if 'V' in self.orientation_procedure.upper() \
else QHBoxLayout()
grid.addWidget(self.start_wgt)
grid.addWidget(self.abort_wgt)
grid.addWidget(self.save_all_wgt)
grid.setAlignment(Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignTop))
return grid
def create_optics_layout(self):
vbox = QGridLayout()
self.set_optics_btn = QPushButton("Set")
self.set_optics_btn.setFixedWidth(100)
self.set_optics_btn.setFixedHeight(40)
self.set_optics_btn.setObjectName("Controller")
self.set_optics_btn.setProperty("actOnBeam", True)
self.set_optics_btn.clicked.connect(self.parent.set_optics)
_tip = "Set associated quadruples"
self.set_optics_btn.setToolTip(_tip)
self.restore_optics_btn = QPushButton("Restore")
self.restore_optics_btn.setFixedWidth(100)
self.restore_optics_btn.setFixedHeight(40)
self.restore_optics_btn.setObjectName("Controller")
self.restore_optics_btn.setProperty("actOnBeam", True)
self.restore_optics_btn.clicked.connect(self.parent.restore_optics)
_tip = "Restore quadruples to their pre-measurement values"
self.restore_optics_btn.setToolTip(_tip)
self.target_optics = QLabel()
#self.target_optics.setText(_text)
self.target_optics.setFixedWidth(150)
self.target_optics.setFixedHeight(40)
self.target_optics.setStyleSheet("background-color:white;")
_tip = "Shows target for optics settings"
self.target_optics.setToolTip(_tip)
vbox.addWidget(self.set_optics_btn, 0, 0, Qt.AlignCenter)
vbox.addWidget(self.target_optics, 1, 0, Qt.AlignCenter)
vbox.addWidget(self.restore_optics_btn, 2, 0, Qt.AlignCenter)
vbox.setContentsMargins(0, 19, 0, 9)
vbox.setAlignment(Qt.AlignCenter)
vbox.setSpacing(8)
return vbox
def in_measurement_procedure(self):
self.abort_wgt.setVisible(True)
self.abort_wgt.setEnabled(True)
self.start_wgt.setEnabled(False)
self.start_wgt.setText("in progress...")
self.save_all_group_box.setEnabled(False)
self.operator_parameters_group.setEnabled(False)
self.expert_parameters_group.setEnabled(False)
if self.optics_group is not None:
self.optics_group.setEnabled(False)
if self.table_tab_wgt is not None:
for table in self.table_wgt:
table.init_value_button.setEnabled(False)
table.restore_value_button.setEnabled(False)
if self.output_parameters_wgt is not None:
for wgt in self.results_output_wgt_dict.values():
wgt.setText("")
#self.output_parameters_wg.setEnabled(False)
def in_abort_procedure(self):
self.abort_wgt.setEnabled(False)
self.start_wgt.setEnabled(False)
self.start_wgt.setText("Aborting...")
def reset_procedure(self):
self.abort_wgt.setVisible(False)
self.abort_wgt.setEnabled(True)
self.start_wgt.setEnabled(True)
self.start_wgt.setText(self.start_wgt_text)
self.save_all_group_box.setEnabled(True)
self.operator_parameters_group.setEnabled(True)
self.expert_parameters_group.setEnabled(True)
if self.optics_group is not None:
self.optics_group.setEnabled(True)
if self.table_tab_wgt is not None:
for table in self.table_wgt:
table.init_value_button.setEnabled(True)
table.restore_value_button.setEnabled(True)
#if self.output_parameters_wgt is not None:
# self.output_parameters_wgt.setEnabled(True)
def in_hdf_measurement_procedure(self):
self.parent.h5_groupbox.analyze_h5_widget.setEnabled(False)
self.parent.h5_groupbox.analyze_h5_widget.setText("Analysing")
self.start_wgt.setEnabled(False)
self.start_wgt.setText("HDF analysis...")
self.save_all_group_box.setEnabled(False)
def hdf_reset_procedure(self):
self.parent.h5_groupbox.analyze_h5_widget.setEnabled(True)
self.parent.h5_groupbox.analyze_h5_widget.setText("Analyze")
self.start_wgt.setEnabled(True)
self.start_wgt.setText(self.start_wgt_text)
self.save_all_group_box.setEnabled(True)
def create_abort_wgt(self, title, action, tooltip):
abort_wgt = QPushButton(title)
abort_wgt.setObjectName("Abort")
abort_wgt.setFixedWidth(150)
abort_wgt.setFixedHeight(40)
abort_wgt.setToolTip(tooltip)
if action:
abort_wgt.clicked.connect(action)
abort_wgt.setVisible(False)
sp_retain = abort_wgt.sizePolicy()
sp_retain.setRetainSizeWhenHidden(True)
abort_wgt.setSizePolicy(sp_retain)
return abort_wgt
def create_start_wgt(self, title, action, tooltip):
start_wgt = QPushButton(title)
start_wgt.setObjectName("Controller")
start_wgt.setProperty("actOnBeam", True)
start_wgt.setFixedWidth(150)
start_wgt.setFixedHeight(40)
start_wgt.setToolTip(tooltip)
if action:
start_wgt.clicked.connect(action)
start_wgt.setVisible(True)
return start_wgt
def combine_save_icons(self): #epics=False, hdf=False, elog=False):
epics = self.autopost_epics
hdf = self.autopost_hdf
elog = self.autopost_elog
combinedIcon = QIcon()
startx1 = 0
startx2 = 0
startx3 = 0
true_list = [epics, hdf, elog]
if true_list.count(True) == 1:
startx1 = 150
startx2 = 150
startx3 = 150
elif true_list.count(True) == 3:
startx1 = 0
startx2 = 150
startx3 = 300
else:
if epics:
startx1 = 75
startx2 = 225
startx3 = 225
elif hdf:
startx2 = 75
startx3 = 225
comboPixmap = QPixmap(420, 100) #420, 100
comboPixmap.fill(Qt.transparent)
epicsImage = QPixmap(":/epics.png")
hdfImage = QPixmap(":/hdfS.png")
elogImage = QPixmap(":/elog.png")
painter = QPainter(comboPixmap)
if epics:
painter.drawPixmap(startx1, 0, epicsImage, 0, -20, 100, 160)
if hdf:
painter.drawPixmap(startx2, 0, hdfImage, 0, -20, 100, 160)
if elog:
painter.drawPixmap(startx3, 0, elogImage)
combinedIcon.addPixmap(comboPixmap)
painter.end()
return combinedIcon
def post_measurement_save_button(self): # epics=True, hdf=True, elog=True):
epics = self.autopost_epics #= epics
hdf = self.autopost_hdf #= hdf
elog = self.autopost_elog #= elog
widget_height = 40
true_list = [epics, hdf, elog]
widget_width = max(75, 45 * true_list.count(True))
save_data_btn = QPushButton("")
save_data_btn.setIconSize(QSize(100, 38))
save_data_btn.setIcon(self.combine_save_icons())
#epics=epics, hdf=hdf, elog=elog))
save_data_btn.setFixedHeight(widget_height)
save_data_btn.setObjectName("WriteData")
save_data_btn.clicked.connect(self.parent.write_to_destinations)
save_data_btn.setFixedHeight(widget_height)
save_data_btn.setFixedWidth(widget_width) #80 for one
if epics and hdf and elog:
choices = "epics/hdf5/elog"
elif epics and hdf:
choices = "epics/hdf5"
elif hdf and elog:
choices = "hdf/elog"
elif epics:
choices = "epics"
elif hdf:
choices = "hdf"
elif elog:
choices = "elog"
_tip = "Saves data to {0}".format(choices)
save_data_btn.setToolTip(_tip)
self.autopost_save = save_data_btn
return self.autopost_save
def post_measurement_group(self):
group_box = QGroupBox("Post-measurement")
group_box.setObjectName("OUTER")
hbox = QVBoxLayout()
hbox.addWidget(self.post_measurement_save_button())
hbox.setContentsMargins(9, 19, 9, 9)
hbox.setAlignment(Qt.AlignmnetFlag(Qt.AlignTop|Qt.AlignHCenter))
group_box.setContentsMargins(0, 0, 0, 0)
group_box.setFixedWidth(208)
group_box.setMaximumHeight(130)
group_box.setFont(self.font_gui)
group_box.setAlignment(Qt.AlignmnetFlag(Qt.AlignTop|Qt.AlignHCenter))
group_box.setLayout(hbox)
return group_box
def save_all_group(self):
self.save_all_group_box = QGroupBox("Save All")
self.save_all_group_box.setObjectName("INNERCENTER")
hbox = QVBoxLayout()
hbox.addWidget(self.post_measurement_save_button())
hbox.setContentsMargins(1, 4, 1, 2)
hbox.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
self.save_all_group_box.setContentsMargins(0, 0, 0, 0)
self.save_all_group_box.setMaximumWidth(160)
self.save_all_group_box.setFixedHeight(60)
self.save_all_group_box.setFont(self.font_gui)
self.save_all_group_box.setAlignment(
Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignHCenter))
self.save_all_group_box.setLayout(hbox)
return self.save_all_group_box
def image_parameters_group(self):
self.pipeline_group_box = QGroupBox("Image Pipeline Expert")
box = QHBoxLayout()
box.setSpacing(10)
try:
start_val_gr = self.settings.data["Expert"]["pipeline"]["data"][
"goodRegion"]
start_val_gr = Qt.Checked if start_val_gr else Qt.Unchecked
except KeyError as ex:
start_val_gr = Qt.Unchecked
box.addWidget(self.create_checkbox(
top_key="Expert", key="goodRegion", text="Good region",
tip="Enables good region in pipeline", default_value=start_val_gr))
try:
start_val_sub = self.settings.data["Expert"]["pipeline"]["data"][
"subtractBackground"]
start_val_sub = Qt.Checked if start_val_sub else Qt.Unchecked
except KeyError as ex:
start_val_sub = Qt.Unchecked
box.addWidget(self.create_checkbox(
top_key="Expert", key="subtractBackground",
text="Subtract bkgrnd",
tip="Enables background subtraction in pipeline",
default_value=start_val_sub))
self.pipeline_group_box.setAlignment(Qt.AlignCenter)
self.pipeline_group_box.setObjectName("INNERCENTER")
self.good_region_group.setObjectName("INNER")
try:
start_val_grThreshold = self.settings.data["Expert"]["pipeline"][
"data"]["grThreshold"]
except KeyError as ex:
start_val_grThreshold = 21
lab_thresh, thresh = self.create_label_qdoublespinbox(
key="grThreshold", label="Threshold:",
start_val=start_val_grThreshold)
try:
start_val_grScale = self.settings.data["Expert"]["pipeline"][
"data"]["grScale"]
except KeyError as ex:
start_val_grScale = 6
lab_gfscale, gfscale = self.create_label_qspinbox(
key="grScale", label="Scale:", start_val=start_val_grScale)
layout = QGridLayout()
layout.addWidget(lab_thresh, 0, 0)
layout.addWidget(thresh, 0, 1)
layout.addWidget(lab_gfscale, 1, 0)
layout.addWidget(gfscale, 1, 1)
self.good_region_group.setLayout(layout)
self.slicing_group.setObjectName("INNER")
try:
start_val_nslices = self.settings.data["Expert"]["pipeline"][
"data"]["slices"]
except KeyError as ex:
start_val_nslices = 21
lab_slices, slices = self.create_label_qspinbox(
key="slices", label="No. Slices:", start_val=start_val_nslices)
try:
start_val_slicing_scale = self.settings.data["Expert"]["pipeline"][
"data"]["slicingScale"]
except KeyError as ex:
start_val_slicing_scale = 5
lab_scale, scale = self.create_label_qspinbox(
key="slicingScale", label="Scale:",
start_val=start_val_slicing_scale)
try:
start_val_orientation = self.settings.data["Expert"]["pipeline"][
"data"]["orientation"]
except KeyError as ex:
start_val_orientation = "vertical"
lab_orientation, self.slice_orientation = self.create_label_qcombobox(
key="orientation", label="Orientation:",
values=["vertical", "horizontal"], start_val=start_val_orientation)
layout = QGridLayout()
layout.addWidget(lab_slices, 0, 0)
layout.addWidget(slices, 0, 1)
layout.addWidget(lab_scale, 1, 0)
layout.addWidget(scale, 1, 1)
layout.addWidget(lab_orientation, 2, 0, 1, 2, Qt.AlignBottom)
layout.addWidget(self.slice_orientation, 3, 0, 1, 2,
Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignRight))
self.slicing_group.setLayout(layout)
layout_top = QGridLayout()
#layout_top.addWidget(self.create_checkbox(
# top_key="Expert", key="pipelineCtrl",
# text="Enable pipeline control from HLA",
# tip="HLA to set pipeline parameters",
# default_value=0), 0, 0, 1, 2)
layout_top.addLayout(box, 1, 0, 1, 2)
layout_top.addWidget(self.good_region_group, 2, 0, 1, 1,
Qt.AlignmentFlag(Qt.AlignHCenter|Qt.AlignTop))
layout_top.addWidget(self.slicing_group, 2, 1, 1, 1,
Qt.AlignmentFlag(Qt.AlignCenter|Qt.AlignTop))
layout_top.setHorizontalSpacing(8)
self.pipeline_group_box.setLayout(layout_top)
self.pipeline_group_box.setFixedHeight(200)
if "HLAPipelineCtrl" in self.parent.input_parameters:
self.pipeline_group_box.setEnabled(
self.parent.input_parameters["HLAPipelineCtrl"])
return self.pipeline_group_box
def checkbox_wgt(self, key: str = "", tooltip: str = "", object_name=None,
hline="NONE"):
def on_change(state):
self.input_parameters[key] = bool(state)
widget = QWidget()
layout = QGridLayout()
layout.setContentsMargins(0, 0, 0, 0)
row_wgt = 0
if hline == "TOP":
layout.addWidget(QHLine(), 0, 0, 1, 3)
row_wgt = 1
try:
text = self.settings.data["Expert"][key]["data"]["text"]
except KeyError as error:
print(("KeyError in guiframe.py; Unknown key {0} " +
"in def checkbox_wgt: {1}").format(key, error))
text = key
checkbox = QCheckBox(text)
checkbox.setToolTip(tooltip)
checkbox.setFont(self.font_gui)
if object_name:
checkbox.setObjectName(object_name)
checkbox.setLayoutDirection(Qt.LeftToRight) #is default
checkbox.stateChanged.connect(on_change)
checked_value = Qt.Unchecked
if "Expert" not in self.settings.data:
return widget
#if key in self.parent.input_parameters.keys():
if key in self.settings.data["Expert"].keys():
if "data" in self.settings.data["Expert"][key].keys():
if "value" in self.settings.data["Expert"][key]["data"].keys():
if self.settings.data["Expert"][key]["data"]["value"]:
checked_value = Qt.Checked
checkbox.setCheckState(checked_value)
layout.addWidget(checkbox, row_wgt, 0)
layout.addWidget(QFrame(), row_wgt, 1, 1, 2)
if hline == "BOTTOM":
layout.addWidget(QHLine(), row_wgt+1, 0, 1, 3)
widget.setLayout(layout)
return widget
def checkbox_rawdata(self, hline="None"):
tooltip = ("Save scanned data to separate hdf file " +
"(for later reanalysis)")
return self.checkbox_wgt(key="rawData", tooltip=tooltip, hline=hline)
def checkbox_autoRestore(self, hline="None"):
tooltip = ("Automatically restores quads to initial values before " +
"new setting or exit")
return self.checkbox_wgt(key="autoRestore", tooltip=tooltip,
hline=hline)
def checkbox_keepImages(self, hline="None"):
tooltip = ("Store plots/images on disk")
return self.checkbox_wgt(key="keepImages", tooltip=tooltip, hline=hline)
def checkbox_autoCycle(self, hline="None"):
tooltip = ("Always cycle quads when setting to new values")
return self.checkbox_wgt(key="autoCycle", tooltip=tooltip,
hline=hline)
def checkbox_debug(self, hline="None"):
tooltip = "Activates print statements in user code"
self.input_parameters["debug"] = False
return self.checkbox_wgt(key="debug", tooltip=tooltip, hline=hline)
def checkbox_simulation(self, hline="NONE"):
def on_change(state):
if bool(state):
self.parent.simulation = True
self.parent.gui_header.change_operation_mode(
user_mode=UserMode.SIMULATION)
self.parent.progressbar_color \
= self.parent.progressbar_simulation
else:
self.parent.simulation = False
self.parent.gui_header.reset_operation_mode()
self.parent.progressbar_color = self.parent.progressbar_standard
self.input_parameters["simulation"] = self.parent.simulation
widget = QWidget()
layout = QGridLayout()
layout.setContentsMargins(0, 0, 0, 0)
row_wgt = 0
if hline == "TOP":
layout.addWidget(QHLine(), 0, 0, 1, 3)
row_wgt = 1
try:
text = self.settings.data["Expert"]["simulation"]["data"]["text"]
except KeyError as error:
print("KeyError in guiframe.py; def checkbox_simulation:", error)
text = "Simulation"
self.simulation_checkbox = QCheckBox(text)
self.simulation_checkbox.setObjectName("Simulation")
self.simulation_checkbox.setToolTip(
"Dry-run only; does not write to EPICS Process Variables")
self.simulation_checkbox.setFont(self.font_gui)
self.simulation_checkbox.stateChanged.connect(on_change)
checked_value = Qt.Unchecked
if "simulation" in self.parent.input_parameters.keys():
if "data" in self.settings.data["Expert"]["simulation"].keys():
if "value" in self.settings.data["Expert"]["simulation"][
"data"].keys():
if self.settings.data["Expert"]["simulation"]["data"][
"value"]:
checked_value = Qt.Checked
self.simulation_checkbox.setCheckState(checked_value)
layout.addWidget(self.simulation_checkbox, row_wgt, 0)
layout.addWidget(QFrame(), row_wgt, 1, 1, 2)
if hline == "BOTTOM":
layout.addWidget(QHLine(), row_wgt+1, 0, 1, 3)
widget.setLayout(layout)
return widget
def get_arrow_button_widget(self, parent_idx=0):
#Back/Forward Buttons START####
arrow_button_widget = QWidget() #self.plot_widget[i])
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.setAlignment(Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignTop))
button_left = QToolButton(arrow_button_widget)
button_left.setArrowType(Qt.LeftArrow)
button_left.clicked.connect(self.on_toggle_left)
layout.addWidget(button_left)
button_right = QToolButton(arrow_button_widget)
button_right.setArrowType(Qt.RightArrow)
button_right.clicked.connect(self.on_toggle_right)
layout.addWidget(button_right)
arrow_button_widget.setLayout(layout)
self.left_arrow_dict[button_left] = parent_idx
self.right_arrow_dict[button_right] = parent_idx
layout.setAlignment(Qt.AlignTop)
arrow_button_widget.setMaximumHeight(25)
return arrow_button_widget
#Back/Forward Buttons Actions
def on_toggle_left(self): #(self, is_clicked)
#print(self.sender())
#print(self.left_arrow_dict[self.sender()])
self.next_figure(self.left_arrow_dict[self.sender()], -1)
def on_toggle_right(self): #(self, is_clicked)
#print(self.sender())
#print(self.right_arrow_dict[self.sender()])
self.next_figure(self.right_arrow_dict[self.sender()], 1)
def next_figure(self, det=0, idx=0):
if det not in self.canvas_fig_dict:
return
fig = self.canvas_fig_dict[det]
no_plots_seq = len(self.multiple_figure_dict[fig])
self.canvas_current_idx[det] = (
self.canvas_current_idx[det] + idx) % no_plots_seq
if self.canvas[det] is not None:
self.sub_results_layout[det].removeWidget(self.canvas[det])
self.canvas[det].deleteLater()
if self.nav[det] is not None:
self.sub_results_layout[det].removeWidget(self.nav[det])
self.nav[det].deleteLater()
if fig in self.multiple_figure_dict:
if self.multiple_figure_dict[fig]:
self.canvas[det] = FigureCanvasQTAgg(self.multiple_figure_dict[
fig][self.canvas_current_idx[det]])
self.sub_results_layout[det].addWidget(self.canvas[det])
self.sub_results_wgt[det].setLayout(
self.sub_results_layout[det])
self.nav[det] = NavigationToolbar(
self.canvas[det], self.sub_results_wgt[det],
coordinates=False)
self.nav[det].setMinimumWidth(400)
self.nav[det].setMinimumHeight(50)
self.nav[det].setVisible(True)
self.nav[det].setStyleSheet("QToolBar { border: 0px }")
def canvas_update(self, fig_data, idx=0):
#place figures in a list
self.parent.clear_screenshot()
self.multiple_figure_dict = fig_data
for i, key in enumerate(self.multiple_figure_dict.keys()):
self.canvas_fig_dict[i] = key
print("UPDATE", flush=True)
#print(len(self.canvas), len(self.nav), len(self.sub_results_layout),
# len(self.multiple_figure_dict.keys(), flush=True))
for i, (canvas, nav, wgt, layout, key) in enumerate(
zip(self.canvas, self.nav,
self.sub_results_wgt,
self.sub_results_layout,
self.multiple_figure_dict.keys())):
if canvas is not None:
layout.removeWidget(canvas)
canvas.deleteLater()
if nav is not None:
nav.deleteLater()
if self.multiple_figure_dict[key]: #'Figure 1']:
if not isinstance(self.multiple_figure_dict[key], list):
temp_list = []
temp_list.append(self.multiple_figure_dict[key])
self.multiple_figure_dict[key] = temp_list
self.canvas[i] = FigureCanvasQTAgg(
self.multiple_figure_dict[key][idx])
self.sub_results_layout[i].addWidget(self.canvas[i])
self.nav[i] = NavigationToolbar(
self.canvas[i], self.sub_results_wgt[i], coordinates=False)
self.nav[i].setMinimumWidth(400)
self.nav[i].setMinimumHeight(50)
#self.nav[i].setContentsMargins(0, 0, 0, 0)
self.nav[i].setVisible(True)
self.nav[i].setStyleSheet("QToolBar { border: 0px }")
self.parent.add_screenshot(title=self.results_tab_wgt_titles[i],
item=wgt)
else:
self.canvas[i] = None
self.nav[i] = None
def canvas_update_2(self, fig_data, idx=0):
#place figures in a list
#Only clear last result fro this canvas
#self.parent.clear_screenshot()
self.multiple_figure_dict_2 = fig_data
for i, key in enumerate(self.multiple_figure_dict_2.keys()):
self.canvas_fig_dict_2[i] = key
print("UPDATE==2", flush=True)
#print(len(self.canvas), len(self.nav), len(self.sub_results_layout),
# len(self.multiple_figure_dict.keys(), flush=True))
for i, (canvas, nav, wgt, layout, key) in enumerate(
zip(self.canvas_2, self.nav_2,
self.sub_results_wgt_2,
self.sub_results_layout_2,
self.multiple_figure_dict_2.keys())):
if canvas is not None:
layout.removeWidget(canvas)
canvas.deleteLater()
if nav is not None:
nav.deleteLater()
if self.multiple_figure_dict_2[key]: #'Figure 1']:
if not isinstance(self.multiple_figure_dict_2[key], list):
temp_list = []
temp_list.append(self.multiple_figure_dict_2[key])
self.multiple_figure_dict_2[key] = temp_list
self.canvas_2[i] = FigureCanvasQTAgg(
self.multiple_figure_dict_2[key][idx])
self.sub_results_layout_2[i].addWidget(self.canvas_2[i])
self.nav_2[i] = NavigationToolbar(
self.canvas_2[i], self.sub_results_wgt_2[i],
coordinates=False)
self.nav_2[i].setMinimumWidth(400)
self.nav_2[i].setMinimumHeight(50)
#self.nav[i].setContentsMargins(0, 0, 0, 0)
self.nav_2[i].setVisible(True)
self.nav_2[i].setStyleSheet("QToolBar { border: 0px }")
self.parent.clear_screenshot(self.results_tab_wgt_titles_2[i],
wgt)
self.parent.add_screenshot(
title=self.results_tab_wgt_titles_2[i], item=wgt)
else:
self.canvas_2[i] = None
self.nav_2[i] = None
def prepare_qlineread(self, line, value):
line.setObjectName("Read")
line.setFixedHeight(24)
line.setText(str(value))
line.setAlignment(Qt.AlignmentFlag(Qt.AlignRight|Qt.AlignBottom))
line.setStyleSheet("QLabel{text-align: right}")
fm = QFontMetricsF(line.font())
param_width = fm.maxWidth() * (len(str(value))*0.5) + 20
line.setMaximumWidth(int(param_width))
def prepare_qlineedit(self, line, value, link, title, key):
has_min = False
has_max = False
is_float = False
is_int = False
no_decimals = 0
try:
min_val = self.settings.data[link][title][key]["data"]["min"]
has_min = True
if isinstance(min_val, float):
is_float = True
d = abs(Decimal(str(min_val)).as_tuple().exponent)
no_decimals = max(no_decimals, d)
elif isinstance(min_val, int):
is_int = True
except KeyError:
pass
try:
max_val = self.settings.data[link][title][key]["data"]["max"]
has_max = True
if isinstance(max_val, float):
is_float = True
d = abs(Decimal(str(max_val)).as_tuple().exponent)
no_decimals = max(no_decimals, d)
elif isinstance(max_val, int):
is_int = True
except KeyError:
pass
validator = None
#QDoubleValidate only controls the number of digits
if is_float:
validator = QDoubleValidator()
validator.setNotation(QDoubleValidator.StandardNotation)
validator.setDecimals(no_decimals)
elif is_int:
validator = QIntValidator()
if validator:
validator_str = "Valid range "
if has_min:
validator.setBottom(min_val)
validator_str += "from {} ".format(min_val)
if has_max:
validator.setTop(max_val)
validator_str += "to {}".format(max_val)
line.setToolTip(validator_str)
line.setValidator(validator)
line.setObjectName("Write")
line.setFixedHeight(24)
line.setText(str(value))
fm = QFontMetricsF(line.font())
param_width = fm.maxWidth() * (len(str(value))*0.5) + 20
line.setMaximumWidth(int(param_width))
return line
def prepare_qspinbox(self, line, value, link, title, key):
min_val = self.settings.data[link][title][key]["data"]["min"]
max_val = self.settings.data[link][title][key]["data"]["max"]
step = self.settings.data[link][title][key]["data"]["step"]
line.setObjectName("Write")
line.setFixedHeight(24)
line.setRange(min_val, max_val)
line.setSingleStep(step)
line.setValue(value)
line.setAlignment(Qt.AlignRight) #required
fm = QFontMetricsF(line.font())
param_width = fm.maxWidth() * (len(str(max_val)) + 0.2)
line.setMaximumWidth(int(param_width))
return line
def prepare_qdoublespinbox(self, line, value, link, title, key):
min_val = self.settings.data[link][title][key]["data"]["min"]
max_val = self.settings.data[link][title][key]["data"]["max"]
step = self.settings.data[link][title][key]["data"]["step"]
line.setObjectName("Write")
line.setFixedHeight(24)
decimal = Decimal(str(step))
line.setDecimals(abs(decimal.as_tuple().exponent)) #precision
line.setRange(min_val, max_val)
line.setSingleStep(step)
line.setValue(value)
line.setAlignment(Qt.AlignRight) #required
fm = QFontMetricsF(line.font())
param_width = fm.maxWidth() * (len(str(max_val)))
line.setMaximumWidth(int(param_width))
return line
def prepare_qcombobox(self, line, value, link, title, key):
line.clear()
line.addItems(value)
line.setFixedHeight(26)
line.setObjectName("Write")
value_for_width = max(value, key=len)
fm = QFontMetricsF(line.font())
param_width = fm.maxWidth() * (len(str(value_for_width)) * 0.5)
line.setFixedWidth(int(param_width))
return line
def prepare_qcheckbox(self, line, value, link, title, key):
line.setChecked(Qt.Checked if value else Qt.Unchecked)
line.setMaximumWidth(320)
line.setMinimumWidth(100)
line.setFixedHeight(28)
try:
orientation = self.settings.data[link][title][key]["data"][
"orientation"]
orientation = Qt.RightToLeft if "RightToLeft" in orientation \
else Qt.LeftToRight
line.setLayoutDirection(orientation)
except KeyError as ex:
print(ex, flush=True)
pass
return line
def prepare_qradiobutton(self, value, link, title, key):
widget = QWidget()
layout = QGridLayout()
layout.setContentsMargins(5, 0, 5, 20)
widget.setMaximumWidth(int(len(value)*100))
target_list = value
color_list = ["#894961", "teal", "darkblue"]
width_list = [70, 70, 70]
self.radiobutton = [None] * len(target_list)
for i, name in enumerate(target_list):
self.radiobutton[i] = QRadioButton(name)
full_width = len(target_list) + 1
layout.addWidget(QHLine(), 0, 0, 1, full_width)
layout.addWidget(QLabel(
self.settings.data[link][title][key]['data']['text']), 1, 0, 1,
full_width, Qt.AlignCenter)
for i, (radio, target, color, width) in enumerate(
zip(self.radiobutton, target_list, color_list, width_list)):
radio.setFont(self.font_pts10)
radio.setStyleSheet("color : {0};".format(color))
radio.val = target
radio.title = title
radio.key = key
layout.addWidget(radio, 2, i, 1, 1, Qt.AlignCenter)
layout.addWidget(QHLine(), 3, 0, 1, layout.columnCount())
layout.setSpacing(0)
widget.setLayout(layout)
return widget
'''
line.setContentsMargins(0, 0, 0, 0)
rblist = line.findChildren(QRadioButton)
for rb in rblist:
rb.toggled.connect(on_radiobutton_change)
wgt_grid.addWidget(line, irow, 0, 1, 4, Qt.AlignLeft)
_idx=0
try:
if key in self.settings.data["Expert"].keys():
top_key = "Expert"
elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
_choice =self.settings.data[top_key][key]['data']['default']
_values = self.settings.data[top_key][key]['data']['value']
if isinstance(_choice, (str, bytes)):
_idx = _values.index(_choice)
elif isinstance(_choice, int):
_idx = _choice if _choice < len(_values) else 0
except KeyError:
pass
rblist[_idx].setChecked(True)
rblist[_idx].toggled.emit(True)
return line
'''
def qtab_wgt(self, key, irow, wgt_grid, stacked=False):
if key in self.settings.data["Expert"].keys():
top_key = "Expert"
elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
def emboss():
line.title = title
line.key = inner_key
line.val = value
def check_cb(new_value):
sender= self.sender()
self.parent.input_parameters[sender.title][sender.key] = new_value
def line_cb(new_value):
sender= self.sender()
self.parent.input_parameters[sender.title][sender.key] = new_value
def on_radiobutton_change(new_value):
sender = self.sender()
#print("rb callback ", new_value, sender.isChecked(), sender.val, flush=True)
if sender.isChecked():
self.parent.input_parameters[sender.title][sender.key] = sender.val
def on_tab_change(new_idx):
sender_tab = self.sender().qtab_widget_dict[new_idx].title
meas_line.setText(sender_tab)
try:
_color = self.settings.data[top_key][key]["data"]["color"][
new_idx]
except KeyError as ex:
_color = "black"
except IndexError as ex:
_color = "black"
meas_line.setStyleSheet("color: {0}".format(_color))
for i in range (0, self.sender().count()):
if i == new_idx:
try:
self.sender().tabBar().setTabTextColor(new_idx,
QColor(_color))
except AttributeError:
#May be a QStackedWidget which does not have tabBar
pass
else:
try:
self.sender().tabBar().setTabTextColor(i,
QColor("black"))
except AttributeError:
#May be a QStackedWidget which does not have tabBar
pass
self.parent.input_parameters[key] = sender_tab
qtab_widget = QTabWidget() if not stacked else QStackedWidget()
qtab_widget_dict = {}
itab = 0
longest_title = "short"
link = self.settings.data[top_key][key]["data"]["link"]
for title, tab in self.settings.data[link].items():
lo = QGridLayout()
qw = QWidget()
_irow = 0
_irowspan = 1
tab_height = 0
if len(title) > len(longest_title):
longest_title = title
self.parent.input_parameters[title] = {}
for inner_key, param in tab.items():
tab_height +=32
wgt_type = param["data"]["widget"]
text = param["data"]["text"]
if "value" in param["data"]:
value = param["data"]["value"]
elif "link" in param["data"]:
link_list = param["data"]["link"]
if len(link_list) == 1:
value = self.settings.data[link_list[0]]
print("values", value, flush=True)
else:
bottom_leaf = self.settings.data[link_list[0]]
for link_item in link_list[1:]:
bottom_leaf = bottom_leaf[link_item]
value = bottom_leaf
label = None
def add_label():
label = QLabel(text)
label.setFixedHeight(24)
label.setFont(self.font_pts10)
label.setContentsMargins(0, 0, 0, 0)
return label
if "QSpinBox" in wgt_type:
line = QSpinBox()
label = add_label()
emboss()
self.prepare_qspinbox(line, value, link, title, inner_key)
line.valueChanged.connect(line_cb)
line.valueChanged.emit(value)
elif "QDoubleSpinBox" in wgt_type:
line = QDoubleSpinBox()
label = add_label()
emboss()
self.prepare_qdoublespinbox(line, value, link, title,
inner_key)
line.valueChanged.connect(line_cb)
line.valueChanged.emit(value)
elif "QLineEdit" in wgt_type:
line = QLineEdit()
label = add_label()
emboss()
self.prepare_qlineedit(line, value, link, title, inner_key)
line.textEdited.connect(line_cb)
line.textEdited.emit(str(value))
elif "QLineRead" in wgt_type:
line = QLineEdit()
label = add_label()
emboss()
self.prepare_qlineread(line, value)
line.textEdited.connect(line_cb)
line.textEdited.emit(str(value))
elif "QCheckBox" in wgt_type:
line = QCheckBox(text)
emboss()
self.prepare_qcheckbox(line, value, link, title, inner_key)
line.stateChanged.connect(check_cb)
line.stateChanged.emit(bool(value))
elif "QComboBox" in wgt_type:
line = QComboBox()
label = add_label()
emboss()
self.prepare_qcombobox(line, value, link, title, inner_key)
line.currentTextChanged.connect(line_cb)
line.setCurrentIndex(0)
line.currentTextChanged.emit(value[0])
elif "QRadioButton" in wgt_type:
tab_height += 32
_irowspan = 2
line = self.prepare_qradiobutton(value, link, title,
inner_key)
#emboss()
rblist = line.findChildren(QRadioButton)
for rb in rblist:
rb.toggled.connect(on_radiobutton_change)
if "startIdx" in param["data"]:
start_idx = param["data"]["startIdx"]
else:
start_idx = 0
rblist[start_idx].setChecked(True)
rblist[start_idx].toggled.emit(True)
icol = 0
icolspan = 3
if label:
lo.addWidget(label, _irow, icol, _irowspan, 1,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
icol += 1
lo.addWidget(line, _irow, icol, _irowspan, icolspan,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
#print(title, tab)
#print(key, line, icolumn, wgt_type, text, flush=True)
_irow += 1
qw.setLayout(lo)
qw.setFixedHeight(tab_height)
qtab_widget_dict[itab] = qw
qtab_widget_dict[itab].title = title
if not stacked:
qtab_widget.addTab(qtab_widget_dict[itab], title)
else:
qtab_widget.addWidget(qtab_widget_dict[itab])
itab += 1
qtab_widget.qtab_widget_dict = qtab_widget_dict
meas_label = QLabel()
meas_label.setFixedHeight(24)
meas_label.setFont(self.font_pts10)
meas_label.setContentsMargins(0, 0, 0, 0)
meas_label.setText(self.settings.data[top_key][key]["data"]["text"])
meas_line = QLineEdit()
meas_line.setObjectName("Read")
fm = QFontMetricsF(meas_line.font())
param_width = fm.maxWidth() * len(longest_title)
meas_line.setMaximumWidth(int(param_width*0.5))
qtab_widget.setContentsMargins(0, 0, 0, 0)
qtab_widget.currentChanged.connect(on_tab_change)
_default_idx = self.settings.data[top_key][key]["data"]["value"]
qtab_widget.setCurrentIndex(_default_idx)
qtab_widget.currentChanged.emit(_default_idx)
final_wgt = QWidget()
final_lo = QGridLayout()
final_wgt.setContentsMargins(0, 0, 0, 0) #0, 40, 0, 0
final_lo.addWidget(meas_label, 0, 0, 1, 2,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
final_lo.addWidget(meas_line, 0, 2, 1, 2,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
qHLine = QHLine()
qHLine.setFixedHeight(10)
final_lo.addWidget(qHLine, 1, 0, 1, 4)
final_lo.addWidget(qtab_widget, 2, 0, 1, 4,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
final_wgt.setLayout(final_lo)
return final_wgt, qtab_widget #
def pv_stacked_wgt(self, pvlist, title, default_value, key, object_name):
"""GUI Input Widget"""
stacked_widget = QStackedWidget()
self.cafe.openPrepare()
self.cafe.open(pvlist)
self.cafe.openNowAndWait(0.4)
for pv in pvlist:
self.cafe.setGetActionWhenMonitorPolicy(
pv, self.cyca.GET_FROM_CACHE)
stack_list = []
for pv, head, val, obj in zip(pvlist, title, default_value,
object_name):
stack, radiobutton_list = self.pv_selector_wgt(
title=head, key=key, pv=pv, manual_value=val)
self.stack_radiolist_dict[stack] = radiobutton_list
stack_list.append(stack)
stack.setObjectName(obj)
stack.style().polish(stack)
stacked_widget.addWidget(stack)
stacked_widget.setMaximumHeight(320)
self.stacked_wgt_dict[stacked_widget] = stack_list
return stacked_widget
def pv_energy_stacked_wgt(self):
pvlist = self.settings.data["EnergyStackedWgt"]["pvlist"]
title = self.settings.data["EnergyStackedWgt"]["title"]
default_value = self.settings.data["EnergyStackedWgt"]["value"]
key = self.settings.data["EnergyStackedWgt"]["key"]
object_name = self.settings.data["EnergyStackedWgt"]["objectName"]
self.energy_stacked_widget = self.pv_stacked_wgt(
pvlist, title, default_value, key, object_name)
radio_list = self.stack_radiolist_dict[
self.energy_stacked_widget.currentWidget()]
for radio in radio_list:
if radio.isChecked():
radio.toggled.emit(True)
return self.energy_stacked_widget
def pv_phase_stacked_wgt(self):
pvlist = self.settings.data["PhaseStackedWgt"]["pvlist"]
title = self.settings.data["PhaseStackedWgt"]["title"]
default_value = self.settings.data["PhaseStackedWgt"]["value"]
key = self.settings.data["PhaseStackedWgt"]["key"]
object_name = self.settings.data["PhaseStackedWgt"]["objectName"]
self.phase_stacked_widget = self.pv_stacked_wgt(
pvlist, title, default_value, key, object_name)
radio_list = self.stack_radiolist_dict[
self.phase_stacked_widget.currentWidget()]
for radio in radio_list:
if radio.isChecked():
radio.toggled.emit(True)
return self.phase_stacked_widget
def pv_selector_wgt(self, title="Select", key="beamEnergy", pv=None,
manual_value="", monitor=True, read=True, manual=True):
group_box = QGroupBox(title)
group_box.setObjectName("INNERCENTER")
grid = QGridLayout()
radio_buddy_text_dict = {}
radiobutton_title = ["Monitor", "Update", "Manual"]
radiobutton_flag = [monitor, read, manual]
radiobutton_list = [None] * len(radiobutton_title)
pv_local = pv
monitor_pv = None
def cb_pv_selector(value):
value_str = radio_buddy_text_dict[self.sender()].text()
#print("cb_pv_selector", value_str)
#Find which group the radio button belongs to:
#Find which stack the group belongs to:
#Set this to the current stack?
for k, v in self.stack_radiolist_dict.items():
if self.sender() in v:
#get groupbox from key
for k2, v2 in self.stacked_wgt_dict.items():
if k in v2:
self.current_stacked_wgt_dict[k2] = pv_local #self.sender()
#print("Current STACK FOUND")
self.radio_stack_dict[self.sender()] = value
if not value_str:
print("Fired on Initialization when not connected", value)
print("sender", self.sender())
print("radio_buddy_text", radio_buddy_text_dict)
print("value", radio_buddy_text_dict[self.sender()].text())
self.input_parameters[key] = 0
return
if hasattr(radio_buddy_text_dict[self.sender()], "pv_info"):
dt = radio_buddy_text_dict[self.sender()].pv_info.dataType
if dt not in [self.cyca.CY_DBR_STRING, self.cyca.CY_DBR_ENUM,
self.cyca.CY_DBR_CHAR]:
value_input = re.findall(r"-?\d+\.?\d*", value_str)
if dt in [self.cyca.CY_DBR_FLOAT, self.cyca.CY_DBR_DOUBLE]:
self.input_parameters[key] = float(value_input[0])
elif dt in [self.cyca.CY_DBR_SHORT, self.cyca.CY_DBR_LONG]:
self.input_parameters[key] = int(value_input[0])
else:
self.input_parameters[key] = value_str
else:
self.input_parameters[key] = value_str
for irow, (radio, flag) in enumerate(zip(radiobutton_list,
radiobutton_flag)):
radio = QRadioButton("")
radio.toggled.connect(cb_pv_selector)
radio.setFont(self.font_pts10)
radio.setFixedWidth(15)
radiobutton_list[irow] = radio
if flag:
grid.addWidget(radio, irow, 0)
if monitor:
ql = QLabel(radiobutton_title[0])
ql.setFont(self.font_pts10)
ql.setFixedHeight(self.widget_height)
ql.setAlignment(Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
grid.addWidget(ql, 0, 1)
if manual:
ql = QLabel(radiobutton_title[2])
ql.setFont(self.font_pts10)
ql.setFixedHeight(self.widget_height)
ql.setAlignment(Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
grid.addWidget(ql, 2, 1)
def mon_cb(handle, pvname, pvdata):
if monitor_pv is not None:
monitor_pv.py_monitor_callback(handle, pvname, pvdata)
if pvname in self.current_stacked_wgt_dict.values() and \
radiobutton_list[0].isChecked(): #
self.input_parameters[key] = pvdata.value[0]
if monitor:
monitor_pv = CAQLabel(self, pv_name=pv, monitor_callback=mon_cb,
show_units=True)
monitor_pv.setAlignment(
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
monitor_pv.setFont(self.font_pts10)
monitor_pv.setFixedHeight(self.widget_height)
monitor_pv.setFixedWidth(122)
grid.addWidget(monitor_pv, 0, 2, 1, 2)
if read:
read_pv = CAQLabel(self, pv_name=pv, pv_within_daq_group=True,
color_mode="static", show_units=True)
read_pv.setAlignment(Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
read_pv.setFont(self.font_pts10)
init_value = self.cafe.getCache(pv)
if init_value is not None:
val = read_pv.format_display_value(init_value)
read_pv.setText(str(val))
read_pv.setFixedHeight(self.widget_height)
read_pv.setFixedWidth(122)
grid.addWidget(read_pv, 1, 2, 1, 2)
def update_read_value():
#print("sender = ", self.sender())
pvdata = self.cafe.getPV(pv)
init_value = pvdata.value[0]
if init_value is not None:
#value_str = read_pv.format_display_value(init_value)
#read_pv.setText(str(value_str))
#print(len(read_pv.text()))
#val = re.findall(r'-?\d+\.?\d*', value_str)
#print (val)
#val[0] = val[0] #add space that we stripped off
read_pv.receive_monitor_update(init_value, pvdata.status,
pvdata.alarmSeverity)
if radiobutton_list[1].isChecked():
radiobutton_list[1].toggled.emit(True)
if read:
qpb = QPushButton(radiobutton_title[1])
qpb.setObjectName("Update")
qpb.pressed.connect(update_read_value)
qpb.setFixedHeight(self.widget_height)
qpb.setFixedWidth(60)
grid.addWidget(qpb, 1, 1)
qpb.pressed.emit()
def update_manual_value(new_text):
if radiobutton_list[2].isChecked():
radiobutton_list[2].toggled.emit(True)
if manual:
manual_wgt = QLineEdit(str(manual_value))
manual_wgt.setObjectName("WriteCenter")
manual_wgt.textChanged.connect(update_manual_value)
manual_wgt.setAlignment(
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
manual_wgt.setFixedHeight(self.widget_height)
manual_wgt.setFixedWidth(74)
grid.addWidget(manual_wgt, 2, 2)
ql = QLabel(self.cafe.getUnits(pv))
ql.setFont(self.font_pts10)
ql.setFixedHeight(self.widget_height)
ql.setAlignment(Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
grid.addWidget(ql, 2, 3)
grid.setContentsMargins(5, 10, 5, 0)
#grid.setContentsMargins(9, 15, 9, 0)
grid.setAlignment(Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
grid.setVerticalSpacing(2)
grid.setHorizontalSpacing(4)
group_box.setContentsMargins(0, 0, 0, 0)
group_box.setMaximumWidth(280)
group_box.setMaximumHeight(320)
group_box.setFont(self.font_pts10)
group_box.setAlignment(Qt.AlignmentFlag(Qt.AlignTop|Qt.AlignHCenter))
group_box.setLayout(grid)
if monitor:
radio_buddy_text_dict[radiobutton_list[0]] = monitor_pv
if read:
radio_buddy_text_dict[radiobutton_list[1]] = read_pv
if manual:
radio_buddy_text_dict[radiobutton_list[2]] = manual_wgt
idx = 0 #1 if read else 0
#print("idx", idx)
#print(radio_buddy_text_dict)
radiobutton_list[idx].setChecked(True)
radiobutton_list[idx].toggled.emit(True)
return group_box, radiobutton_list
def input_wgt_logging(self, irow, wgt_grid):
tooltip = "Select logging level, CRITICAL=50, DEBUG=10"
value = ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'] #NOTSET=0
label = QLabel("Logging level:")
label.setFixedHeight(24)
label.setFont(self.font_pts10)
label.setContentsMargins(5, 0, 0, 0)
label.setToolTip(tooltip)
return self.input_wgt_qcombobox(label, "loggingLevel", value, irow,
wgt_grid)
def input_wgt_qcombobox(self, label, key, value, irow, wgt_grid):
suggested = "WW"
if key in self.settings.data["Expert"].keys():
top_key = "Expert"
elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
else:
top_key = "Expert"
def combo_cb(new_text):
self.input_parameters[key] = new_text
if 'loggingLevel' in key:
self.parent.logger.setLevel(new_text)
line = QComboBox()
line.clear()
line.addItems(value)
line.setFixedHeight(26)
line.currentTextChanged.connect(combo_cb)
line.setCurrentIndex(2)
line.currentTextChanged.emit(value[2])
value_for_width = max(value, key=len)
fm = QFontMetricsF(line.font())
param_width = max(fm.width(str(value_for_width)), fm.width(suggested))
line.setFixedWidth(int(param_width + 56))
line.setObjectName("Write")
if key in self.settings.data[top_key]:
if "layout" in self.settings.data[top_key][key]['data']:
if "VERT" in self.settings.data[top_key][key]['data'][
'layout'].upper():
box = QVBoxLayout()
label.setAlignment(Qt.AlignBottom)
else:
box = QHBoxLayout()
label.setAlignment(Qt.AlignCenter)
else:
box = QVBoxLayout()
label.setAlignment(Qt.AlignBottom)
else:
box = QHBoxLayout()
label.setAlignment(Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
box.setAlignment(Qt.AlignCenter)
box.addWidget(label)
box.addWidget(line)
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 3
if 'loggingLevel' not in key:
wgt_grid.addLayout(box, a, b, c, d,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
return box if 'loggingLevel' in key else line
def input_wgt_qradiobutton(self, key, value, irow, wgt_grid):
def on_radiobutton_change(new_value):
radio_button = self.sender()
if radio_button.isChecked():
self.parent.input_parameters[key] = radio_button.target
#print("KEY================", key, self.parent.input_parameters[key], new_value)
if key in self.settings.data["Expert"].keys():
top_key = "Expert"
elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
if 'forwardLink' in self.settings.data[top_key][key]['data']:
link = self.settings.data[top_key][key]['data'][
'forwardLink'][0]
for item in self.settings.data[link][radio_button.target]:
value_list = self.settings.data[link][radio_button.target][
item]
if item in self.line_sender_dict:
if self.settings.data[top_key][item]['data'][
'widget'] in 'QComboBox':
self.line_sender_dict[item].clear()
self.line_sender_dict[item].addItems(value_list)
self.line_sender_dict[item].setCurrentIndex(0)
self.line_sender_dict[item].currentTextChanged.emit(
value_list[0])
elif self.settings.data[top_key][item]['data'][
'widget'] in 'QLineEdit':
self.line_sender_dict[item].setText(str(value_list))
line = self.radio_buttons(key=key, options=value)
line.setContentsMargins(0, 0, 0, 0)
rblist = line.findChildren(QRadioButton)
for rb in rblist:
rb.toggled.connect(on_radiobutton_change)
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 4
wgt_grid.addWidget(line, a, b, c, d, Qt.AlignLeft)
_idx=0
try:
if key in self.settings.data["Expert"].keys():
top_key = "Expert"
elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
_choice =self.settings.data[top_key][key]['data']['default']
_values = self.settings.data[top_key][key]['data']['value']
if isinstance(_choice, (str, bytes)):
_idx = _values.index(_choice)
elif isinstance(_choice, int):
_idx = _choice if _choice < len(_values) else 0
except KeyError:
pass
rblist[_idx].setChecked(True)
rblist[_idx].toggled.emit(True)
return line
def input_wgt_qcheckbox(self, key, value, label_text, irow, wgt_grid):
def check_cb(new_value):
self.parent.input_parameters[key] = bool(new_value)
#print("check_cbp", key, new_value, flush=True)
if key == "HLAPipelineCtrl":
if self.pipeline_group_box is not None:
self.pipeline_group_box.setEnabled(bool(new_value))
line = QCheckBox(label_text)
line.stateChanged.connect(check_cb)
#line.toggled.connect(check_cb)
line.setChecked(Qt.Checked if value else Qt.Unchecked)
line.setMaximumWidth(320)
line.setMinimumWidth(100)
line.setFixedHeight(28)
if key in self.settings.data["Expert"].keys():
top_key = "Expert"
elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
col_wdt = 4
try:
orientation = self.settings.data[top_key][key]["data"][
"orientation"]
orientation = Qt.RightToLeft if "RightToLeft" in orientation \
else Qt.LeftToRight
line.setLayoutDirection(orientation)
col_wdt=3
except KeyError:
pass
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = col_wdt
wgt_grid.addWidget(line, a, b, c, d, Qt.AlignLeft | Qt.AlignVCenter)
#line.stateChanged.emit(Qt.Checked if value else Qt.Unchecked)
return line
def input_wgt_qlabel(self, value, irow, wgt_grid):
#Read only has no callback
suggested = "WWWW"
line = QLabel()
line.setText(str(value)) #"{0: 3.1f}".format(value))
line.setFixedHeight(24)
line.setAlignment(Qt.AlignmentFlag(Qt.AlignRight|Qt.AlignBottom))
line.setStyleSheet("QLabel{text-align: right}")
fm = QFontMetricsF(line.font())
param_width = max(fm.width(str(value)), fm.width(suggested))
line.setMaximumWidth(int(param_width + 40))
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 4
wgt_grid.addWidget(line, a, b, c, d)
return line
def input_wgt_qlineread(self, key, value, label, irow, wgt_grid):
def line_cb(new_value):
self.parent.input_parameters[key] = new_value
#print("NEW VALUE FROM BASE GUI FRAME", new_value)
suggested = "WW"
line = QLineEdit()
line.setObjectName("Read")
line.setText(str(value)) #"{0: 3.1f}".format(value))
line.setFixedHeight(26)
line.textChanged.connect(line_cb)
#line.textEdited.connect(line_cb)
line.textChanged.emit(str(value))
line.setAlignment(Qt.AlignmentFlag(Qt.AlignRight|Qt.AlignBottom))
line.setStyleSheet("QLabel{text-align: right}")
try:
w =self.settings.data["Parameters"][key]["data"]["width"]
line.setFixedWidth(w)
except KeyError:
fm = QFontMetricsF(line.font())
param_width = max(fm.width(str(value)), fm.width(suggested))
extra_width = 22 if len(str(value)) < 16 else 26
line.setFixedWidth(int(param_width + extra_width))
qframe_buffer = QFrame()
qframe_buffer.setFixedWidth(3)
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 1
wgt_grid.addWidget(label, a, b, c, d,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
wgt_grid.addWidget(qframe_buffer, a, b+1, c, d,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
wgt_grid.addWidget(line, a, b+2, c, d,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
return line
def input_wgt_qlineedit(self, key, value, label, irow, wgt_grid):
def line_cb(new_value):
self.parent.input_parameters[key] = new_value
line = QLineEdit()
line.setObjectName("Write")
line.setFixedHeight(24)
line.textEdited.connect(line_cb)
line.setText(str(value))
fm = QFontMetricsF(line.font())
param_width = fm.width(str(value))
extra_width = 22 if len(str(value)) < 16 else 26
line.setFixedWidth(int(param_width + extra_width))
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 2
wgt_grid.addWidget(label, a, b, c, d,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
wgt_grid.addWidget(line, a, b+2, c, d,
Qt.AlignmentFlag(Qt.AlignLeft|Qt.AlignVCenter))
return line
def input_wgt_qdoublespinbox(self, key, value, label, irow, wgt_grid):
def line_cb(new_value):
self.parent.input_parameters[key] = new_value
suggested = "WWWW"
line = QDoubleSpinBox()
line.setObjectName("Write")
line.setFixedHeight(24)
line.valueChanged.connect(line_cb)
line.setValue(value)
if key in self.settings.data["Expert"].keys():
top_key = "Expert"
elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
min_val = self.settings.data[top_key][key]["data"]["min"]
max_val = self.settings.data[top_key][key]["data"]["max"]
step = self.settings.data[top_key][key]["data"]["step"]
try:
if 'tooltip' in self.settings.data[top_key][key]["data"]:
label.setToolTip(self.settings.data[top_key][key]["data"][
"tooltip"])
except KeyError:
pass
decimal = Decimal(str(step))
line.setDecimals(abs(decimal.as_tuple().exponent)) #precision
line.setRange(min_val, max_val)
line.setSingleStep(step)
fm = QFontMetricsF(line.font())
param_width = max(fm.width(str(decimal)), fm.width(suggested))
line.setMaximumWidth(int(param_width + 40))
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 2
wgt_grid.addWidget(label, a, b, c, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
wgt_grid.addWidget(line, a, b+2, c, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
return line
def input_wgt_qspinbox(self, key, value, label, irow, wgt_grid):
def line_cb(new_value):
self.parent.input_parameters[key] = new_value
suggested = "WWWW"
line = QSpinBox()
line.setObjectName("Write")
line.setFixedHeight(24)
line.valueChanged.connect(line_cb)
line.setValue(value)
if key in self.settings.data["Expert"].keys():
top_key = "Expert"
elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
min_val = self.settings.data[top_key][key]["data"]["min"]
max_val = self.settings.data[top_key][key]["data"]["max"]
step = self.settings.data[top_key][key]["data"]["step"]
line.setRange(min_val, max_val)
line.setSingleStep(step)
fm = QFontMetricsF(line.font())
param_width = max(fm.width(str(max_val)), fm.width(suggested))
line.setMaximumWidth(int(param_width + 40))
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 2
wgt_grid.addWidget(label, a, b, c, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
wgt_grid.addWidget(line, a, b+2, c, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
return line
def input_wgt_qenergystacked(self, irow, wgt_grid):
qframe_top = QFrame()
qframe_top.setFixedHeight(3)
stacked_wgt = self.pv_energy_stacked_wgt()
qframe_bottom = QFrame()
qframe_bottom.setFixedHeight(3)
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 4
wgt_grid.addWidget(qframe_top, a, b, c, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
wgt_grid.addWidget(stacked_wgt, a+1, b, c+3, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
wgt_grid.addWidget(qframe_bottom, a+2, b, c, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
return stacked_wgt
def input_wgt_qphasestacked(self, irow, wgt_grid):
qframe_top = QFrame()
qframe_top.setFixedHeight(3)
stacked_wgt = self.pv_phase_stacked_wgt()
qframe_bottom = QFrame()
qframe_bottom.setFixedHeight(3)
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 4
wgt_grid.addWidget(qframe_top, a, b, c, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
wgt_grid.addWidget(stacked_wgt, a+1, b, c+3, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
wgt_grid.addWidget(qframe_bottom, a+2, b, c, d,
Qt.AlignmentFlag(Qt.AlignLeft | Qt.AlignVCenter))
return stacked_wgt
def input_wgt_qhline(self, irow, wgt_grid):
qHLine = QHLine()
qHLine.setFixedHeight(10)
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 4
wgt_grid.addWidget(qHLine, a, b, c, d)
def input_wgt_qvline(self, irow, wgt_grid):
qVLine = QVLine()
qVLine.setFixedWidth(20)
qVLine.setFixedHeight(int(17 * wgt_grid.rowCount()))
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 4
wgt_grid.addWidget(qVLine, a, b, c, d)
def input_wgt_frame(self, irow, wgt_grid):
qFrame = QFrame()
qFrame.setFixedHeight(10)
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 4
wgt_grid.addWidget(qHLine, a, b, c, d)
def input_wgt(self, buddy, label, key, value, irow=0, wgt_grid=None,):
if wgt_grid is None:
wgt_grid = self.input_wgt_grid
label_text = label
label = QLabel(label_text if buddy != "QCheckBox".upper() else "")
label.setFixedHeight(24)
label.setFont(self.font_pts10)
label.setContentsMargins(5, 0, 0, 0)
line = None
qtab = None
#Add callbacksand actions
if buddy == "QComboBox".upper():
line = self.input_wgt_qcombobox(label, key, value, irow, wgt_grid)
elif buddy == "QRadioButton".upper():
line = self.input_wgt_qradiobutton(key, value, irow, wgt_grid)
elif buddy == "QCheckBox".upper():
line = self.input_wgt_qcheckbox(key, value, label_text, irow,
wgt_grid)
elif buddy == "QLabel".upper():
line = self.input_wgt_qlabel(value, irow, wgt_grid)
elif buddy == "QLineRead".upper():
line = self.input_wgt_qlineread(key, value, label, irow, wgt_grid)
elif buddy == "QDoubleSpinBox".upper():
line = self.input_wgt_qdoublespinbox(key, value, label, irow,
wgt_grid)
elif buddy == "QSpinBox".upper():
line = self.input_wgt_qspinbox(key, value, label, irow, wgt_grid)
elif buddy == "QPhaseStackedWidget".upper():
line = self.input_wgt_qphasestacked(irow, wgt_grid)
elif buddy == "QEnergyStackedWidget".upper():
line = self.input_wgt_qenergystacked(irow, wgt_grid)
elif buddy == "QLineEdit".upper():
line = self.input_wgt_qlineedit(key, value, label, irow, wgt_grid)
elif buddy == "QHLine".upper():
self.input_wgt_qhline(irow, wgt_grid)
elif buddy == "QVLine".upper():
self.input_wgt_qvline(irow, wgt_grid)
elif buddy == "QFrame".upper():
self.input_wgt_qframe(irow, wgt_grid)
elif buddy == "QTabWidget".upper():
#print("buddy/label", buddy, label, key, value, flush=True)
line, qtab = self.qtab_wgt(key, irow, wgt_grid)
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 4
wgt_grid.addWidget(line, a, b, c, d,
Qt.AlignLeft | Qt.AlignVCenter)
elif buddy == "QStackedWidget".upper():
#print("buddy/label", buddy, label, key, value, flush=True)
line, qtab = self.qtab_wgt(key, irow, wgt_grid, stacked=True)
if self.grid_loc:
a = self.grid_loc[0]
b = self.grid_loc[1]
c = self.grid_loc[2]
d = self.grid_loc[3]
else:
a = irow
b = 0
c = 1
d = 4
wgt_grid.addWidget(line, a, b, c, d,
Qt.AlignLeft | Qt.AlignVCenter)
else:
wgt_list = ["QCheckBox", "QComboBox", "QDoubleSpinBox", "QFrame",
"QHLine", "QLabel", "QLineEdit", "QLineRead",
"QRadioButton", "QSpinBox", "QStackedWiodget",
"QTabWidget","QVLine", "QPhaseStackedWidget",
"QEnergyStackedWidget"]
print("Widget {0} is not Supported".format(buddy))
print("Supported widgets are: {0}".format(wgt_list))
pass
if qtab is not None:
self.line_sender_dict[key] = qtab
elif line is not None:
self.line_sender_dict[key] = line
def enter_input_parameters(self):
#"undulator": {"flag": 0, "data" :
#{"widget": "None", "text" : "Target:", "value" : "Aramis"}},
#"deflector": {"flag": 1, "data" :
#{"widget": "QComboBox", "text" : "RF Tranverse Deflector:",
# "forwardLink": ["RFDeflector"]}},
#profileMonitor": {"flag": 1, "data" :
#{"widget": "QComboBox", "text" : "Profile Monitor:",
# "link": ["RFDeflector", "SINDI01", "profileMonitor"]
#json input "Parameters" key
# All key values added to self.input_parameters
#flag 1: add to self.input_parameters for analysis thread
#widget None: does not add widget into container
#text: Will add label to a widget
#forwardLink: Will substitute for target and execute
#link: Will substitute for target
#operator
self.operator_parameters_group = self.operator_parameters_groupbox()
if self.facility == Facility.SwissFEL:
try:
if self.settings.data["Parameters"]["undulator"]["flag"]:
self.operator_parameters_group.layout().addWidget(
self.parent.gui_header.operator_group_header())
except KeyError:
pass
def draw_widget(buddy):
flag = self.settings.data["Parameters"][key]["flag"]
if buddy == "NONE":
return False
elif buddy not in ["QHLINE", "QVLINE", "QFRAME"] and not flag:
return False
return True
##in_j = 0
for (key, val), label in zip(self.all_input_parameters.items(),
self.all_input_labels.values()):
buddy = self.settings.data[
"Parameters"][key]["data"]["widget"].upper()
j = self.input_wgt_grid.rowCount()
##if j > 4:
## self.input_wgt_grid_column = 6
## in_j += 1
##else:
## in_j = j
#if buddy != "NONE":
self.grid_loc = None
if "useGrid" in self.settings.data:
if self.settings.data["useGrid"]:
if 'grid' in self.settings.data["Parameters"][key]["data"]:
self.grid_loc = self.settings.data[
"Parameters"][key]["data"]["grid"]
if draw_widget(buddy):
self.input_wgt(buddy=buddy, label=label, key=key, value=val,
irow=j, wgt_grid=self.input_wgt_grid)
##if j == 4:
## in_j = 1
##self.input_wgt_grid.setHorizontalSpacing(10)
self.operator_parameters_group.layout().addLayout(self.input_wgt_grid)
self.operator_parameters_group.setMinimumHeight(INPUT_PARAMETERS_HEIGHT)
lo = QGridLayout()
lo.setContentsMargins(9, 19, 9, 9)
lo.addWidget(self.operator_parameters_group, 0, 0, 4, 1,
alignment=Qt.AlignTop)
#if random.randint(1, 10) > 9:
# lo.addWidget(self.create_analysis_wgt(), 0, 1)
#else:
if self.has_optics:
lo.addWidget(self.optics_groupbox(), 0, 1)
row_count = 1
else:
row_count = 0
if self.has_procedure:
if 'V' in self.orientation_procedure.upper():
lo.addWidget(
self.analysis_procedure_group(), row_count, 1, 1, 1)
else:
lo.addWidget(
self.analysis_procedure_group(), lo.rowCount(), 0, 1, 1)
#Centers input parameters group box
lo.setAlignment(Qt.AlignmentFlag(Qt.AlignHCenter|Qt.AlignTop))
lo.setHorizontalSpacing(20)
lo.setVerticalSpacing(10)
self.operator_wgt.setLayout(lo)
#expert
self.expert_parameters_group = self.expert_parameters_groupbox()
for (key, val), label in zip(self.all_expert_parameters.items(),
self.all_expert_labels.values()):
self.grid_loc = None
if "useGrid" in self.settings.data:
if self.settings.data["useGrid"]:
if 'grid' in self.settings.data["Expert"][key]["data"]:
self.grid_loc = self.settings.data[
"Expert"][key]["data"]["grid"]
buddy = self.settings.data[
"Expert"][key]["data"]["widget"].upper()
j = self.expert_wgt_grid.rowCount()
if buddy != "NONE":
self.input_wgt(buddy=buddy, label=label, key=key, value=val,
irow=j, wgt_grid=self.expert_wgt_grid)
#Add expert parameters to input_parameters
self.input_parameters.update(self.expert_parameters)
#Need to emit radio button here as input_parameters is
#overwritten by sel.expoert_parameters
#which give a list [Gasusian and FWMH]
if self.radiobutton:
self.radiobutton[0].toggled.emit(True)
if self.expert_wgt_grid:
self.expert_parameters_group.layout().addLayout(
self.expert_wgt_grid)
if "pipeline" in self.parent.input_parameters.keys():
self.expert_parameters_group.layout().addWidget(
self.image_parameters_group())
self.expert_parameters_group.layout().addWidget(QHLine())
if "autoRestore" in self.parent.input_parameters.keys() and \
"autoCycle" in self.parent.input_parameters.keys():
hbox = QHBoxLayout()
hbox.addWidget(self.checkbox_autoRestore(hline="None"))
hbox.addWidget(self.checkbox_autoCycle(hline="None"))
self.expert_parameters_group.layout().addLayout(hbox)
elif "autoRestore" in self.parent.input_parameters.keys():
self.expert_parameters_group.layout().addWidget(
self.checkbox_autoRestore(hline="TOP"))
elif "autoCycle" in self.parent.input_parameters.keys():
self.expert_parameters_group.layout().addWidget(
self.checkbox_autoCycle())
if "keepImages" in self.parent.input_parameters.keys():
self.expert_parameters_group.layout().addWidget(
self.checkbox_keepImages())
_matches = ["debug", "debugLevel", "simulation"]
match = False
for tag in _matches:
if any([x in tag for x in self.parent.input_parameters.keys()]):
match = True
break
if match:
hbox2 = QHBoxLayout()
if "debug" in self.parent.input_parameters.keys():
hbox2.addWidget(self.checkbox_debug(hline="None"))
if "simulation" in self.parent.input_parameters.keys():
hbox2.addWidget(self.checkbox_simulation(hline="None"))
self.expert_parameters_group.layout().addLayout(hbox2)
self.expert_parameters_group.layout().addLayout(
self.input_wgt_logging(self.expert_wgt_grid.rowCount(),
self.expert_wgt_grid))
self.expert_parameters_group.layout().addWidget(QHLine())
self.expert_parameters_group.setMinimumHeight(EXPERT_PARAMETERS_HEIGHT)
lo = QGridLayout()
lo.setContentsMargins(9, 19, 9, 9)
lo.addWidget(self.expert_parameters_group, 0, 0, 1, 1,
alignment=Qt.AlignTop)
lo.setAlignment(Qt.AlignmentFlag(Qt.AlignHCenter|Qt.AlignTop))
lo.setHorizontalSpacing(20)
self.expert_wgt.setLayout(lo)
#test
def radio_buttons(self, key="", options: list = [], start_idx=0):
widget = QWidget()
layout = QGridLayout()
layout.setContentsMargins(5, 0, 5, 0)
widget.setMaximumWidth(220)
#self.setLayout(layout)
target_list = options
color_list = ["#894961", "teal", "darkblue"]
self.radiobutton = [None] * len(options)
for i, title in enumerate(options):
self.radiobutton[i] = QRadioButton(title)
width_list = [70, 70, 70]
if key in self.settings.data["Expert"].keys():
top_key = "Expert"
elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
_width = 1
_full_width = _width * len(options) + 1
layout.addWidget(QHLine(), 0, 0, 1, _full_width)
layout.addWidget(QLabel(
self.settings.data[top_key][key]['data']['text']), 1, 0, 1, 1,
Qt.AlignCenter)
for i, (radio, target, color, width) in enumerate(
zip(self.radiobutton, target_list, color_list, width_list)):
radio.setFont(self.font_pts10)
radio.setStyleSheet("color : {0};".format(color))
radio.target = target
layout.addWidget(radio, 1, _width*i+1, 1, _width, Qt.AlignCenter)
layout.addWidget(QHLine(), 2, 0, 1, layout.columnCount())
widget.setLayout(layout)
return widget
def create_table_wgt(self, pv_list: list):
return CAQTableWidget(self, pv_list=pv_list, init_column=True,
notify_freq_hz=5, notify_unison=True)
def create_table_layout(self, branches):
@Slot(int)
def on_table_tab_changed(tab_idx):
#print("Changed", tab_idx, self.table_wgt[tab_idx].tab_text)
#print("PM", self.line_sender_dict['profileMonitor'].currentIndex())
#print("PM", self.line_sender_dict['profileMonitor'].currentText())
#key = self.line_sender_dict['profileMonitor'].currentText()
#cannot enumerate self.branches!!
for i, table in enumerate(self.table_wgt):
branch_key = self.branches[i]['key'] #branch['key']
key = self.line_sender_dict[branch_key].currentText()
#print(branch_key, key, i, tab_idx)
#if key in self.branches[i]['lastLine'][key]:
# print("i/idx", i, tab_idx,
# self.branches[i]['lastLine'][key])
#else:
# self.branches[i]['lastLine'][key] = [' ',' ']
#print(self.branches[i]['tagged'])
if i == tab_idx:
if key in self.branches[i]['tagged']:
table.paint_rows(reset=True, last_row=[' ', ' '])
table.paint_rows(
row_range=self.branches[i]['tagged'][key],
reset=False,
last_row=self.branches[i]['lastLine'][key])
else:
table.paint_rows(reset=True, last_row=[' ', ' '])
self.branches = branches
pv_dict = {}
for i in range(0, len(self.branches)):
_title = self.branches[i]['tabTitle']
pv_dict[_title] = self.branches[i]['magnets']
self.table_layout = QGridLayout()
self.table_layout.setAlignment(
Qt.AlignmentFlag(Qt.AlignHCenter|Qt.AlignTop))
self.table_tab_wgt = QTabWidget()
self.table_tab_wgt.setFixedWidth(600)
self.table_tab_wgt.tabBar().setShape(QTabBar.TriangularNorth)
#self.table_tab_wgt.tabBar().setDrawBase(False)
#Initialization has to loop
self.table_wgt = [None] * len(pv_dict)
for i, tab_text in enumerate(pv_dict.keys()):
self.table_wgt[i] = self.create_table_wgt(
pv_list=pv_dict[tab_text])
self.table_wgt[i].tab_text = tab_text
self.table_wgt[i].setFont(self.font_pts10)
self.table_tab_wgt.addTab(self.table_wgt[i], tab_text)
color = self.branches[i]['tabTextColor']
self.table_tab_wgt.tabBar().setTabTextColor(i, QColor(color))
self.table_tab_wgt.currentChanged.connect(on_table_tab_changed)
self.table_layout.addWidget(self.table_tab_wgt, 0, 0)
self.table_layout.setContentsMargins(0, 27, 0, 0)
self.table_tab_wgt.currentChanged.emit(0)
return self.table_layout #tab_wgt