cleaner app starting, new application settings class
This commit is contained in:
@@ -8,7 +8,7 @@ from PyQt5.QtWidgets import QMenu, QAction, QSpinBox, QMenu
|
||||
from pyqtgraph import ROI, Point, RectROI, mkPen
|
||||
from pyqtgraph import functions as fn
|
||||
|
||||
from app_config import settings
|
||||
from app_config import AppCfg# settings
|
||||
|
||||
from math import *
|
||||
|
||||
|
||||
@@ -14,13 +14,13 @@ from pathlib import Path
|
||||
|
||||
#import qsingleton #ZAC: orig. code
|
||||
#from CoordinatesModel import CoordinatesModel #ZAC: orig. code
|
||||
from app_config import settings, appsconf, option
|
||||
from app_config import AppCfg #settings, option, appsconf
|
||||
|
||||
EMBL_RESULTS_TIMEOUT = "embl/results_timeout"
|
||||
|
||||
EMBL_SAVE_FILES = "embl/save_files"
|
||||
|
||||
embl = appsconf["embl"]
|
||||
#embl = appsconf["embl"]
|
||||
|
||||
#import imageio
|
||||
import numpy as np
|
||||
@@ -72,6 +72,7 @@ class EmblMessage(QObject):
|
||||
|
||||
def __init__(self, parent=None, **kwargs):
|
||||
super(EmblMessage, self).__init__(parent, **kwargs)
|
||||
return #ZAC: orig. code
|
||||
if not embl["enabled"]:
|
||||
return
|
||||
context = zmq.Context()
|
||||
|
||||
@@ -34,7 +34,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# from coord_library import conversions
|
||||
#import conversions #ZAC: orig. code
|
||||
from app_config import settings
|
||||
from app_config import AppCfg
|
||||
|
||||
#from storage import Folders #ZAC: orig. code
|
||||
#folders = Folders() #ZAC: orig. code
|
||||
|
||||
123
app_config.py
123
app_config.py
@@ -1,4 +1,3 @@
|
||||
|
||||
#TODO:
|
||||
# currently 2 settings/configs are used
|
||||
# QSettings -> cat ~/.config/Paul\ Scherrer\ Institut/SwissMX.conf
|
||||
@@ -6,54 +5,102 @@
|
||||
# QSettings are changed by program
|
||||
# #yaml is fixed and not altened by program
|
||||
|
||||
import yaml
|
||||
from PyQt5.QtCore import QSettings
|
||||
from pathlib import Path
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
import os
|
||||
from PyQt5.QtCore import QSettings
|
||||
#import yaml
|
||||
#from pathlib import Path
|
||||
|
||||
class AppCfg(QSettings):
|
||||
SKIP_ESCAPE_TRANSITIONS_IF_SAFE="escape/skip_transitions_if_safe"
|
||||
|
||||
BEAM_MARKER_POSITIONS="beam/marker_positions"
|
||||
BEAM_SIZE="beam/size"
|
||||
|
||||
CRYOJET_MOTION_ENABLED="cryojet/motion_enabled"
|
||||
CRYOJET_NOZZLE_OUT="cryojet/nozzle_out"
|
||||
CRYOJET_NOZZLE_IN="cryojet/nozzle_in"
|
||||
|
||||
DELTATAU_SHOW_PLOTS="deltatau/show_plots"
|
||||
DELTATAU_OMEGACOS="deltatau/omegacos"
|
||||
DELTATAU_SORT_POINTS="deltatau/sort_points"
|
||||
DELTATAU_VELOCITY_SCALE="deltatau/velocity_scale"
|
||||
|
||||
CAMERA_TRANSFORMATIONS="camera/transformations"
|
||||
CAMERA_ZOOM_TO_PPM="camera/zoom_to_ppm"
|
||||
|
||||
EXPERIMENT_PGROUP="experiment/pgroup"
|
||||
EXPERIMENT_UID="experiment/uid"
|
||||
|
||||
ACTIVATE_PULSE_PICKER="scanning/activate_pulse_picker"
|
||||
|
||||
def __init__(self):
|
||||
super(AppCfg, self).__init__("PSI", "SwissMX")
|
||||
keys = self.allKeys()
|
||||
if AppCfg.ACTIVATE_PULSE_PICKER not in keys:
|
||||
self.setValue(AppCfg.ACTIVATE_PULSE_PICKER, False)
|
||||
|
||||
if AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE not in keys:
|
||||
self.setValue(AppCfg.SKIP_ESCAPE_TRANSITIONS_IF_SAFE, False)
|
||||
|
||||
if "hits/marker_size" not in keys:
|
||||
self.setValue("hits/marker_size", 10)
|
||||
|
||||
if "graphs/show_auxiliary" not in keys:
|
||||
self.setValue("graphs/show_auxiliary", False)
|
||||
|
||||
if "graphs/auxiliary_graph_index" not in keys:
|
||||
self.setValue("graphs/auxiliary_graph_index", 0)
|
||||
|
||||
if "scan_request/last_location" not in keys:
|
||||
d10 = os.path.join(os.path.expanduser("~"), "Data10")
|
||||
self.setValue("scan_request/last_location", d10)
|
||||
|
||||
if AppCfg.BEAM_SIZE in keys:
|
||||
_log.info("setting beamsize from stored settings: {}".format(self.value(AppCfg.BEAM_SIZE)))
|
||||
else:
|
||||
_log.warning("beam size may not reflect reality, please check")
|
||||
self.setValue(AppCfg.BEAM_SIZE, (40, 20))
|
||||
|
||||
|
||||
settings = QSettings("PSI", "SwissMX")
|
||||
def option(self,key: str) -> bool:
|
||||
try:
|
||||
return self.value(key, type=bool)
|
||||
except:
|
||||
_log.error(f"option {key} not known")
|
||||
return False
|
||||
|
||||
inst_folder = Path(__file__).absolute().parent
|
||||
def toggle_option(self,key: str):
|
||||
v = self.value(key, type=bool)
|
||||
self.setValue(key, not v)
|
||||
self.sync()
|
||||
|
||||
config_file = inst_folder / "swissmx.yaml"
|
||||
configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader)
|
||||
endstation = configs["configure_for"]
|
||||
appsconf = configs[endstation]
|
||||
|
||||
simulated = appsconf.get("simulate", False)
|
||||
#inst_folder = Path(__file__).absolute().parent
|
||||
#config_file = inst_folder / "swissmx.yaml"
|
||||
#configs = yaml.load(config_file.read_text(),Loader=yaml.FullLoader)
|
||||
#endstation = configs["configure_for"]
|
||||
#appsconf = configs[endstation]
|
||||
#simulated = appsconf.get("simulate", False)
|
||||
#logger.info(f"configuring for endstation: {endstation.upper()}")
|
||||
|
||||
logger.info(f"configuring for endstation: {endstation.upper()}")
|
||||
|
||||
if simulated:
|
||||
logger.warning("SIMULATION is ACTIVE")
|
||||
css_file = inst_folder / "swissmx.css"
|
||||
#if simulated:
|
||||
# logger.warning("SIMULATION is ACTIVE")
|
||||
#css_file = inst_folder / "swissmx.css"
|
||||
|
||||
|
||||
|
||||
def font(name: str) -> str:
|
||||
p = Path(__file__).absolute().parent / "fonts" / name
|
||||
return str(p)
|
||||
#def font(name: str) -> str:
|
||||
# p = Path(__file__).absolute().parent / "fonts" / name
|
||||
# return str(p)
|
||||
|
||||
|
||||
def logo(size: int = 0) -> str:
|
||||
p = Path(__file__).absolute().parent / "logos" / "logo.png"
|
||||
if size:
|
||||
p = Path(__file__).absolute().parent / "logos" / f"tell_logo_{size}x{size}.png"
|
||||
return str(p)
|
||||
#def logo(size: int = 0) -> str:
|
||||
# p = Path(__file__).absolute().parent / "logos" / "logo.png"
|
||||
# if size:
|
||||
# p = Path(__file__).absolute().parent / "logos" / f"tell_logo_{size}x{size}.png"
|
||||
# return str(p)
|
||||
|
||||
|
||||
def option(key: str) -> bool:
|
||||
try:
|
||||
return settings.value(key, type=bool)
|
||||
except:
|
||||
logger.error(f"option {key} not known")
|
||||
return False
|
||||
|
||||
|
||||
def toggle_option(key: str):
|
||||
v = settings.value(key, type=bool)
|
||||
settings.setValue(key, not v)
|
||||
settings.sync()
|
||||
|
||||
12
camera.py
12
camera.py
@@ -341,6 +341,15 @@ if __name__ == "__main__":
|
||||
exit(0)
|
||||
n += 1
|
||||
else:
|
||||
def closeEvent(cam,evt):
|
||||
print(args)
|
||||
try:
|
||||
pv=cam._pv['pic']
|
||||
pv.clear_auto_monitor() # disconnect PV monitor callback -> program exit faster.
|
||||
except AttributeError:
|
||||
_log.warning('disconnect PV callback failed.')
|
||||
|
||||
|
||||
class UIcamera(epics_cam):
|
||||
|
||||
def __init__(self, prefix="ESB-MX-CAM"):
|
||||
@@ -446,7 +455,7 @@ if __name__ == "__main__":
|
||||
|
||||
## Display the data and assign each frame a time value from 1.0 to 3.0
|
||||
cam = UIcamera(prefix=args.prefix)
|
||||
|
||||
win.closeEvent=lambda x:closeEvent(cam, x)
|
||||
|
||||
#cam.set_binning(4,4)
|
||||
#cam.run()
|
||||
@@ -470,3 +479,4 @@ if __name__ == "__main__":
|
||||
## Start Qt event loop unless running in interactive mode.
|
||||
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
||||
QtGui.QApplication.instance().exec_()
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from PyQt5 import QtWidgets, QtGui
|
||||
from PyQt5.QtWidgets import QWidget, QSizePolicy, QVBoxLayout, QDoubleSpinBox, QMessageBox
|
||||
|
||||
from app_config import option, toggle_option
|
||||
from app_config import AppCfg #option, toggle_option
|
||||
|
||||
|
||||
def toggle_warn(key):
|
||||
|
||||
236
swissmx.py
236
swissmx.py
@@ -28,6 +28,16 @@ logging.getLogger('matplotlib').setLevel(logging.INFO)
|
||||
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
|
||||
_log = logging.getLogger("swissmx")
|
||||
|
||||
import time
|
||||
class timestamp():
|
||||
def __init__(self):
|
||||
self.t=time.time()
|
||||
def log(self,txt):
|
||||
t=time.time()
|
||||
print(txt+f'{t-self.t:6.3g}')
|
||||
self.t=t
|
||||
ts=timestamp()
|
||||
ts.log('Import part 1/7:')
|
||||
import sys, os, time
|
||||
import json, re
|
||||
import random, signal
|
||||
@@ -40,27 +50,6 @@ import random, signal
|
||||
#from helicalscan import HelicalScanGui #ZAC: orig. code
|
||||
# publisher = pubber.Publisher()
|
||||
|
||||
SKIP_ESCAPE_TRANSITIONS_IF_SAFE = "escape/skip_transitions_if_safe"
|
||||
|
||||
BEAM_MARKER_POSITIONS = "beam/marker_positions"
|
||||
BEAM_SIZE = "beam/size"
|
||||
|
||||
CRYOJET_MOTION_ENABLED = "cryojet/motion_enabled"
|
||||
CRYOJET_NOZZLE_OUT = "cryojet/nozzle_out"
|
||||
CRYOJET_NOZZLE_IN = "cryojet/nozzle_in"
|
||||
|
||||
DELTATAU_SHOW_PLOTS = "deltatau/show_plots"
|
||||
DELTATAU_OMEGACOS = "deltatau/omegacos"
|
||||
DELTATAU_SORT_POINTS = "deltatau/sort_points"
|
||||
DELTATAU_VELOCITY_SCALE = "deltatau/velocity_scale"
|
||||
|
||||
CAMERA_TRANSFORMATIONS = "camera/transformations"
|
||||
CAMERA_ZOOM_TO_PPM = "camera/zoom_to_ppm"
|
||||
|
||||
EXPERIMENT_PGROUP = "experiment/pgroup"
|
||||
EXPERIMENT_UID = "experiment/uid"
|
||||
|
||||
ACTIVATE_PULSE_PICKER = "scanning/activate_pulse_picker"
|
||||
|
||||
TASK_JUNGFRAU_SETTINGS = "jungfrau_settings"
|
||||
TASK_SETUP_PPM_CALIBRATION = "ppm_calibration"
|
||||
@@ -74,7 +63,7 @@ TASK_GRID = "grid"
|
||||
TASK_PRELOCATED = "prelocated"
|
||||
TASK_HELICAL = "helical"
|
||||
TASK_EMBL = "embl"
|
||||
|
||||
ts.log('Import part 2/7:')
|
||||
import PrelocatedCoordinatesModel # ZAC: orig. code
|
||||
from EmblModule import EmblWidget #ZAC: orig. code
|
||||
from HelicalTable import HelicalTableWidget #ZAC: orig. code
|
||||
@@ -84,7 +73,7 @@ from HelicalTable import HelicalTableWidget #ZAC: orig. code
|
||||
#import mx_swissfel #ZAC: orig. code
|
||||
#swissfel = mx_swissfel.SwissFELMachine() #ZAC: orig. code
|
||||
#from bernina_pulse_picker import pulsePicker #ZAC: orig. code
|
||||
|
||||
ts.log('Import part 3/7:')
|
||||
import qtawesome
|
||||
import qutilities
|
||||
from PyQt5 import QtCore, QtGui
|
||||
@@ -95,7 +84,7 @@ from PyQt5.QtWidgets import (
|
||||
QMessageBox, QPlainTextEdit, QProgressBar, QProgressDialog, QPushButton, QShortcut, QSizePolicy, QSpinBox,
|
||||
QSplashScreen, QTextBrowser, QToolBox, QVBoxLayout, QWidget,)
|
||||
from PyQt5.uic import loadUiType
|
||||
|
||||
ts.log('Import part 4/7:')
|
||||
import CustomROI as CstROI
|
||||
#from CustomROI import BeamMark, Grid, CrystalCircle #ZAC: orig. code
|
||||
#from GenericDialog import GenericDialog #ZAC: orig. code
|
||||
@@ -104,21 +93,21 @@ import CustomROI as CstROI
|
||||
from epics_widgets.MotorTweak import MotorTweak
|
||||
from epics_widgets.SmaractMotorTweak import SmaractMotorTweak
|
||||
from epics_widgets.SimMotorTweak import SimMotorTweak
|
||||
|
||||
|
||||
ts.log('Import part 5/7:')
|
||||
from matplotlib import pyplot
|
||||
import numpy as np
|
||||
import pyqtgraph as pg
|
||||
import pyqtgraph.exporters
|
||||
# use antialias for draw lines, interpret image data as row-major instead of col-major
|
||||
pg.setConfigOptions(antialias=True,imageAxisOrder='row-major')
|
||||
|
||||
ts.log('Import part 6/7:')
|
||||
import app_utils
|
||||
from app_config import settings, appsconf, option, toggle_option, simulated
|
||||
from app_config import AppCfg #settings, option, toggle_option
|
||||
|
||||
import epics
|
||||
from epics.ca import pend_event
|
||||
import camera,backlight,zoom,illumination,geometry
|
||||
ts.log('Import part 7/7:')
|
||||
|
||||
|
||||
#_URL = "http://PC12288:8080"
|
||||
@@ -386,7 +375,9 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
tbox.layout().addWidget(htab)
|
||||
|
||||
def add_beam_marker(self):
|
||||
w, h = settings.value(BEAM_SIZE)
|
||||
app = QApplication.instance()
|
||||
cfg = app._cfg
|
||||
w, h = cfg.value(AppCfg.BEAM_SIZE)
|
||||
self._beammark = CstROI.BeamMark([100, 100], (int(w), int(h)), parent=self)
|
||||
self.vb.addItem(self._beammark)
|
||||
|
||||
@@ -422,6 +413,8 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
self.img.setImage(pic)
|
||||
|
||||
def init_settings_tracker(self):
|
||||
app=QApplication.instance()
|
||||
cfg=app._cfg
|
||||
_log.info("configuring widget persistence")
|
||||
fields = {
|
||||
# 'folder': (self._label_folder, str),
|
||||
@@ -434,7 +427,7 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
}
|
||||
for key, f_config in fields.items():
|
||||
widget, conv = f_config
|
||||
value = settings.value(key)
|
||||
value = cfg.value(key)
|
||||
try:
|
||||
wset, wget = widget.setText, widget.text
|
||||
_log.debug("tracking text field {}".format(key))
|
||||
@@ -530,8 +523,10 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
_log.warning("failed writing {}".format(fname))
|
||||
|
||||
def persist_setting(self, s, v):
|
||||
app=QApplication.instance()
|
||||
cfg=app._cfg
|
||||
_log.debug("persisting {} = {}".format(s, v))
|
||||
settings.setValue(s, v)
|
||||
cfg.setValue(s, v)
|
||||
|
||||
def method_changed(self, index):
|
||||
method = self._tabs_daq_methods.currentWidget().accessibleName()
|
||||
@@ -2477,8 +2472,8 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
self._grids = []
|
||||
tab = self._tab_daq_method_grid
|
||||
layout = tab.layout() # gridlayout
|
||||
self._sb_grid_x_step.setValue(30.0)
|
||||
self._sb_grid_y_step.setValue(30.0)
|
||||
self._sb_grid_x_step.setValue(30)
|
||||
self._sb_grid_y_step.setValue(30)
|
||||
self._bt_add_grid.clicked.connect(self.daq_grid_add_grid)
|
||||
self._bt_remove_all_grids.clicked.connect(self.daq_grid_remove_all)
|
||||
self._find_targets_from_microscope_image.clicked.connect(
|
||||
@@ -2564,6 +2559,8 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
cont.layout().addWidget(w)
|
||||
|
||||
def init_actions(self):
|
||||
app = QApplication.instance()
|
||||
cfg = app._cfg
|
||||
self.toolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
|
||||
|
||||
self.shortcut = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_S), self)
|
||||
@@ -2611,8 +2608,8 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
# icon = qtawesome.icon("material.shutter_speed")
|
||||
action = QAction("Use Pulse Picker", self)
|
||||
action.setCheckable(True)
|
||||
action.setChecked(option(ACTIVATE_PULSE_PICKER))
|
||||
action.triggered.connect(lambda: toggle_option(ACTIVATE_PULSE_PICKER))
|
||||
action.setChecked(cfg.option(AppCfg.ACTIVATE_PULSE_PICKER))
|
||||
action.triggered.connect(lambda: cfg.toggle_option(AppCfg.ACTIVATE_PULSE_PICKER))
|
||||
self.toolBar.addAction(action)
|
||||
|
||||
icon = qtawesome.icon("material.timeline")
|
||||
@@ -3120,60 +3117,33 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
|
||||
def init_settings(self):
|
||||
app = QApplication.instance()
|
||||
# settings = Settings
|
||||
#global folders
|
||||
s = settings
|
||||
keys = s.allKeys()
|
||||
|
||||
if ACTIVATE_PULSE_PICKER not in keys:
|
||||
settings.setValue(ACTIVATE_PULSE_PICKER, False)
|
||||
|
||||
if SKIP_ESCAPE_TRANSITIONS_IF_SAFE not in keys:
|
||||
settings.setValue(SKIP_ESCAPE_TRANSITIONS_IF_SAFE, False)
|
||||
cfg = app._cfg
|
||||
keys = cfg.allKeys()
|
||||
|
||||
#if EXPERIMENT_PGROUP not in keys:
|
||||
# self.update_user_and_storage()
|
||||
|
||||
if "hits/marker_size" not in keys:
|
||||
settings.setValue("hits/marker_size", 10)
|
||||
|
||||
if "window/geometry" in keys:
|
||||
self.restoreGeometry(s.value("window/geometry", ""))
|
||||
self.restoreState(s.value("window/windowState", ""))
|
||||
self.restoreGeometry(cfg.value("window/geometry", ""))
|
||||
self.restoreState(cfg.value("window/windowState", ""))
|
||||
|
||||
if "window/main_splitter" in keys:
|
||||
sizes = [int(s) for s in s.value("window/main_splitter")]
|
||||
sizes = [int(s) for s in cfg.value("window/main_splitter")]
|
||||
self._main_splitter.setSizes(sizes)
|
||||
else:
|
||||
self._main_splitter.setSizes([500, 1200])
|
||||
|
||||
if "graphs/show_auxiliary" not in keys:
|
||||
s.setValue("graphs/show_auxiliary", False)
|
||||
|
||||
if "graphs/auxiliary_graph_index" not in keys:
|
||||
s.setValue("graphs/auxiliary_graph_index", 0)
|
||||
|
||||
if "scan_request/last_location" not in keys:
|
||||
d10 = os.path.join(os.path.expanduser("~"), "Data10")
|
||||
s.setValue("scan_request/last_location", d10)
|
||||
|
||||
if BEAM_MARKER_POSITIONS in keys:
|
||||
self._beam_markers = s.value(BEAM_MARKER_POSITIONS)
|
||||
if AppCfg.BEAM_MARKER_POSITIONS in keys:
|
||||
self._beam_markers = s.value(AppCfg.BEAM_MARKER_POSITIONS)
|
||||
self.update_beam_marker_fitters()
|
||||
_log.info("read beam markers {}".format(self._beam_markers))
|
||||
|
||||
if BEAM_SIZE in keys:
|
||||
_log.info("setting beamsize from stored settings: {}".format(s.value(BEAM_SIZE)))
|
||||
else:
|
||||
_log.warning("beam size may not reflect reality, please check")
|
||||
s.setValue(BEAM_SIZE, (40, 20))
|
||||
if AppCfg.CAMERA_TRANSFORMATIONS in keys:
|
||||
app._camera.set_transformations(s.value(AppCfg.CAMERA_TRANSFORMATIONS))
|
||||
|
||||
if CAMERA_TRANSFORMATIONS in keys:
|
||||
app._camera.set_transformations(s.value(CAMERA_TRANSFORMATIONS))
|
||||
|
||||
if CAMERA_ZOOM_TO_PPM in keys:
|
||||
self._zoom_to_ppm = s.value(CAMERA_ZOOM_TO_PPM)
|
||||
_log.info(f"{CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}")
|
||||
if AppCfg.CAMERA_ZOOM_TO_PPM in keys:
|
||||
self._zoom_to_ppm = s.value(AppCfg.CAMERA_ZOOM_TO_PPM)
|
||||
_log.info(f"{AppCfg.CAMERA_ZOOM_TO_PPM} updated: {self._zoom_to_ppm}")
|
||||
self.update_ppm_fitters()
|
||||
|
||||
def really_quit(self):
|
||||
@@ -3184,11 +3154,9 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""this is called when the user clicks the window's cross icon"""
|
||||
if (
|
||||
self._do_quit
|
||||
or QMessageBox.question( self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes
|
||||
):
|
||||
if (self._do_quit or QMessageBox.question( self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes):
|
||||
app=QApplication.instance()
|
||||
cfg=app._cfg
|
||||
try:
|
||||
pv=app._camera._pv['pic']
|
||||
pv.clear_auto_monitor() # disconnect PV monitor callback -> program exit faster.
|
||||
@@ -3196,10 +3164,10 @@ class Main(QMainWindow, Ui_MainWindow):
|
||||
_log.warning('disconnect PV callback failed.')
|
||||
|
||||
_log.info('disconnect PV callback')
|
||||
settings.setValue("window/geometry", self.saveGeometry())
|
||||
settings.setValue("window/windowState", self.saveState())
|
||||
settings.setValue("window/main_splitter", self._main_splitter.sizes())
|
||||
settings.setValue("last_active", time.time())
|
||||
cfg.setValue("window/geometry", self.saveGeometry())
|
||||
cfg.setValue("window/windowState", self.saveState())
|
||||
cfg.setValue("window/main_splitter", self._main_splitter.sizes())
|
||||
cfg.setValue("last_active", time.time())
|
||||
_log.info('save settings')
|
||||
#QMainWindow.closeEvent(self, event)
|
||||
_log.info('closeEvent done')
|
||||
@@ -3242,6 +3210,27 @@ def sigint_handler(*args):
|
||||
app.quit()
|
||||
|
||||
|
||||
class StartupSplash:
|
||||
|
||||
def __init__(self):
|
||||
splash_pix = QPixmap("artwork/logo/256x256.png")
|
||||
self._wnd=splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
|
||||
splash.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
|
||||
splash.setEnabled(False)
|
||||
|
||||
self._prgsBar=prgs=QProgressBar(splash)
|
||||
prgs.setMaximum(100)
|
||||
prgs.setGeometry(0, splash_pix.height() - 50, splash_pix.width(), 20)
|
||||
|
||||
splash.show()
|
||||
|
||||
def set(self,i,msg):
|
||||
self._prgsBar.setValue(i)
|
||||
self._wnd.showMessage(f"<font color='red'>{msg}</font></h1>", int(Qt.AlignBottom|Qt.AlignCenter), Qt.black)
|
||||
app=QApplication.instance()
|
||||
app.processEvents()
|
||||
time.sleep(.1)
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
@@ -3253,38 +3242,11 @@ def main():
|
||||
args = parser.parse_args()
|
||||
_log.info('Arguments:{}'.format(args.__dict__))
|
||||
|
||||
# needed so pycharm can restart application
|
||||
signal.signal(signal.SIGINT, sigint_handler)
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
# set app icon
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
app._args=args
|
||||
|
||||
if args.sim&0x01:
|
||||
app._backlight = backlight.Backlight(None)
|
||||
else:
|
||||
app._backlight = backlight.Backlight()
|
||||
if args.sim&0x02:
|
||||
app._illumination = illumination.IlluminationControl(None)
|
||||
else:
|
||||
app._illumination = illumination.IlluminationControl()
|
||||
if args.sim&0x04:
|
||||
app._zoom = zoom.QopticZoom(None)
|
||||
else:
|
||||
app._zoom = zoom.QopticZoom()
|
||||
if args.sim&0x08:
|
||||
app._camera = camera.epics_cam(None)
|
||||
app._camera.sim_gen(mode=1)
|
||||
else:
|
||||
app._camera = camera.epics_cam()
|
||||
#app._camera.run() is called in center_piece_update
|
||||
app._geometry=geometry.geometry()
|
||||
|
||||
|
||||
|
||||
app_icon = QtGui.QIcon()
|
||||
app_icon.addFile("artwork/logo/16x16.png", QtCore.QSize(16, 16))
|
||||
app_icon.addFile("artwork/logo/24x24.png", QtCore.QSize(24, 24))
|
||||
@@ -3293,29 +3255,55 @@ def main():
|
||||
app_icon.addFile("artwork/logo/256x256.png", QtCore.QSize(256, 256))
|
||||
app.setWindowIcon(app_icon)
|
||||
|
||||
splash_pix = QPixmap("artwork/logo/256x256.png")
|
||||
splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
|
||||
splash.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
|
||||
splash.setEnabled(False)
|
||||
startupWin=StartupSplash()
|
||||
|
||||
progressBar = QProgressBar(splash)
|
||||
progressBar.setMaximum(10)
|
||||
progressBar.setGeometry(0, splash_pix.height() - 50, splash_pix.width(), 20)
|
||||
#for i in range(1, 20):
|
||||
# startupWin.set(i,f'sample startup text {i}')
|
||||
# #app.processEvents()
|
||||
# t = time.time()
|
||||
# #while time.time() < t + 0.1:
|
||||
# # app.processEvents()
|
||||
|
||||
splash.show()
|
||||
# splash.showMessage("<h1><font color='red'>Solid support scanning brought to you by</font></h1>", Qt.AlignTop | Qt.AlignCenter, Qt.black)
|
||||
#app._settings=QSettings("PSI", "SwissMX")
|
||||
|
||||
for i in range(1, 11):
|
||||
progressBar.setValue(i)
|
||||
t = time.time()
|
||||
while time.time() < t + 0.1:
|
||||
app.processEvents()
|
||||
app._args=args
|
||||
|
||||
startupWin.set(5, f'load settings')
|
||||
app._cfg=AppCfg()
|
||||
app._geometry=geometry.geometry()
|
||||
|
||||
startupWin.set(15, f'connect backlight')
|
||||
if args.sim&0x01:
|
||||
app._backlight = backlight.Backlight(None)
|
||||
else:
|
||||
app._backlight = backlight.Backlight()
|
||||
startupWin.set(20, f'connect illumination')
|
||||
if args.sim&0x02:
|
||||
app._illumination = illumination.IlluminationControl(None)
|
||||
else:
|
||||
app._illumination = illumination.IlluminationControl()
|
||||
startupWin.set(40, f'connect zoom')
|
||||
if args.sim&0x04:
|
||||
app._zoom = zoom.QopticZoom(None)
|
||||
else:
|
||||
app._zoom = zoom.QopticZoom()
|
||||
startupWin.set(60, f'connect camera')
|
||||
if args.sim&0x08:
|
||||
app._camera = camera.epics_cam(None)
|
||||
app._camera.sim_gen(mode=1)
|
||||
else:
|
||||
app._camera = camera.epics_cam()
|
||||
#app._camera.run() is called in center_piece_update
|
||||
|
||||
startupWin.set(60, f'start main window')
|
||||
|
||||
main = Main()
|
||||
main.show()
|
||||
splash.finish(main)
|
||||
startupWin._wnd.finish(main)
|
||||
|
||||
# needed so pycharm can restart application
|
||||
signal.signal(signal.SIGINT, sigint_handler)
|
||||
|
||||
#main.update_user_and_storage() #ZAC: orig. code
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
18
zoom.py
18
zoom.py
@@ -32,7 +32,7 @@ from PyQt5.uic import loadUiType
|
||||
|
||||
import backlight, illumination, camera
|
||||
import epics
|
||||
from app_config import settings
|
||||
from app_config import AppCfg #settings
|
||||
|
||||
Ui_Zoom, QWidget = loadUiType("zoom.ui")
|
||||
MIN_ZOOM = 1
|
||||
@@ -50,19 +50,21 @@ class Zoom(QGroupBox, Ui_Zoom):
|
||||
self.setTitle("Sample Viewing")
|
||||
|
||||
def configure(self):
|
||||
keys = settings.allKeys()
|
||||
app=QApplication.instance()
|
||||
cfg=app._cfg
|
||||
keys=cfg.allKeys()
|
||||
if "sample_viewing/zoom_buttons" not in keys:
|
||||
settings.setValue("sample_viewing/zoom_buttons",
|
||||
cfg.setValue("sample_viewing/zoom_buttons",
|
||||
json.dumps([(1, "1"),(200, "200"),(400, "400"),(600, "600"),(800, "800"),(1000, "1000"),]),)
|
||||
buttons = json.loads(settings.value("sample_viewing/zoom_buttons"))
|
||||
buttons = json.loads(cfg.value("sample_viewing/zoom_buttons"))
|
||||
|
||||
if "backlight/backlight_pv" not in keys:
|
||||
settings.setValue("backlight/backlight_pv", "SAR-EXPMX:MOT_BLGT")
|
||||
backlight_pv = settings.value("backlight/backlight_pv")
|
||||
cfg.setValue("backlight/backlight_pv", "SAR-EXPMX:MOT_BLGT")
|
||||
backlight_pv = cfg.value("backlight/backlight_pv")
|
||||
|
||||
if "sample_viewing/zoom_api" not in keys:
|
||||
settings.setValue("sample_viewing/zoom_api", "rest://pc12818.psi.ch:9999")
|
||||
zoom_api = settings.value("sample_viewing/zoom_api")
|
||||
cfg.setValue("sample_viewing/zoom_api", "rest://pc12818.psi.ch:9999")
|
||||
zoom_api = cfg.value("sample_viewing/zoom_api")
|
||||
|
||||
#self.get_zoom_pv = PV(zoom_api + ":ZOOM-RBV", callback=self.zoom_update_cb)
|
||||
#self.status_pv = PV(zoom_api + ":ZOOM-STATUS", callback=self.zoom_status_cb)
|
||||
|
||||
Reference in New Issue
Block a user