7 Commits

Author SHA1 Message Date
71bcf8c7df merge 2023-02-21 14:55:46 +01:00
6994394da4 update from pyacc 2023-02-21 14:43:41 +01:00
64ce267c84 qradiobutton now excepts default value 2022-10-28 11:05:25 +02:00
cd289303a6 qradiobutton now excepts default value 2022-10-28 10:59:28 +02:00
87def4961c sendelogsls.py uses bdbase.sendelogframe.py 2022-10-24 08:12:47 +02:00
a332aecd87 v1.4.0 2022-10-06 08:26:50 +02:00
fcf37b60c8 overdue 2022-09-14 15:03:15 +02:00
5 changed files with 817 additions and 143 deletions

132
base.py
View File

@@ -5,10 +5,11 @@ from collections import OrderedDict
from datetime import datetime from datetime import datetime
import getpass import getpass
import h5py import h5py
import logging
import inspect import inspect
import platform import platform
import re
import os import os
import re
import sys import sys
import time import time
@@ -30,6 +31,8 @@ from pyqtacc.bdbase.readjson import ReadJSON
from pyqtacc.bdbase.savehdf import QSaveHDF from pyqtacc.bdbase.savehdf import QSaveHDF
from pyqtacc.bdbase.hdf5filemenu import HDF5GroupBox from pyqtacc.bdbase.hdf5filemenu import HDF5GroupBox
from pyqtacc.bdbase.sendelog import QSendToELOG from pyqtacc.bdbase.sendelog import QSendToELOG
from pyqtacc.bdbase.screenshot import QScreenshot from pyqtacc.bdbase.screenshot import QScreenshot
from pyqtacc.bdbase.guiframe import GUIFrame from pyqtacc.bdbase.guiframe import GUIFrame
@@ -101,32 +104,53 @@ class BaseWindow(QMainWindow):
time_in_seconds=self.time_in_seconds, time_in_seconds=self.time_in_seconds,
reanalysis_time_in_seconds=self.reanalysis_time) reanalysis_time_in_seconds=self.reanalysis_time)
print("date_str", date_str, flush=True) #print("date_str", date_str, flush=True)
write_message_fired = False
for i, (nfig, name) in enumerate( for i, (nfig, name) in enumerate(
zip(self.settings.data["GUI"]["resultsSeq"], zip(self.settings.data["GUI"]["resultsSeq"],
self.settings.data["GUI"]["subResultsTabTitle"])): self.settings.data["GUI"]["subResultsTabTitle"])):
canvas = 'Canvas {0}'.format(i+1) canvas = 'Canvas {0}'.format(i+1)
name_base = name.replace(' ', '_').lower() name_base = name.replace(' ', '_').lower()
for idx in range(0, nfig): if self.all_data['Figure data'][canvas] is not None:
nfig_canvas = len(self.all_data['Figure data'][canvas])
nfig_canvas = min(nfig_canvas, nfig)
else:
nfig_canvas = nfig
for idx in range(0, nfig_canvas):
if self.all_data['Figure data'][canvas] is not None: if self.all_data['Figure data'][canvas] is not None:
name = name_base + "_{0}".format( name = name_base + "_{0}".format(
idx) if idx > 0 else name_base idx) if idx > 0 else name_base
save_dest = (folder_name + date_str + '_' + name + save_dest = (folder_name + date_str + '_' + name +
'.png') '.png')
print("idx", i, save_dest, flush=True)
if not os.path.exists(save_dest): if not os.path.exists(save_dest):
if self.all_data['Figure data'][canvas][ if self.all_data['Figure data'][canvas][
idx] is not None: idx] is not None:
self.all_data['Figure data'][canvas][ _dirname = os.path.dirname(save_dest)
idx].savefig(save_dest) if os.access(_dirname, os.W_OK):
self.all_data['Figure data'][canvas][
idx].savefig(save_dest)
elif not write_message_fired:
_mess = ("Do not have write permission " +
"for directory {0} from this " +
"host {1}. Images not saved and " +
"cannot be sent to elog").format(
_dirname, os.uname()[1])
self.parent.trigger_log_message.emit(
MsgSeverity.WARN.name, _pymodule,
_line(), _mess, {})
write_message_fired = True
attach_files.append(save_dest) attach_files.append(save_dest)
if attach_files: if attach_files:
self.parent.attach_files = attach_files self.parent.attach_files = attach_files
print("All files attached") print("All files attached", flush=True)
else: else:
print("No files to attach", flush=True) print("No files to attach", flush=True)
time.sleep(0.2) #avoid race condition time.sleep(0.2) #avoid race condition
@@ -276,12 +300,15 @@ class BaseWindow(QMainWindow):
def run(self): def run(self):
"""Run thread """Run thread
""" """
all_dict = self.analysis_procedure.measure_and_analyze( all_dict = self.analysis_procedure.measure_and_analyze(
self.input_parameters) self.input_parameters)
# Emit results # Emit results
if all_dict is not None: if all_dict:
self.trigger_thread_event.emit(all_dict) self.trigger_thread_event.emit(all_dict)
mess = "Analysis completed" mess = "Analysis completed"
self.parent.trigger_log_message.emit( self.parent.trigger_log_message.emit(
MsgSeverity.INFO.name, _pymodule, _line(), mess, {}) MsgSeverity.INFO.name, _pymodule, _line(), mess, {})
@@ -293,7 +320,7 @@ class BaseWindow(QMainWindow):
def __init__(self, parent=None, pymodule=None, appversion=None, title="", def __init__(self, parent=None, pymodule=None, appversion=None, title="",
user_mode=UserMode.OPERATION, facility=Facility.SwissFEL, user_mode=UserMode.OPERATION, facility=Facility.SwissFEL,
extended=True, has_optics=True): extended=True, has_optics=True, has_procedure=True):
super(BaseWindow, self).__init__(parent) super(BaseWindow, self).__init__(parent)
self.parent = parent self.parent = parent
@@ -307,12 +334,18 @@ class BaseWindow(QMainWindow):
self.facility = facility self.facility = facility
self.user_mode = user_mode self.user_mode = user_mode
self.appname, self.appext = self.pymodule.split(".") self.appname, self.appext = self.pymodule.split(".")
print("=============================================") print("=============================================")
print("Starting {0} at: {1}".format(self.appname, datetime.now())) print("Starting {0} at: {1}".format(self.appname, datetime.now()))
print("User: {0} Host: {1}".format(os.getlogin(), os.uname()[1])) print("User: {0} Host: {1}".format(os.getlogin(), os.uname()[1]))
print("=============================================", flush=True) print("=============================================", flush=True)
self.settings = ReadJSON(self.appname)
#Read out current_logbook
self.cafe = PyCafe.CyCafe() self.cafe = PyCafe.CyCafe()
self.cyca = PyCafe.CyCa() self.cyca = PyCafe.CyCa()
self.cafe_exception = PyCafe.CafeException self.cafe_exception = PyCafe.CafeException
@@ -332,7 +365,7 @@ class BaseWindow(QMainWindow):
self.hdf_dialog = None self.hdf_dialog = None
self.daq_analysis_completed = False self.daq_analysis_completed = False
self.hdf_save_completed = False
self.setObjectName("MainWindow") self.setObjectName("MainWindow")
self.setWindowTitle(self.appname) self.setWindowTitle(self.appname)
@@ -343,8 +376,7 @@ class BaseWindow(QMainWindow):
self.menu = self.menuBar() self.menu = self.menuBar()
self.settings = ReadJSON(self.appname)
''' '''
try: try:
dirname = self.settings.data["stdout"]["destination"] dirname = self.settings.data["stdout"]["destination"]
@@ -364,6 +396,12 @@ class BaseWindow(QMainWindow):
self.stdlog_dest = (self.settings.data["stdlog"]["destination"] + self.stdlog_dest = (self.settings.data["stdlog"]["destination"] +
self.appname + "-" + os.getlogin() + ".log") self.appname + "-" + os.getlogin() + ".log")
self.logging = logging
#self.logging.basicConfig(filename=self.stdlog_dest, level=logging.DEBUG)
self.logging.basicConfig(level=logging.DEBUG)
self.logger = self.logging.getLogger(__name__)
self.logger.info("Logging activated")
self.date_str = None self.date_str = None
self.autopost_elog = True self.autopost_elog = True
@@ -382,13 +420,16 @@ class BaseWindow(QMainWindow):
self.autopost_epics = self.settings.data["menuFlags"]["hasEpics"] self.autopost_epics = self.settings.data["menuFlags"]["hasEpics"]
except KeyError as error: except KeyError as error:
print("KeyError in base.py, init:", error) print("KeyError in base.py, init:", error)
self.autopost_epics = True self.autopost_epics = False
try: try:
self.autopost_hdf = self.settings.data["menuFlags"]["hasH5"] self.autopost_hdf = self.settings.data["menuFlags"]["hasH5"]
except KeyError as error: except KeyError as error:
print("KeyError in base.py, init:", error) print("KeyError in base.py, init:", error)
self.autopost_hdf = True self.autopost_hdf = False
self.hdf_save_completed = False if self.autopost_hdf else True
self.all_input_parameters = {} #gui self.all_input_parameters = {} #gui
self.all_input_labels = {} #gui self.all_input_labels = {} #gui
@@ -463,18 +504,23 @@ class BaseWindow(QMainWindow):
if self.facility == Facility.SwissFEL: if self.facility == Facility.SwissFEL:
from pyqtacc.sf.guiheader import GUIHeader from pyqtacc.sf.guiheader import GUIHeader
from pyqtacc.bdbase.sendelog import QSendToELOG
elif self.facility == Facility.SLS: elif self.facility == Facility.SLS:
from pyqtacc.sls.guiheader import GUIHeader from pyqtacc.sls.guiheader import GUIHeader
from pyqtacc.sls.sendelogsls import QSendToELOG
self.gui_header = GUIHeader(self, user_mode=self.user_mode, self.gui_header = GUIHeader(self, user_mode=self.user_mode,
extended=extended) extended=extended)
self.mainwindow_layout.addWidget(self.gui_header.header_wgt) self.mainwindow_layout.addWidget(self.gui_header.header_wgt)
self.gui_frame = GUIFrame(self, has_optics=self.has_optics) self.gui_frame = GUIFrame(self, has_optics=self.has_optics,
has_procedure=has_procedure)
self.show_log_message = self.gui_frame.show_log_message self.show_log_message = self.gui_frame.show_log_message
self.hdf_dock_widget = QNoDockWidget(" HDF5", self) if self.autopost_hdf:
self.init_hdf_analysis_wgt() self.hdf_dock_widget = QNoDockWidget(" HDF5", self)
self.init_hdf_analysis_wgt()
self.mainwindow_layout.addWidget(self.gui_frame.central_tab_widget) self.mainwindow_layout.addWidget(self.gui_frame.central_tab_widget)
self.mainwindow.setLayout(self.mainwindow_layout) self.mainwindow.setLayout(self.mainwindow_layout)
@@ -523,7 +569,7 @@ class BaseWindow(QMainWindow):
if self.settings.data["Parameters"][key]["flag"]: if self.settings.data["Parameters"][key]["flag"]:
self.input_parameters[key] = val self.input_parameters[key] = val
self.all_input_parameters[key] = val self.all_input_parameters[key] = val
#print("val=",val, key) #print("val=",val, key)
except KeyError as e: except KeyError as e:
@@ -569,8 +615,8 @@ class BaseWindow(QMainWindow):
if self.settings.data["Expert"][key]["flag"]: if self.settings.data["Expert"][key]["flag"]:
self.expert_parameters[key] = val self.expert_parameters[key] = val
self.all_expert_parameters[key] = val self.all_expert_parameters[key] = val
#print("val=",val, key) #print("val=",val, key)
except KeyError as e: except KeyError as e:
print("Key Error in base.py initialization:", e) print("Key Error in base.py initialization:", e)
@@ -811,7 +857,7 @@ class BaseWindow(QMainWindow):
""" """
#Close all dock widgets #Close all dock widgets
#self.removeDockWidget(self.hdf_dock_widget) #self.removeDockWidget(self.hdf_dock_widget)
self.logger.info("Closing Application")
self.save_application_settings() self.save_application_settings()
QApplication.processEvents() QApplication.processEvents()
self.cafe.monitorStopAll() self.cafe.monitorStopAll()
@@ -1147,6 +1193,7 @@ class BaseWindow(QMainWindow):
#print("filename", self.hdf_filename) #print("filename", self.hdf_filename)
def verify_send_to_elog(self): def verify_send_to_elog(self):
if self.analysis_thread is not None: if self.analysis_thread is not None:
if self.analysis_thread.isRunning(): if self.analysis_thread.isRunning():
_mess = ("Measurement in progress. " + _mess = ("Measurement in progress. " +
@@ -1180,6 +1227,9 @@ class BaseWindow(QMainWindow):
def send_to_elog(self): def send_to_elog(self):
""" Response to elog_action; normally overwritten """ Response to elog_action; normally overwritten
""" """
if not self.verify_send_to_elog():
return
'''
if self.analysis_thread is not None: if self.analysis_thread is not None:
if self.analysis_thread.isRunning(): if self.analysis_thread.isRunning():
_mess = ("Measurement in progress. " + _mess = ("Measurement in progress. " +
@@ -1188,6 +1238,7 @@ class BaseWindow(QMainWindow):
QMessageBox.Ok) QMessageBox.Ok)
return return
'''
#_elog_sf = ElogSwissFEL() #_elog_sf = ElogSwissFEL()
_logbook = None _logbook = None
@@ -1197,6 +1248,7 @@ class BaseWindow(QMainWindow):
_attach_files = [] _attach_files = []
_message = "" _message = ""
QSendToELOG(self, logbook=_logbook, categoryIdx=_category_idx, QSendToELOG(self, logbook=_logbook, categoryIdx=_category_idx,
domainIdx=_domain_idx, sectionIdx=_section_idx, domainIdx=_domain_idx, sectionIdx=_section_idx,
title=self.title, message=_message, title=self.title, message=_message,
@@ -1613,7 +1665,7 @@ class BaseWindow(QMainWindow):
@Slot() @Slot()
def start_analysis_thread(self): def start_analysis_thread(self):
if not self.analysis_procedure: if not self.analysis_procedure:
mess = "Analysis thread not configured for this application" mess = "Analysis thread not configured for this application"
self.show_log_message(MsgSeverity.ERROR, _pymodule, _line(), mess) self.show_log_message(MsgSeverity.ERROR, _pymodule, _line(), mess)
@@ -1636,17 +1688,17 @@ class BaseWindow(QMainWindow):
if not self.verify_analysis_preconditions(): if not self.verify_analysis_preconditions():
return return
self.analysis_thread = self.AnalysisThread( self.analysis_thread = self.AnalysisThread(
self, self.analysis_procedure, self.input_parameters) self, self.analysis_procedure, self.input_parameters)
self.analysis_thread.trigger_thread_event.connect( self.analysis_thread.trigger_thread_event.connect(
self.receive_analysis_results) self.receive_analysis_results)
self.analysis_thread.started.connect(self.analysis_thread_started) self.analysis_thread.started.connect(self.analysis_thread_started)
self.analysis_thread.finished.connect(self.analysis_thread_finished) self.analysis_thread.finished.connect(self.analysis_thread_finished)
#getMachineDatafor hdf
self.analysis_thread.start() self.analysis_thread.start()
QApplication.processEvents() QApplication.processEvents()
@@ -1686,17 +1738,26 @@ class BaseWindow(QMainWindow):
@Slot(dict) @Slot(dict)
def receive_analysis_results(self, all_dict): def receive_analysis_results(self, all_dict):
#print("receive analysis results", all_dict)
self.all_data = all_dict self.all_data = all_dict
self.gui_frame.canvas_update(all_dict['Figure data']) self.gui_frame.canvas_update(all_dict['Figure data'])
if self.gui_frame.results_output_wgt_dict:
#all_dict['Processed data']['Results']={}
#all_dict['Processed data']['Results']['mean'] = 123.23
#all_dict['Processed data']['Results']['SD'] = 0.23
try:
results_data = all_dict['Processed data']['Results']
self.gui_frame.send_to_results_output_wgt(results_data)
except:
pass
self.gui_frame.central_tab_widget.setCurrentIndex(1) self.gui_frame.central_tab_widget.setCurrentIndex(1)
self.gui_frame.results_tab_wgt.setCurrentIndex(0) self.gui_frame.results_tab_wgt.setCurrentIndex(0)
@Slot() @Slot()
def receive_abort_analysis(self): def receive_abort_analysis(self):
"""Instantiate action on abort """Instantiate action on abort
""" """
print("Aborting")
if self.analysis_procedure.abort: if self.analysis_procedure.abort:
return return
self.gui_frame.in_abort_procedure() self.gui_frame.in_abort_procedure()
@@ -1719,6 +1780,12 @@ class BaseWindow(QMainWindow):
message="Measurement in progress..."): message="Measurement in progress..."):
'''Receives update of message''' '''Receives update of message'''
self.progressbar.setVisible(True) self.progressbar.setVisible(True)
try:
if self.input_parameters["simulation"] :
self.progressbar_color = self.progressbar_simulation
except KeyError:
pass
if value == PROGRESS_BAR_THREAD_INIT: if value == PROGRESS_BAR_THREAD_INIT:
self.progressbar.setVisible(False) self.progressbar.setVisible(False)
self.progressbar.setFormat("") self.progressbar.setFormat("")
@@ -1738,6 +1805,8 @@ class BaseWindow(QMainWindow):
prog_val = re.findall(r'\d+', message) prog_val = re.findall(r'\d+', message)
if prog_val: if prog_val:
self.progressbar.setValue(int(prog_val[0])) self.progressbar.setValue(int(prog_val[0]))
else:
self.progressbar.setValue(int(10))
mess = "Aborting measurement procedure" mess = "Aborting measurement procedure"
self.show_log_message( self.show_log_message(
MsgSeverity.WARN.name, _pymodule, _line(), mess) MsgSeverity.WARN.name, _pymodule, _line(), mess)
@@ -1764,7 +1833,8 @@ class BaseWindow(QMainWindow):
self.progressbar.setValue(value) self.progressbar.setValue(value)
self.progressbar.setObjectName(self.progressbar_color) self.progressbar.setObjectName(self.progressbar_color)
self.daq_analysis_completed = True self.daq_analysis_completed = True
self.hdf_save_completed = False if self.autopost_hdf:
self.hdf_save_completed = False
QTimer.singleShot(2000, lambda: self.progressbar.setVisible(False)) QTimer.singleShot(2000, lambda: self.progressbar.setVisible(False))
else: else:
self.progressbar.setFormat(message) self.progressbar.setFormat(message)
@@ -1774,7 +1844,7 @@ class BaseWindow(QMainWindow):
self.progressbar.style().polish(self.progressbar) self.progressbar.style().polish(self.progressbar)
QApplication.processEvents() QApplication.processEvents()
time.sleep(0.0001) time.sleep(0.0001)
def initialize_application(self, appname=_appname, delay=None, def initialize_application(self, appname=_appname, delay=None,
facility=Facility.SwissFEL): facility=Facility.SwissFEL):

View File

@@ -18,6 +18,7 @@ class Facility(IntEnum):
PSI = 0 PSI = 0
SwissFEL = 1 SwissFEL = 1
SLS = 2 SLS = 2
HIPA = 3
class MsgSeverity(IntEnum): class MsgSeverity(IntEnum):
""" For use with message logger """ For use with message logger

View File

@@ -17,15 +17,15 @@ from qtpy.QtWidgets import (QCheckBox, QComboBox, QDoubleSpinBox, QFrame,
QStackedWidget, QTabBar, QTabWidget, QToolButton, QStackedWidget, QTabBar, QTabWidget, QToolButton,
QVBoxLayout, QWidget) QVBoxLayout, QWidget)
from caqtwidgets.pvwidgets import (CAQLabel, CAQTableWidget, QMessageWidget, from caqtwidgets.pvwidgets import (CAQLabel, CAQTableWidget, QMessageWidget,
QHLine) QHLine, QVLine)
from pyqtacc.bdbase.enumkind import Facility, MsgSeverity, UserMode from pyqtacc.bdbase.enumkind import Facility, MsgSeverity, UserMode
_pymodule = os.path.basename(__file__) _pymodule = os.path.basename(__file__)
_appversion = "1.0.0" _appversion = "1.0.0"
INPUT_PARAMETERS_HEIGHT = 600 INPUT_PARAMETERS_HEIGHT = 200
EXPERT_PARAMETERS_HEIGHT = 600 EXPERT_PARAMETERS_HEIGHT = 200
def _line(): def _line():
@@ -42,11 +42,12 @@ def _line():
class GUIFrame(QWidget): class GUIFrame(QWidget):
""" GUI Class """ GUI Class
""" """
def __init__(self, parent, has_optics=True): def __init__(self, parent, has_optics=True, has_procedure=True):
#super(GUIFrame, self).__init__() #super(GUIFrame, self).__init__()
super().__init__() super().__init__()
self.parent = parent self.parent = parent
self.has_optics = has_optics self.has_optics = has_optics
self.has_procedure = has_procedure
self.appname = parent.appname self.appname = parent.appname
self.facility = parent.facility self.facility = parent.facility
self.settings = parent.settings self.settings = parent.settings
@@ -61,6 +62,8 @@ class GUIFrame(QWidget):
self.all_expert_parameters = parent.all_expert_parameters self.all_expert_parameters = parent.all_expert_parameters
self.all_expert_labels = parent.all_expert_labels self.all_expert_labels = parent.all_expert_labels
self.results_output_wgt_dict = {}
try: try:
self.widget_height = self.settings.data["StyleGuide"][ self.widget_height = self.settings.data["StyleGuide"][
"widgetHeight"] "widgetHeight"]
@@ -75,18 +78,21 @@ class GUIFrame(QWidget):
self.expert_parameters_group = None self.expert_parameters_group = None
self.operator_parameters_group = None self.operator_parameters_group = None
self.output_parameters_wgt = None
self.optics_group = None self.optics_group = None
self.energy_stacked_widget = None self.energy_stacked_widget = None
self.phase_stacked_widget = None self.phase_stacked_widget = None
self.table_tab_wgt = None self.table_tab_wgt = None
self.radiobutton = None
self.multiple_figure_dict = None self.multiple_figure_dict = None
self.line_sender_dict = {} self.line_sender_dict = {}
self.radio_stack_dict = {} self.radio_stack_dict = {}
self.stack_radiolist_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_qcolor = parent.msg_severity_qcolor
self.msg_severity = MsgSeverity self.msg_severity = MsgSeverity
@@ -102,7 +108,7 @@ class GUIFrame(QWidget):
self.measurement_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.measurement_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.measurement_layout.setSpacing(50) self.measurement_layout.setSpacing(50)
self.measurement_tab_wgt = QTabWidget(self.measurement_wgt) self.measurement_tab_wgt = QTabWidget(self.measurement_wgt)
self.measurement_tab_wgt.setFixedWidth(480) self.measurement_tab_wgt.setMinimumWidth(480)
self.operator_wgt = QWidget(self.measurement_tab_wgt) self.operator_wgt = QWidget(self.measurement_tab_wgt)
self.expert_wgt = QWidget(self.measurement_tab_wgt) self.expert_wgt = QWidget(self.measurement_tab_wgt)
@@ -111,20 +117,6 @@ class GUIFrame(QWidget):
self.results_layout = QHBoxLayout(self.results_wgt) self.results_layout = QHBoxLayout(self.results_wgt)
self.results_tab_wgt = QTabWidget(self.results_wgt) self.results_tab_wgt = QTabWidget(self.results_wgt)
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.canvas_fig_dict = {} self.canvas_fig_dict = {}
self.left_arrow_dict = {} self.left_arrow_dict = {}
@@ -136,13 +128,32 @@ class GUIFrame(QWidget):
self.start_wgt_text = "Start" self.start_wgt_text = "Start"
self.save_all_wgt = QWidget() self.save_all_wgt = QWidget()
self.init_measurement_tab_wgt() if "GUI" in self.settings.data:
self.init_results_tab_wgt() 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()
self.slice_orientation = "vertical" #horizontal/vertical for SATMA02
self.init_measurement_tab_wgt()
self.log_wgt = QMessageWidget() self.log_wgt = QMessageWidget()
self.log_layout = QVBoxLayout(self.log_wgt) self.log_layout = QVBoxLayout(self.log_wgt)
self.show_log_message(MsgSeverity.INFO, _pymodule, _line(), #self.show_log_message(MsgSeverity.INFO, _pymodule, _line(),
"Application started") # "Application started")
self.input_wgt_grid = QGridLayout() self.input_wgt_grid = QGridLayout()
self.input_wgt_grid.setHorizontalSpacing(0) self.input_wgt_grid.setHorizontalSpacing(0)
@@ -160,8 +171,9 @@ class GUIFrame(QWidget):
""" """
self.central_tab_widget.setFont(self.font_gui) self.central_tab_widget.setFont(self.font_gui)
self.central_tab_widget.addTab(self.measurement_wgt, "Measurement") self.central_tab_widget.addTab(self.measurement_wgt, "Measurement")
self.central_tab_widget.addTab( if "GUI" in self.settings.data:
self.results_wgt, self.settings.data["GUI"]["resultsTabTitle"]) self.central_tab_widget.addTab(
self.results_wgt, self.settings.data["GUI"]["resultsTabTitle"])
self.central_tab_widget.addTab(self.log_wgt, "Log") self.central_tab_widget.addTab(self.log_wgt, "Log")
def init_measurement_tab_wgt(self): def init_measurement_tab_wgt(self):
@@ -236,7 +248,7 @@ class GUIFrame(QWidget):
hbox.setSpacing(5) hbox.setSpacing(5)
hbox.setAlignment(Qt.AlignTop | Qt.AlignHCenter) hbox.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
group_box.setMaximumWidth(208) group_box.setMaximumWidth(208)
group_box.setMaximumHeight(220) group_box.setMinimumHeight(196)
group_box.setFont(self.font_gui) group_box.setFont(self.font_gui)
group_box.setAlignment(Qt.AlignTop | Qt.AlignHCenter) group_box.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
group_box.setLayout(hbox) group_box.setLayout(hbox)
@@ -260,6 +272,76 @@ class GUIFrame(QWidget):
self.optics_group.cycle_quads = None self.optics_group.cycle_quads = None
return self.optics_group 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.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.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"): def input_parameters_group(self, title="Input Parameters"):
""" Generic group box for user supplied input """ Generic group box for user supplied input
""" """
@@ -301,11 +383,12 @@ class GUIFrame(QWidget):
#print(self.input_parameters) #print(self.input_parameters)
checkbox = QCheckBox(text) checkbox = QCheckBox(text)
checkbox.setToolTip(tip) checkbox.setToolTip(tip)
checkbox.setFont(self.font_gui) checkbox.setFont(self.font_gui)
checkbox.stateChanged.connect(on_checkbox_change) checkbox.stateChanged.connect(on_checkbox_change)
#checkbox.setFixedHeight(30) #checkbox.setFixedHeight(30)
#checkbox.setLayoutDirection(Qt.RightToLeft)
checked_value = default_value checked_value = default_value
if key in self.parent.input_parameters.keys(): if key in self.parent.input_parameters.keys():
if "data" in self.settings.data[top_key][key].keys(): if "data" in self.settings.data[top_key][key].keys():
@@ -316,16 +399,18 @@ class GUIFrame(QWidget):
checked_value = Qt.Unchecked checked_value = Qt.Unchecked
checkbox.setCheckState(checked_value) checkbox.setCheckState(checked_value)
checkbox.stateChanged.emit(checked_value)
return checkbox return checkbox
def create_label_qdoublespinbox(self, key, label="", min_val=0, max_val=1, def create_label_qdoublespinbox(self, key, label="", min_val=0, max_val=1,
step=0.1, start_val=0.5): step=0.1, start_val=0.5, digits=1):
""" Generic QDoubleSpinbox with buddy label """ Generic QDoubleSpinbox with buddy label
""" """
def callback(value): def callback(value):
self.input_parameters[key] = value self.input_parameters[key] = round(value, digits)
widget_height = 24 widget_height = 24
suggested = "WWW" suggested = "WWW"
@@ -347,6 +432,7 @@ class GUIFrame(QWidget):
wgt.setMaximumWidth(param_width + 40) wgt.setMaximumWidth(param_width + 40)
wgt.valueChanged.connect(callback) wgt.valueChanged.connect(callback)
wgt.setValue(start_val) wgt.setValue(start_val)
wgt.valueChanged.emit(start_val)
return lab, wgt return lab, wgt
@@ -358,6 +444,7 @@ class GUIFrame(QWidget):
def cb(value): def cb(value):
self.input_parameters[key] = value self.input_parameters[key] = value
widget_height = 24 widget_height = 24
suggested = "WWW" suggested = "WWW"
lab = QLabel(label) lab = QLabel(label)
@@ -377,15 +464,17 @@ class GUIFrame(QWidget):
wgt.setMaximumWidth(param_width + 40) wgt.setMaximumWidth(param_width + 40)
wgt.valueChanged.connect(cb) wgt.valueChanged.connect(cb)
wgt.setValue(start_val) wgt.setValue(start_val)
wgt.valueChanged.emit(start_val)
return lab, wgt return lab, wgt
def create_label_qcombobox(self, key, label="", values: list = []): def create_label_qcombobox(self, key, label="", values: list = [], start_val: str =""):
""" Generic QCombobox with buddy label """ Generic QCombobox with buddy label
""" """
def cb(new_text): def cb(new_text):
self.input_parameters[key] = new_text self.input_parameters[key] = new_text
print( self.input_parameters)
widget_height = 26 widget_height = 26
suggested = "WWW" suggested = "WWW"
@@ -402,8 +491,11 @@ class GUIFrame(QWidget):
wgt.setFont(self.font_pts10) wgt.setFont(self.font_pts10)
wgt.setContentsMargins(5, 0, 0, 0) wgt.setContentsMargins(5, 0, 0, 0)
wgt.currentTextChanged.connect(cb) wgt.currentTextChanged.connect(cb)
wgt.setCurrentIndex(0)
wgt.currentTextChanged.emit(values[0]) 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) value_for_width = max(values, key=len)
@@ -411,23 +503,33 @@ class GUIFrame(QWidget):
param_width = max(fm.width(str(value_for_width)), fm.width(suggested)) param_width = max(fm.width(str(value_for_width)), fm.width(suggested))
wgt.setFixedWidth(param_width + 50) wgt.setFixedWidth(param_width + 50)
return lab, wgt return lab, wgt
def image_parameters_group(self): def image_parameters_group(self):
group_box = QGroupBox("Image Pipeline Parameters") group_box = QGroupBox("Image Pipeline Expert")
box = QHBoxLayout() box = QHBoxLayout()
box.setSpacing(10) 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( box.addWidget(self.create_checkbox(
top_key="Expert", key="goodRegion", text="Good region", top_key="Expert", key="goodRegion", text="Good region",
tip="Enables good region in pipeline", default_value=Qt.Checked)) 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( box.addWidget(self.create_checkbox(
top_key="Expert", key="subtractBackground", top_key="Expert", key="subtractBackground",
text="Subtract bkgrnd", text="Subtract bkgrnd",
tip="Enables background subtraction in pipeline", tip="Enables background subtraction in pipeline",
default_value=Qt.Checked)) default_value=start_val_sub))
group_box.setAlignment(Qt.AlignCenter) group_box.setAlignment(Qt.AlignCenter)
group_box.setObjectName("INNERCENTER") group_box.setObjectName("INNERCENTER")
@@ -435,10 +537,20 @@ class GUIFrame(QWidget):
good_region = QGroupBox("Good Region") good_region = QGroupBox("Good Region")
good_region.setObjectName("INNER") good_region.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( lab_thresh, thresh = self.create_label_qdoublespinbox(
key="grThreshold", label="Threshold:") 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( lab_gfscale, gfscale = self.create_label_qspinbox(
key="grScale", label="Scale:") key="grScale", label="Scale:", start_val=start_val_grScale)
layout = QGridLayout() layout = QGridLayout()
layout.addWidget(lab_thresh, 0, 0) layout.addWidget(lab_thresh, 0, 0)
layout.addWidget(thresh, 0, 1) layout.addWidget(thresh, 0, 1)
@@ -449,13 +561,28 @@ class GUIFrame(QWidget):
slicing = QGroupBox("Slicing") slicing = QGroupBox("Slicing")
slicing.setObjectName("INNER") slicing.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( lab_slices, slices = self.create_label_qspinbox(
key="slices", label="No. Slices:", start_val=21) 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( lab_scale, scale = self.create_label_qspinbox(
key="slicingScale", label="Scale:") key="slicingScale", label="Scale:", start_val=start_val_slicing_scale)
lab_orientation, orientation = self.create_label_qcombobox(
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:", key="orientation", label="Orientation:",
values=["vertical", "horizontal"]) values=["vertical", "horizontal"], start_val=start_val_orientation)
layout = QGridLayout() layout = QGridLayout()
@@ -464,7 +591,7 @@ class GUIFrame(QWidget):
layout.addWidget(lab_scale, 1, 0) layout.addWidget(lab_scale, 1, 0)
layout.addWidget(scale, 1, 1) layout.addWidget(scale, 1, 1)
layout.addWidget(lab_orientation, 2, 0, 1, 2, Qt.AlignBottom) layout.addWidget(lab_orientation, 2, 0, 1, 2, Qt.AlignBottom)
layout.addWidget(orientation, 3, 0, 1, 2, Qt.AlignTop | Qt.AlignRight) layout.addWidget(self.slice_orientation, 3, 0, 1, 2, Qt.AlignTop | Qt.AlignRight)
slicing.setLayout(layout) slicing.setLayout(layout)
layout_top = QGridLayout() layout_top = QGridLayout()
@@ -556,11 +683,19 @@ class GUIFrame(QWidget):
for table in self.table_wgt: for table in self.table_wgt:
table.init_value_button.setEnabled(False) table.init_value_button.setEnabled(False)
table.restore_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): def in_abort_procedure(self):
self.abort_wgt.setEnabled(False) self.abort_wgt.setEnabled(False)
self.start_wgt.setEnabled(False) self.start_wgt.setEnabled(False)
self.start_wgt.setText("Aborting...") self.start_wgt.setText("Aborting...")
def reset_procedure(self): def reset_procedure(self):
self.abort_wgt.setVisible(False) self.abort_wgt.setVisible(False)
@@ -576,6 +711,8 @@ class GUIFrame(QWidget):
for table in self.table_wgt: for table in self.table_wgt:
table.init_value_button.setEnabled(True) table.init_value_button.setEnabled(True)
table.restore_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): def in_hdf_measurement_procedure(self):
self.parent.h5_groupbox.analyze_h5_widget.setEnabled(False) self.parent.h5_groupbox.analyze_h5_widget.setEnabled(False)
@@ -739,7 +876,7 @@ class GUIFrame(QWidget):
except KeyError as error: except KeyError as error:
print(("KeyError in guiframe.py; Unknown key {0} " + print(("KeyError in guiframe.py; Unknown key {0} " +
"in def checkbox_wgt: {1}").format(key, error)) "in def checkbox_wgt: {1}").format(key, error))
text = key text = key
checkbox = QCheckBox(text) checkbox = QCheckBox(text)
checkbox.setToolTip(tooltip) checkbox.setToolTip(tooltip)
@@ -747,9 +884,12 @@ class GUIFrame(QWidget):
if object_name: if object_name:
checkbox.setObjectName(object_name) checkbox.setObjectName(object_name)
checkbox.setLayoutDirection(Qt.LeftToRight) #is default
checkbox.stateChanged.connect(on_change) checkbox.stateChanged.connect(on_change)
checked_value = Qt.Unchecked 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.parent.input_parameters.keys():
if key in self.settings.data["Expert"].keys(): if key in self.settings.data["Expert"].keys():
if "data" in self.settings.data["Expert"][key].keys(): if "data" in self.settings.data["Expert"][key].keys():
@@ -921,18 +1061,23 @@ class GUIFrame(QWidget):
def canvas_update(self, fig_data, idx=0): def canvas_update(self, fig_data, idx=0):
#place figures in a list #place figures in a list
self.parent.clear_screenshot()
self.parent.clear_screenshot()
self.multiple_figure_dict = fig_data self.multiple_figure_dict = fig_data
for i, key in enumerate(self.multiple_figure_dict.keys()): for i, key in enumerate(self.multiple_figure_dict.keys()):
self.canvas_fig_dict[i] = key self.canvas_fig_dict[i] = key
for i, (canvas, nav, wgt, layout, key) in enumerate( for i, (canvas, nav, wgt, layout, key) in enumerate(
zip(self.canvas, self.nav, zip(self.canvas, self.nav,
self.sub_results_wgt, self.sub_results_wgt,
self.sub_results_layout, self.sub_results_layout,
self.multiple_figure_dict.keys())): self.multiple_figure_dict.keys())):
if canvas is not None: if canvas is not None:
layout.removeWidget(canvas) layout.removeWidget(canvas)
@@ -941,10 +1086,13 @@ class GUIFrame(QWidget):
nav.deleteLater() nav.deleteLater()
if self.multiple_figure_dict[key]: #'Figure 1']: if self.multiple_figure_dict[key]: #'Figure 1']:
if not isinstance(self.multiple_figure_dict[key], list): if not isinstance(self.multiple_figure_dict[key], list):
temp_list = [] temp_list = []
temp_list.append(self.multiple_figure_dict[key]) temp_list.append(self.multiple_figure_dict[key])
self.multiple_figure_dict[key] = temp_list self.multiple_figure_dict[key] = temp_list
self.canvas[i] = FigureCanvasQTAgg( self.canvas[i] = FigureCanvasQTAgg(
self.multiple_figure_dict[key][idx]) self.multiple_figure_dict[key][idx])
self.sub_results_layout[i].addWidget(self.canvas[i]) self.sub_results_layout[i].addWidget(self.canvas[i])
@@ -955,10 +1103,10 @@ class GUIFrame(QWidget):
#self.nav[i].setContentsMargins(0, 0, 0, 0) #self.nav[i].setContentsMargins(0, 0, 0, 0)
self.nav[i].setVisible(True) self.nav[i].setVisible(True)
self.nav[i].setStyleSheet("QToolBar { border: 0px }") self.nav[i].setStyleSheet("QToolBar { border: 0px }")
self.parent.add_screenshot(title=self.results_tab_wgt_titles[i], self.parent.add_screenshot(title=self.results_tab_wgt_titles[i],
item=wgt) item=wgt)
else: else:
self.canvas[i] = None self.canvas[i] = None
self.nav[i] = None self.nav[i] = None
@@ -975,16 +1123,22 @@ class GUIFrame(QWidget):
self.cafe.setGetActionWhenMonitorPolicy( self.cafe.setGetActionWhenMonitorPolicy(
pv, self.cyca.GET_FROM_CACHE) pv, self.cyca.GET_FROM_CACHE)
stack_list = []
for pv, head, val, obj in zip(pvlist, title, default_value, for pv, head, val, obj in zip(pvlist, title, default_value,
object_name): object_name):
stack, radiobutton_list = self.pv_selector_wgt( stack, radiobutton_list = self.pv_selector_wgt(
title=head, key=key, pv=pv, manual_value=val) title=head, key=key, pv=pv, manual_value=val)
self.stack_radiolist_dict[stack] = radiobutton_list self.stack_radiolist_dict[stack] = radiobutton_list
stack_list.append(stack)
stack.setObjectName(obj) stack.setObjectName(obj)
stack.style().polish(stack) stack.style().polish(stack)
stacked_widget.addWidget(stack) stacked_widget.addWidget(stack)
stacked_widget.setMaximumHeight(220)
stacked_widget.setMaximumHeight(320)
self.stacked_wgt_dict[stacked_widget] = stack_list
return stacked_widget return stacked_widget
def pv_energy_stacked_wgt(self): def pv_energy_stacked_wgt(self):
@@ -1033,10 +1187,27 @@ class GUIFrame(QWidget):
radiobutton_title = ["Monitor", "Update", "Manual"] radiobutton_title = ["Monitor", "Update", "Manual"]
radiobutton_flag = [monitor, read, manual] radiobutton_flag = [monitor, read, manual]
radiobutton_list = [None] * len(radiobutton_title) radiobutton_list = [None] * len(radiobutton_title)
pv_local = pv
monitor_pv = None
def cb_pv_selector(value): def cb_pv_selector(value):
value_str = radio_buddy_text_dict[self.sender()].text() 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 self.radio_stack_dict[self.sender()] = value
if not value_str: if not value_str:
@@ -1074,6 +1245,7 @@ class GUIFrame(QWidget):
if flag: if flag:
grid.addWidget(radio, irow, 0) grid.addWidget(radio, irow, 0)
if monitor: if monitor:
ql = QLabel(radiobutton_title[0]) ql = QLabel(radiobutton_title[0])
ql.setFont(self.font_pts10) ql.setFont(self.font_pts10)
@@ -1088,8 +1260,18 @@ class GUIFrame(QWidget):
ql.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) ql.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
grid.addWidget(ql, 2, 1) 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: if monitor:
monitor_pv = CAQLabel(self, pv_name=pv, show_units=True) monitor_pv = CAQLabel(self, pv_name=pv, monitor_callback=mon_cb,
show_units=True)
monitor_pv.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) monitor_pv.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
monitor_pv.setFont(self.font_pts10) monitor_pv.setFont(self.font_pts10)
monitor_pv.setFixedHeight(self.widget_height) monitor_pv.setFixedHeight(self.widget_height)
@@ -1161,13 +1343,14 @@ class GUIFrame(QWidget):
ql.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) ql.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
grid.addWidget(ql, 2, 3) grid.addWidget(ql, 2, 3)
grid.setContentsMargins(9, 15, 9, 0) grid.setContentsMargins(5, 10, 5, 0)
#grid.setContentsMargins(9, 15, 9, 0)
grid.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) grid.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
grid.setVerticalSpacing(2) grid.setVerticalSpacing(2)
grid.setHorizontalSpacing(4) grid.setHorizontalSpacing(4)
group_box.setContentsMargins(0, 0, 0, 0) group_box.setContentsMargins(0, 0, 0, 0)
group_box.setMaximumWidth(280) group_box.setMaximumWidth(280)
group_box.setMaximumHeight(260) group_box.setMaximumHeight(320)
group_box.setFont(self.font_pts10) group_box.setFont(self.font_pts10)
group_box.setAlignment(Qt.AlignTop | Qt.AlignHCenter) group_box.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
group_box.setLayout(grid) group_box.setLayout(grid)
@@ -1233,11 +1416,19 @@ class GUIFrame(QWidget):
return line return line
def input_wgt_qradiobutton(self, key, value, irow, wgt_grid): def input_wgt_qradiobutton(self, key, value, irow, wgt_grid):
def on_radiobutton_change(): #new_value): def on_radiobutton_change(new_value):
radio_button = self.sender() radio_button = self.sender()
self.parent.input_parameters[key] = radio_button.target if radio_button.isChecked():
if 'forwardLink' in self.settings.data['Parameters'][key]['data']: self.parent.input_parameters[key] = radio_button.target
link = self.settings.data['Parameters'][key]['data'][ #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] 'forwardLink'][0]
for item in self.settings.data[link][radio_button.target]: for item in self.settings.data[link][radio_button.target]:
@@ -1245,26 +1436,45 @@ class GUIFrame(QWidget):
item] item]
if item in self.line_sender_dict: if item in self.line_sender_dict:
if self.settings.data['Parameters'][item]['data'][ if self.settings.data[top_key][item]['data'][
'widget'] in 'QComboBox': 'widget'] in 'QComboBox':
self.line_sender_dict[item].clear() self.line_sender_dict[item].clear()
self.line_sender_dict[item].addItems(value_list) self.line_sender_dict[item].addItems(value_list)
self.line_sender_dict[item].setCurrentIndex(0) self.line_sender_dict[item].setCurrentIndex(0)
self.line_sender_dict[item].currentTextChanged.emit( self.line_sender_dict[item].currentTextChanged.emit(
value_list[0]) value_list[0])
elif self.settings.data['Parameters'][item]['data'][ elif self.settings.data[top_key][item]['data'][
'widget'] in 'QLineEdit': 'widget'] in 'QLineEdit':
self.line_sender_dict[item].setText(str(value_list)) self.line_sender_dict[item].setText(str(value_list))
line = self.radio_buttons(value) line = self.radio_buttons(key=key, options=value)
line.setContentsMargins(0, 0, 0, 0)
rblist = line.findChildren(QRadioButton) rblist = line.findChildren(QRadioButton)
for rb in rblist: for rb in rblist:
rb.toggled.connect(on_radiobutton_change) rb.toggled.connect(on_radiobutton_change)
rblist[0].setChecked(True)
rblist[0].toggled.emit(True)
wgt_grid.addWidget(line, irow, 0, 1, 4) 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 return line
@@ -1276,10 +1486,26 @@ class GUIFrame(QWidget):
line.setChecked(Qt.Checked if value else Qt.Unchecked) line.setChecked(Qt.Checked if value else Qt.Unchecked)
line.stateChanged.connect(check_cb) line.stateChanged.connect(check_cb)
line.setMaximumWidth(320) line.setMaximumWidth(320)
line.setMinimumWidth(220) line.setMinimumWidth(100)
line.setFixedHeight(28) 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"
wgt_grid.addWidget(line, irow, 0, 1, 4, Qt.AlignLeft | Qt.AlignVCenter) 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
wgt_grid.addWidget(line, irow, 0, 1, col_wdt, Qt.AlignLeft | Qt.AlignVCenter)
return line return line
@@ -1298,22 +1524,27 @@ class GUIFrame(QWidget):
return line return line
def input_wgt_qlineread(self, value, label, irow, wgt_grid): def input_wgt_qlineread(self, key, value, label, irow, wgt_grid):
#Read only has no callback def line_cb(new_value):
self.parent.input_parameters[key] = new_value
suggested = "WW" suggested = "WW"
line = QLineEdit() line = QLineEdit()
line.setObjectName("Read") line.setObjectName("Read")
line.setText(str(value)) #"{0: 3.1f}".format(value)) line.setText(str(value)) #"{0: 3.1f}".format(value))
line.setFixedHeight(24) line.setFixedHeight(24)
line.textChanged.connect(line_cb)
line.setAlignment(Qt.AlignRight | Qt.AlignBottom) line.setAlignment(Qt.AlignRight | Qt.AlignBottom)
line.setStyleSheet("QLabel{text-align: right}") line.setStyleSheet("QLabel{text-align: right}")
fm = QFontMetricsF(line.font()) fm = QFontMetricsF(line.font())
param_width = max(fm.width(str(value)), fm.width(suggested)) param_width = max(fm.width(str(value)), fm.width(suggested))
line.setMaximumWidth(param_width + 24) extra_width = 22 if len(str(value)) < 16 else 26
line.setFixedWidth(param_width + extra_width)
wgt_grid.addWidget(label, irow, 0, 1, 2, Qt.AlignLeft | Qt.AlignVCenter) qframe_buffer = QFrame()
wgt_grid.addWidget(line, irow, 2, 1, 2, Qt.AlignLeft | Qt.AlignVCenter) qframe_buffer.setFixedWidth(3)
wgt_grid.addWidget(label, irow, 0, 1, 1, Qt.AlignLeft | Qt.AlignVCenter)
wgt_grid.addWidget(qframe_buffer, irow, 1, 1, 1, Qt.AlignLeft | Qt.AlignVCenter)
wgt_grid.addWidget(line, irow, 2, 1, 1, Qt.AlignLeft | Qt.AlignVCenter)
return line return line
def input_wgt_qlineedit(self, key, value, label, irow, wgt_grid): def input_wgt_qlineedit(self, key, value, label, irow, wgt_grid):
@@ -1322,13 +1553,15 @@ class GUIFrame(QWidget):
suggested = "WW" suggested = "WW"
line = QLineEdit() line = QLineEdit()
line.setObjectName("Write") line.setObjectName("Write")
line.setFixedHeight(24) line.setFixedHeight(24)
line.textEdited.connect(line_cb) line.textEdited.connect(line_cb)
line.setText(str(value)) line.setText(str(value))
fm = QFontMetricsF(line.font()) fm = QFontMetricsF(line.font())
param_width = max(fm.width(str(value)), fm.width(suggested)) param_width = max(fm.width(str(value)), fm.width(suggested))
line.setMaximumWidth(param_width + 20) extra_width = 22 if len(str(value)) < 16 else 26
line.setFixedWidth(param_width + extra_width)
wgt_grid.addWidget(label, irow, 0, 1, 2, Qt.AlignLeft | Qt.AlignVCenter) wgt_grid.addWidget(label, irow, 0, 1, 2, Qt.AlignLeft | Qt.AlignVCenter)
wgt_grid.addWidget(line, irow, 2, 1, 2, Qt.AlignLeft | Qt.AlignVCenter) wgt_grid.addWidget(line, irow, 2, 1, 2, Qt.AlignLeft | Qt.AlignVCenter)
@@ -1395,22 +1628,30 @@ class GUIFrame(QWidget):
return line return line
def input_wgt_qenergystacked(self, irow, wgt_grid): def input_wgt_qenergystacked(self, irow, wgt_grid):
qFrame = QFrame() qframe_top = QFrame()
qFrame.setFixedHeight(10) qframe_top.setFixedHeight(3)
line = self.pv_energy_stacked_wgt() stacked_wgt = self.pv_energy_stacked_wgt()
wgt_grid.addWidget(qFrame, irow, 0, 1, 4) qframe_bottom = QFrame()
wgt_grid.addWidget(line, irow+1, 0, 1, 4) qframe_bottom.setFixedHeight(3)
return line wgt_grid.addWidget(qframe_top, irow, 0, 1, 4)
wgt_grid.addWidget(stacked_wgt, irow+1, 0, 1, 4)
wgt_grid.addWidget(qframe_bottom, irow+2, 0, 1, 4)
return stacked_wgt
def input_wgt_qphasestacked(self, irow, wgt_grid): def input_wgt_qphasestacked(self, irow, wgt_grid):
qFrame = QFrame() qframe_top = QFrame()
qFrame.setFixedHeight(10) qframe_top.setFixedHeight(3)
line = self.pv_phase_stacked_wgt() stacked_wgt = self.pv_phase_stacked_wgt()
wgt_grid.addWidget(qFrame, irow, 0, 1, 4) qframe_bottom = QFrame()
wgt_grid.addWidget(line, irow+1, 0, 1, 4) qframe_bottom.setFixedHeight(3)
return line wgt_grid.addWidget(qframe_top, irow, 0, 1, 4)
wgt_grid.addWidget(stacked_wgt, irow+1, 0, 1, 4)
wgt_grid.addWidget(qframe_bottom, irow+2, 0, 1, 4)
return stacked_wgt
def input_wgt_qhline(self, irow, wgt_grid): def input_wgt_qhline(self, irow, wgt_grid):
qHLine = QHLine() qHLine = QHLine()
@@ -1424,7 +1665,13 @@ class GUIFrame(QWidget):
wgt_grid.addWidget(qFrame, irow, 0, 1, 4) wgt_grid.addWidget(qFrame, irow, 0, 1, 4)
def input_wgt(self, buddy, label, key, value, irow=0, wgt_grid=None): def input_wgt(self, buddy, label, key, value, irow=0, wgt_grid=None,):
if "QVLINE" in buddy:
print("QVLine", label, key, value)
if "QVLINE" in buddy:
print("QVLine", label, key, value)
if wgt_grid is None: if wgt_grid is None:
wgt_grid = self.input_wgt_grid wgt_grid = self.input_wgt_grid
@@ -1451,7 +1698,7 @@ class GUIFrame(QWidget):
line = self.input_wgt_qlabel(value, irow, wgt_grid) line = self.input_wgt_qlabel(value, irow, wgt_grid)
elif buddy == "QLineRead".upper(): elif buddy == "QLineRead".upper():
line = self.input_wgt_qlineread(value, label, irow, wgt_grid) line = self.input_wgt_qlineread(key, value, label, irow, wgt_grid)
elif buddy == "QDoubleSpinBox".upper(): elif buddy == "QDoubleSpinBox".upper():
line = self.input_wgt_qdoublespinbox(key, value, label, irow, line = self.input_wgt_qdoublespinbox(key, value, label, irow,
@@ -1517,21 +1764,31 @@ class GUIFrame(QWidget):
except KeyError: except KeyError:
pass pass
def draw_widget(buddy):
flag = self.settings.data["Parameters"][key]["flag"]
if buddy == "NONE":
return False
elif buddy not in ["QHLINE", "QFRAME"] and not flag:
return False
return True
for (key, val), label in zip(self.all_input_parameters.items(), for (key, val), label in zip(self.all_input_parameters.items(),
self.all_input_labels.values()): self.all_input_labels.values()):
buddy = self.settings.data[ buddy = self.settings.data[
"Parameters"][key]["data"]["widget"].upper() "Parameters"][key]["data"]["widget"].upper()
j = self.input_wgt_grid.rowCount() j = self.input_wgt_grid.rowCount()
if buddy != "NONE": #if buddy != "NONE":
if draw_widget(buddy):
self.input_wgt(buddy=buddy, label=label, key=key, value=val, self.input_wgt(buddy=buddy, label=label, key=key, value=val,
irow=j, wgt_grid=self.input_wgt_grid) irow=j, wgt_grid=self.input_wgt_grid)
self.operator_parameters_group.layout().addLayout(self.input_wgt_grid) self.operator_parameters_group.layout().addLayout(self.input_wgt_grid)
self.operator_parameters_group.setFixedHeight(INPUT_PARAMETERS_HEIGHT) self.operator_parameters_group.setMinimumHeight(INPUT_PARAMETERS_HEIGHT)
lo = QGridLayout() lo = QGridLayout()
lo.setContentsMargins(9, 19, 9, 9) lo.setContentsMargins(9, 19, 9, 9)
lo.addWidget(self.operator_parameters_group, 0, 0, 4, 1) lo.addWidget(self.operator_parameters_group, 0, 0, 4, 1, alignment=Qt.AlignTop)
#if random.randint(1, 10) > 9: #if random.randint(1, 10) > 9:
# lo.addWidget(self.create_analysis_wgt(), 0, 1) # lo.addWidget(self.create_analysis_wgt(), 0, 1)
#else: #else:
@@ -1540,8 +1797,11 @@ class GUIFrame(QWidget):
row_count = 1 row_count = 1
else: else:
row_count = 0 row_count = 0
lo.addWidget(self.analysis_procedure_group(), row_count, 1)
if self.has_procedure:
lo.addWidget(self.analysis_procedure_group(), row_count, 1)
#Centers input parameters group box #Centers input parameters group box
lo.setAlignment(Qt.AlignHCenter | Qt.AlignTop) lo.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
lo.setHorizontalSpacing(20) lo.setHorizontalSpacing(20)
@@ -1564,6 +1824,11 @@ class GUIFrame(QWidget):
#Add expert parameters to input_parameters #Add expert parameters to input_parameters
self.input_parameters.update(self.expert_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: if self.expert_wgt_grid:
self.expert_parameters_group.layout().addLayout( self.expert_parameters_group.layout().addLayout(
self.expert_wgt_grid) self.expert_wgt_grid)
@@ -1595,7 +1860,7 @@ class GUIFrame(QWidget):
self.expert_parameters_group.layout().addWidget( self.expert_parameters_group.layout().addWidget(
self.checkbox_keepImages()) self.checkbox_keepImages())
self.expert_parameters_group.layout().addWidget(QHLine()) ##self.expert_parameters_group.layout().addWidget(QHLine())
hbox2 = QHBoxLayout() hbox2 = QHBoxLayout()
hbox2.addWidget(self.checkbox_debug(hline="None")) hbox2.addWidget(self.checkbox_debug(hline="None"))
@@ -1612,21 +1877,23 @@ class GUIFrame(QWidget):
self.expert_parameters_group.layout().addWidget(QHLine()) self.expert_parameters_group.layout().addWidget(QHLine())
self.expert_parameters_group.setFixedHeight(EXPERT_PARAMETERS_HEIGHT) self.expert_parameters_group.setMinimumHeight(EXPERT_PARAMETERS_HEIGHT)
lo = QGridLayout() lo = QGridLayout()
lo.setContentsMargins(9, 19, 9, 9) lo.setContentsMargins(9, 19, 9, 9)
lo.addWidget(self.expert_parameters_group, 0, 0, 2, 1) lo.addWidget(self.expert_parameters_group, 0, 0, 1, 1, alignment=Qt.AlignTop)
lo.setAlignment(Qt.AlignHCenter | Qt.AlignTop) lo.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
lo.setHorizontalSpacing(20) lo.setHorizontalSpacing(20)
self.expert_wgt.setLayout(lo) self.expert_wgt.setLayout(lo)
#test #test
def radio_buttons(self, options: list = [], start_idx=0): def radio_buttons(self, key="", options: list = [], start_idx=0):
widget = QWidget() widget = QWidget()
layout = QGridLayout() layout = QGridLayout()
layout.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(5, 0, 5, 0)
self.setLayout(layout) widget.setMaximumWidth(220)
#self.setLayout(layout)
target_list = options target_list = options
color_list = ["#894961", "teal", "darkblue"] color_list = ["#894961", "teal", "darkblue"]
@@ -1637,11 +1904,18 @@ class GUIFrame(QWidget):
width_list = [70, 70, 70] width_list = [70, 70, 70]
layout.addWidget(QHLine(), 0, 0, 1, 3) if key in self.settings.data["Expert"].keys():
layout.addWidget(QLabel("RF Tranverse Deflector"), 1, 0, 1, 3, top_key = "Expert"
Qt.AlignCenter) elif key in self.settings.data["Parameters"].keys():
top_key = "Parameters"
_fix_width = False _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( for i, (radio, target, color, width) in enumerate(
zip(self.radiobutton, target_list, color_list, width_list)): zip(self.radiobutton, target_list, color_list, width_list)):
@@ -1649,14 +1923,17 @@ class GUIFrame(QWidget):
radio.setFont(self.font_pts10) radio.setFont(self.font_pts10)
radio.setStyleSheet("color : {0};".format(color)) radio.setStyleSheet("color : {0};".format(color))
radio.target = target radio.target = target
layout.addWidget(radio, 2, i)
if _fix_width: layout.addWidget(radio, 1, _width*i+1, 1, _width, Qt.AlignCenter)
radio.setFixedWidth(width)
#_qf = QFrame()
#_qf.setFixedWidth(10)
#layout.addWidget(_qf, 1, layout.columnCount())
self.radiobutton[start_idx].setChecked(True) #self.radiobutton[start_idx].setChecked(True)
self.radiobutton[start_idx].toggled.emit(True) #self.radiobutton[start_idx].toggled.emit(True)
layout.addWidget(QHLine(), 3, 0, 1, 3) layout.addWidget(QHLine(), 2, 0, 1, layout.columnCount())
widget.setLayout(layout) widget.setLayout(layout)

View File

@@ -34,6 +34,7 @@ class QSendToELOG(QDialog):
attachFile=None, destination_folder=None): attachFile=None, destination_folder=None):
#super(QSendToELOG, self).__init__(parent) #super(QSendToELOG, self).__init__(parent)
super().__init__() super().__init__()
self.files_text = '' self.files_text = ''
self.fflag = False self.fflag = False
self.parent = parent self.parent = parent
@@ -43,7 +44,7 @@ class QSendToELOG(QDialog):
self.destination = destination_folder self.destination = destination_folder
self.window_title = self.parent.appname + ": " + _appname self.window_title = self.parent.appname + ": " + _appname
self.pymodule = _pymodule self.pymodule = _pymodule
self.setWindowTitle(self.window_title) self.setWindowTitle(self.window_title)
elog_books = list(self.parent.settings.data["ElogBooks"]) elog_books = list(self.parent.settings.data["ElogBooks"])
@@ -51,6 +52,7 @@ class QSendToELOG(QDialog):
self.elog_items.addItems(elog_books) self.elog_items.addItems(elog_books)
self.elog_items.currentIndexChanged.connect(self.on_elog_change) self.elog_items.currentIndexChanged.connect(self.on_elog_change)
idx = 0 idx = 0
if logbook is not None: if logbook is not None:
try: try:
idx = elog_books.index(logbook) idx = elog_books.index(logbook)
@@ -144,7 +146,7 @@ class QSendToELOG(QDialog):
self.files = [] self.files = []
self.attributes = {} self.attributes = {}
self.layout = QVBoxLayout(self) self.layout = QVBoxLayout(self)
self.layout.addLayout(logbook) self.layout.addLayout(logbook)
self.layout.addLayout(self.applicationbox) self.layout.addLayout(self.applicationbox)
@@ -187,7 +189,7 @@ class QSendToELOG(QDialog):
self.fflag = True self.fflag = True
filebox.addWidget(self.filesE) filebox.addWidget(self.filesE)
openCloseVBox = QVBoxLayout() openCloseVBox = QVBoxLayout()
self.openBtn = QPushButton('Add') self.openBtn = QPushButton('Add')
self.openBtn.setAutoDefault(False) self.openBtn.setAutoDefault(False)
@@ -216,7 +218,7 @@ class QSendToELOG(QDialog):
self.messagelbl.setStyleSheet("QLabel { color : red; }") self.messagelbl.setStyleSheet("QLabel { color : red; }")
self.layout.addWidget(self.messagelbl) self.layout.addWidget(self.messagelbl)
self.layout.addLayout(btnLayout) self.layout.addLayout(btnLayout)
self.setMinimumWidth(440) self.setMinimumWidth(440)
self.exec() self.exec()

324
sendelogframe.py Normal file
View File

@@ -0,0 +1,324 @@
import getpass
import inspect
import os
import time
from qtpy.QtCore import Qt
from qtpy.QtWidgets import (QComboBox, QDialog, QFileDialog, QHBoxLayout,
QLabel, QLineEdit, QPushButton, QTextEdit,
QVBoxLayout)
import elog # https://github.com/paulscherrerinstitute/py_elog
from pyqtacc.bdbase.enumkind import MsgSeverity
_version = "1.0.0"
_pymodule = os.path.basename(__file__)
_appname, _appext = _pymodule.split(".")
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 QSendToELOGFrame(QDialog):
""" Graphical interface to elog
"""
def __init__(self, parent, logbook=None, title=None, message=None,
attachFile=None, destination_folder=None):
super().__init__()
self.files_text = ''
self.fflag = False
self.parent = parent
if destination_folder is None:
self.destination = self.parent.elog_dest + " / " + self.parent.appname
else:
self.destination = destination_folder
self.window_title = self.parent.appname + ": " + _appname
self.pymodule = _pymodule
self.setWindowTitle(self.window_title)
elog_books = list(self.parent.settings.data["ElogBooks"])
self.elog_items = QComboBox()
self.elog_items.addItems(elog_books)
self.elog_items.currentIndexChanged.connect(self.on_elog_change)
idx = 0
if logbook is not None:
try:
idx = elog_books.index(logbook)
except Exception:
mess = "Index not found for logbook {0}".format(logbook)
self.parent.show_log_message(MsgSeverity.WARN, self.pymodule,
_line(), mess)
else:
logbook = self.parent.settings.data["Elog"]["book"]
try:
idx = elog_books.index(logbook)
except Exception:
mess = "Index not found for logbook {0}".format(logbook)
self.parent.show_log_message(MsgSeverity.WARN, self.pymodule,
_line(), mess)
self.logbook = logbook
self.elog_items.setCurrentIndex(idx)
self.elog_items.currentIndexChanged.emit(idx)
self.elog_items.setObjectName("Elog")
self.title_items = QHBoxLayout()
self.title_items.addWidget(QLabel('Title: '))
self.titleline = QLineEdit()
self.titleline.setObjectName('Elog')
#self.titleline.setStatusTip('elog')
if title is None:
title = self.parent.appname
self.titleline.setText(str(title))
self.titleline.setFixedWidth(300)
self.titleline.setAlignment(Qt.AlignCenter)
self.title_items.addWidget(self.titleline)
self.applicationbox = QHBoxLayout()
self.applicationbox.addWidget(QLabel('Application:'))
self.applicationlabel = QLabel(self.parent.pymodule)
self.applicationlabel.setObjectName("Elog")
# self.applicationbox.addStretch()
self.applicationbox.addWidget(self.applicationlabel)
logbook = QHBoxLayout()
logbook.addWidget(QLabel('Logbook: '))
logbook.addWidget(self.elog_items)
authorbox = QHBoxLayout()
authorbox.addWidget(QLabel('Author: '))
self.author = QLineEdit()
self.author.setObjectName('Elog')
self.author.setFixedWidth(195)
self.author.setStatusTip('elog')
self.author.setText(getpass.getuser())
authorbox.addWidget(self.author)
self.files = []
self.attributes = {}
self.layout = QVBoxLayout(self)
self.layout.addLayout(logbook)
self.layout.addLayout(self.applicationbox)
self.layout.addLayout(authorbox)
self.layout.addLayout(self.title_items)
report = QLabel('Report: ')
self.layout.addWidget(report)
self.message = QTextEdit(message)
self.layout.addWidget(self.message)
filebox = QHBoxLayout()
qlfile = QLabel('Attach:')
qlfile.setAlignment(Qt.AlignTop)
filebox.addWidget(qlfile)
self.filesE = QTextEdit()
self.filesE.setAlignment(Qt.AlignTop)
self.filesE.setFixedHeight(80)
self.filesE.setReadOnly(True)
self.attachFile = attachFile
if self.attachFile is not None:
_attachFile = []
if isinstance(self.attachFile, str):
_attachFile.append(self.attachFile)
elif isinstance(self.attachFile, list):
_attachFile = self.attachFile
for i, file in enumerate(_attachFile):
_attach_base = os.path.basename(file)
if i > 0:
self.files_text += "\n"
self.files_text += str(_attach_base)
self.filesE.setText(self.files_text)
self.fflag = True
filebox.addWidget(self.filesE)
openCloseVBox = QVBoxLayout()
self.openBtn = QPushButton('Add')
self.openBtn.setAutoDefault(False)
self.openBtn.clicked.connect(self.openFiles)
openCloseVBox.addWidget(self.openBtn)
closeBtn = QPushButton('Clear')
closeBtn.setAutoDefault(False)
closeBtn.clicked.connect(self.clearFiles)
openCloseVBox.addWidget(closeBtn)
filebox.addLayout(openCloseVBox)
self.layout.addLayout(filebox)
btnLayout = QHBoxLayout()
self.okBtn = QPushButton('Send')
self.okBtn.setAutoDefault(False)
self.okBtn.clicked.connect(self.ok)
self.cancelBtn = QPushButton('Cancel')
self.cancelBtn.setAutoDefault(False)
self.cancelBtn.clicked.connect(self.close)
btnLayout.addWidget(self.okBtn)
btnLayout.addWidget(self.cancelBtn)
self.messagelbl = QLabel('')
self.messagelbl.setStyleSheet("QLabel { color : red; }")
self.layout.addWidget(self.messagelbl)
self.layout.addLayout(btnLayout)
self.setMinimumWidth(440)
#self.exec()
def on_elog_change(self, elog_change_val):
if "test" in self.elog_items.currentText():
_bgcolor = "QComboBox {background: plum; color : black;}"
else:
_bgcolor = "QComboBox {background: lightblue; color : black;}"
self.elog_items.setStyleSheet(_bgcolor)
def ok(self):
message = self.message.document().toPlainText()
if not message:
self.messagelbl.setText('Please enter a brief Report')
return
title = self.titleline.text()
if not title:
self.messagelbl.setText('Titel attribute is required')
return
author = self.author.text()
application = self.applicationlabel.text()
self.attributes['Autor'] = author
self.attributes['Author'] = author
self.attributes['Application'] = application
self.attributes['Titel'] = title
self.attributes['Title'] = title
self.attributes['When'] = str(time.time())
self.attributes['Wann'] = str(time.time())
if self.attachFile is not None:
_attachFile = []
if isinstance(self.attachFile, str):
_attachFile.append(self.attachFile)
elif isinstance(self.attachFile, list):
_attachFile = self.attachFile
for i in range(0, len(_attachFile)):
if "/tmp" in _attachFile[i]:
self.files.append(str(_attachFile[i]))
elif "/afs/psi.ch" in _attachFile[i]:
self.files.append(str(_attachFile[i]))
elif "/sls/bd/data/" in _attachFile[i]:
self.files.append(str(_attachFile[i]))
else:
self.files.append(self.destination + str(_attachFile[i]))
el = self.elog_items.currentText()
url = self.parent.settings.data["ElogBooks"][el]["url"]
self.logbook = elog.open(url, user='robot', password='robot')
try:
if self.files:
self.logbook.post(message, attributes=self.attributes,
attachments=self.files)
else:
self.logbook.post(message, attributes=self.attributes)
#self.trigger_elog_entry.emit(True, url, "OK")
self.receive_elog_notification(True, url, "OK")
except Exception as ex:
#self.trigger_elog_entry.emit(False, url, str(ex))
print("Exception in sendelog.py", str(ex))
self.receive_elog_notification(False, url, str(ex))
#for file in self.files:
# if os.path.exists(file):
# os.remove(file)
self.close()
def clearFiles(self):
self.attachFile = []
self.filesE.clear()
self.files = []
self.files_text = ''
self.fflag = False
def openFiles(self):
# Notethat openFiles also gets called when qDialog cacnel is clicked!
qFileDialog = QFileDialog()
extensions = ("Images (*.bmp *.eps *.gif *.jpeg *.jpg *.pdf *.png " +
"*.ps *.tiff *.xpm);;Text files (*.txt *.text);;" +
"JSON/XML files (*.json *.xml)")
flocal = qFileDialog.getOpenFileNames(
self, 'Open File', self.destination, extensions)[0]
if not flocal:
return
self.files.append(flocal[0])
if self.fflag:
self.files_text += '\n'
self.files_text += str(flocal[0].split('/')[-1])
self.fflag = True
self.filesE.setText(self.files_text)
def receive_elog_notification(self, is_accepted, logbook_url, elog_message):
'''Receive notification from ELOG, and report to log window'''
yes_no = "made" if is_accepted else "failed"
mess = "Entry into ELOG: {0} {1}".format(logbook_url, yes_no)
if is_accepted:
self.parent.show_log_message(MsgSeverity.INFO, self.pymodule,
_line(), mess)
else:
mess += ".\n" + elog_message
self.parent.show_log_message(MsgSeverity.WARN, self.pymodule,
_line(), mess)
self.parent.statusbar.showMessage(mess)
def get_logbook_specific_items(self, logbook):
'''Retrieve logbook specific options'''
#First check what is the logbook being requested?
#find layout items
layout_items = []
layout_items_optional = []
try:
layout_items = list(self.parent.settings.data[
"ElogBooks"][logbook]['Required'].keys())
except KeyError:
pass
try:
layout_items_optional = list(self.parent.settings.data[
"ElogBooks"][logbook]['Optional'].keys())
except KeyError:
pass
layout_items.extend(layout_items_optional)
return layout_items