mirror of
https://gitlab.psi.ch/pyqtacc/proscan.git
synced 2025-12-31 11:40:55 +01:00
294 lines
12 KiB
Python
294 lines
12 KiB
Python
""" Gui header for PROSCAN
|
|
"""
|
|
from qtpy.QtCore import Qt, QTimer
|
|
from qtpy.QtGui import QFont
|
|
from qtpy.QtWidgets import (
|
|
QApplication, QFrame, QGridLayout, QGroupBox, QHBoxLayout, QLabel,
|
|
QProxyStyle, QVBoxLayout, QWidget)
|
|
|
|
from caqtwidgets.pvwidgets import CAQLabel
|
|
from pyqtacc.bdbase.enumkind import UserMode
|
|
|
|
class GUIHeader(QWidget):
|
|
""" GUI Header Class
|
|
"""
|
|
def __init__(self, parent, user_mode=UserMode.OPERATION, extended=True):
|
|
super(GUIHeader, self).__init__()
|
|
self.parent = parent
|
|
self.appname = parent.appname
|
|
self.title = parent.title
|
|
self.settings = parent.settings
|
|
self.user_mode = user_mode
|
|
self.current_user_mode_name = user_mode.name
|
|
|
|
self.extended = extended
|
|
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.header_groups = self.settings.data['header']
|
|
self.header_status = [None] * len(self.header_groups)
|
|
self.header_row = {"COMET": 1, "G1": 2, "SH": 1, "G2": 2, "O2": 1,
|
|
"PIF": 0, "G3": 0, "MASTER": 1}
|
|
#self.header_row = {"COMET": 0, "G1": 0, "SH": 0, "G2": 0, "O2": 0,
|
|
# "PIF": 0, "G3": 0, "MASTER": 0}
|
|
|
|
self.font_gui = QFont("sans serif")
|
|
self.font_gui.setPointSize(11)
|
|
self.font_pts10 = QFont("sans serif")
|
|
self.font_pts10.setPointSize(10)
|
|
self.widget_height = self.settings.data["StyleGuide"]["widgetHeight"]
|
|
self.extra_height = self.settings.data["StyleGuide"]["extraGroupHeight"]
|
|
|
|
pvlist = []
|
|
header_colors = []
|
|
for sector in self.header_groups:
|
|
pvlist.append(self.settings.data[sector]["status"])
|
|
header_colors.append(self.settings.data[sector]["colorObj"])
|
|
|
|
self.cafe.openPrepare()
|
|
self.cafe.open(pvlist)
|
|
self.cafe.openNowAndWait(0.4)
|
|
self.cafe.printDisconnected()
|
|
|
|
self.station_width = 200 #default
|
|
self.station_height = 100
|
|
self.hor_layout = QHBoxLayout()
|
|
self.grid_layout = QGridLayout()
|
|
self.beam_current_wgt_dict = {}
|
|
self.beam_current_wgt_group = {}
|
|
has_hbox_layout = False
|
|
|
|
self.pframe_matrix = {"POST-COMET": {}, "G1": {}, "PRE-SH": {},
|
|
"POST-SH": {}, "G2": {}, "PRE-O2": {},
|
|
"O2": {}, "PRE-PIF": {}, "PRE-G3": {}}
|
|
|
|
|
|
def pframe(color="green"):
|
|
qframe = QFrame()
|
|
qframe.setStyleSheet("background-color: {0};".format(color))
|
|
qframe.setFixedWidth(6)
|
|
qframe.setFixedHeight(6)
|
|
return qframe
|
|
|
|
def draw_box(nheight: int = 10, nwidth: int = 8, area: str = None):
|
|
if area is None:
|
|
return
|
|
qw = QWidget()
|
|
qgrid = QGridLayout()
|
|
for i in range(0, nheight):
|
|
self.pframe_matrix[area][i] = {}
|
|
for j in range(0, nwidth):
|
|
self.pframe_matrix[area][i][j] = {}
|
|
pf = pframe('green')
|
|
qgrid.addWidget(pf, i, j, 1, 1, Qt.AlignCenter)
|
|
#if i==3 and j==3:
|
|
# pf.setVisible(False)
|
|
self.pframe_matrix[area][i][j] = True
|
|
|
|
|
|
qgrid.setSpacing(1)
|
|
qgrid.setContentsMargins(0, 0, 0, 0)
|
|
qgrid.setAlignment(Qt.AlignCenter)
|
|
qw.setLayout(qgrid)
|
|
return qw
|
|
|
|
if has_hbox_layout:
|
|
for sector, pv, color in zip(self.header_groups, pvlist,
|
|
header_colors):
|
|
if sector == "MASTER":
|
|
qframe = QFrame()
|
|
qframe.setFixedWidth(200)
|
|
self.hor_layout.addWidget(qframe)
|
|
self.hor_layout.addWidget(self.beam_current_widget(
|
|
header=sector, pv= pv, color_obj=color))
|
|
self.hor_layout.setSpacing(6)
|
|
self.hor_layout.setAlignment(Qt.AlignLeft)
|
|
self.hor_layout.setContentsMargins(5, 0, 5, 0)
|
|
else:
|
|
j = 0
|
|
for (sector, pv, color) in (
|
|
zip(self.header_groups, pvlist, header_colors)):
|
|
if sector == "MASTER":
|
|
qframe = QFrame()
|
|
qframe.setFixedWidth(100)
|
|
self.grid_layout.addWidget(qframe, self.header_row[sector], j, 2, 1)
|
|
j += 1
|
|
|
|
self.grid_layout.addWidget(self.beam_current_widget(
|
|
header=sector, pv= pv, color_obj=color), self.header_row[sector], j, 2, 1)
|
|
j += 1
|
|
_align = Qt.AlignCenter
|
|
if sector in ["PIF"]:
|
|
qw = draw_box(nheight=10, nwidth=8, area="PRE-G3")
|
|
self.grid_layout.addWidget(qw, 0, j, 2, 1, _align)
|
|
j += 1
|
|
elif sector in ["O2"]:
|
|
qw = draw_box(nheight=5, nwidth=16, area="PRE-PIF")
|
|
self.grid_layout.addWidget(qw, 0, j-1, 1, 1, _align)
|
|
qw = draw_box(nheight=10, nwidth=8, area="O2")
|
|
self.grid_layout.addWidget(qw, 0, j, 2, 1, _align)
|
|
j += 1
|
|
elif sector in ["COMET"]:
|
|
qw = draw_box(nheight=10, nwidth=8, area="POST-COMET")
|
|
self.grid_layout.addWidget(qw, 1, j, 2, 1, _align)
|
|
j += 1
|
|
elif sector in ["SH"]:
|
|
qw = draw_box(nheight=15, nwidth=10, area="POST-SH")
|
|
self.grid_layout.addWidget(qw, 0, j, 3, 1, _align)
|
|
j += 1
|
|
elif sector in ["G1"]:
|
|
qw = draw_box(nheight=5,nwidth=16, area="G1")
|
|
self.grid_layout.addWidget(qw, 1, j-1, 1, 1, _align)
|
|
qw = draw_box(nheight=10, nwidth=8, area="PRE-SH")
|
|
self.grid_layout.addWidget(qw, 1, j, 2, 1, _align)
|
|
j += 1
|
|
elif sector in ["G2"]:
|
|
|
|
qw = draw_box(nheight=10, nwidth=16, area="G2")
|
|
self.grid_layout.addWidget(qw, 0, j-1, 2, 1, _align)
|
|
qw = draw_box(nheight=10, nwidth=8, area="PRE-O2")
|
|
self.grid_layout.addWidget(qw, 0, j, 2, 1, _align)
|
|
j += 1
|
|
elif sector not in ["MASTER", "G3"]:
|
|
qw = draw_box()
|
|
self.grid_layout.addWidget(qw, 0, j, 2, 1, _align)
|
|
j += 1
|
|
|
|
if has_hbox_layout:
|
|
self.grid_layout.setSpacing(6)
|
|
else:
|
|
self.grid_layout.setSpacing(0)
|
|
self.grid_layout.setAlignment(Qt.AlignLeft)
|
|
self.grid_layout.setContentsMargins(5, 0, 5, 0)
|
|
|
|
self.header_wgt = QGroupBox()
|
|
self.header_wgt.setObjectName(self.user_mode.name)
|
|
if has_hbox_layout:
|
|
self.header_wgt.setLayout(self.hor_layout)
|
|
self.header_wgt.setFixedHeight(110)
|
|
else:
|
|
self.header_wgt.setLayout(self.grid_layout)
|
|
self.header_wgt.setFixedHeight(160)
|
|
#self.header_wgt.setStyle(QProxyStyle())
|
|
title = "PROSCAN {0}".format(self.user_mode.name)
|
|
if self.title:
|
|
title += ": {0}".format(self.title)
|
|
self.header_wgt.setTitle(title)
|
|
|
|
print(self.pframe_matrix)
|
|
|
|
self.target_beamline = None
|
|
|
|
self.timer = QTimer()
|
|
#self.timer.timeout.connect(lambda: self.blink_target_beamline(None))
|
|
self.timer.timeout.connect(self.blink_target_beamline)
|
|
self.timer.start(500)
|
|
self.timer_count = 0
|
|
|
|
self.master_to_wgt = {"Gantry 1": "G1", "Gantry 2": "G2",
|
|
"Gantry 3": "G3", "OPTIS2": "O2"}
|
|
|
|
def blink_target_beamline(self):
|
|
target = self.target_beamline
|
|
if target is None:
|
|
return
|
|
self.target_beamline = target
|
|
self.timer_count += 1
|
|
if self.timer_count < 2:
|
|
return
|
|
if self.timer_count % 2 == 0:
|
|
self.reset_beamline()
|
|
else:
|
|
self.set_target_beamline(reset=False)
|
|
if self.timer_count > 8:
|
|
self.timer.stop()
|
|
QApplication.processEvents()
|
|
|
|
|
|
def set_target_beamline(self, reset=True):
|
|
""" Select beamline target and modify color scheme accordinly
|
|
"""
|
|
print("set_target_beamline", self.target_beamline, flush=True)
|
|
master = self.beam_current_wgt_group[self.target_beamline]
|
|
master.setObjectName("ARAMIS")
|
|
master.style().polish(master)
|
|
|
|
print("set_target_beamline//", self.target_beamline, flush=True)
|
|
|
|
if reset:
|
|
self.reset_beamline()
|
|
|
|
|
|
def reset_beamline(self):
|
|
""" Reset QGroupBox for previous target to original colors
|
|
"""
|
|
print("reset_target_beamline", self.target_beamline, flush=True)
|
|
|
|
master = self.beam_current_wgt_group[self.target_beamline]
|
|
|
|
if "BEAMLINE" not in master.objectName():
|
|
master.setObjectName("BEAMLINE")
|
|
master.style().polish(master)
|
|
print("reset_target_beamline/", self.target_beamline, flush=True)
|
|
|
|
print("reset_target_beamline//", self.target_beamline, flush=True)
|
|
|
|
def reset_operation_mode(self):
|
|
""" Reset header colors to application operation mode
|
|
"""
|
|
self.change_operation_mode(user_mode=self.user_mode)
|
|
|
|
def change_operation_mode(self, user_mode=UserMode.OPERATION):
|
|
""" Different operation modes have different color schemes
|
|
"""
|
|
title_name = user_mode.name
|
|
dry_run_tags = ['HUSH', 'Dry']
|
|
#print('title', self.header_wgt.title(), flush=True)
|
|
|
|
if any([x in self.header_wgt.title() for x in dry_run_tags]):
|
|
title_name = 'DRY RUN' if user_mode.name == 'SIMULATION' \
|
|
else user_mode.name
|
|
|
|
|
|
self.header_wgt.setObjectName(user_mode.name)
|
|
self.header_wgt.setTitle(self.header_wgt.title().replace(
|
|
self.current_user_mode_name, title_name))
|
|
self.header_wgt.style().polish(self.header_wgt)
|
|
self.current_user_mode_name = title_name
|
|
|
|
def beam_current_widget(self, header: str="", pv: str ="",
|
|
color_obj: str="MACHINE"):
|
|
""" QGroupBox encompassing beam current info
|
|
"""
|
|
station = QGroupBox()
|
|
station.setObjectName(color_obj.upper())
|
|
station.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
|
|
station.setFlat(False)
|
|
station.setTitle(header)
|
|
beam_current = CAQLabel(self, pv_name=pv, show_units=True)
|
|
beam_current.setFixedHeight(self.widget_height)
|
|
if header == "MASTER":
|
|
beam_current.setFixedWidth(140)
|
|
else:
|
|
beam_current.setFixedWidth(100)
|
|
|
|
grid_layout = QGridLayout()
|
|
grid_layout.addWidget(beam_current, 0, 0, 1, 1, Qt.AlignCenter)
|
|
grid_layout.setVerticalSpacing(0)
|
|
grid_layout.setHorizontalSpacing(0)
|
|
grid_layout.setContentsMargins(2, 9, 2, 0)
|
|
|
|
station.setLayout(grid_layout)
|
|
station.setFixedHeight(beam_current.height() + self.extra_height)
|
|
station.setFixedWidth(beam_current.width() + 15)
|
|
self.beam_current_wgt_dict[header] = beam_current
|
|
self.beam_current_wgt_group[header] = station
|
|
return station
|
|
|
|
|