Source code for lavuelib.configDialog

# Copyright (C) 2017  DESY, Notkestr. 85, D-22607 Hamburg
#
# lavue is an image viewing program for photon science imaging detectors.
# Its usual application is as a live viewer using hidra as data source.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation in  version 2
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA  02110-1301, USA.
#
# Authors:
#     Jan Kotanski <jan.kotanski@desy.de>
#     Christoph Rosemann <christoph.rosemann@desy.de>
#

""" configuration widget """

from .qtuic import uic
import pyqtgraph as _pg
from pyqtgraph import QtCore
import os
import json
import logging

try:
    from pyqtgraph import QtWidgets
except Exception:
    from pyqtgraph import QtGui as QtWidgets

from . import edDictDialog

_formclass, _baseclass = uic.loadUiType(
    os.path.join(os.path.dirname(os.path.abspath(__file__)),
                 "ui", "ConfigDialog.ui"))

logger = logging.getLogger("lavue")


[docs]class TableWidgetDragCheckBoxes(QtWidgets.QTableWidget): """ TableWidget with drag and drop checkboxes """ def __init__(self, parent): """ constructor :param parent: parent object :type parent: :class:`pyqtgraph.QtCore.QObject` """ QtWidgets.QTableWidget.__init__(self, parent) #: (:obj:`list` < [ :obj:`str`, :obj:`bool` ] > ) checkbox item list self.__checkboxdata = [] #: (:obj:`list` < :obj:`str`, :obj:`str` > ) checkbox name items self.__nameitems = {} self.setDragEnabled(True) self.setAcceptDrops(True) self.viewport().setAcceptDrops(True) self.setDropIndicatorShown(True) self.setDragDropOverwriteMode(False) self.setDragDropMode( QtWidgets.QAbstractItemView.InternalMove) self.setSelectionMode( QtWidgets.QAbstractItemView.ExtendedSelection) self.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectRows) self.setColumnCount(1) self.horizontalHeader().hide() self.verticalHeader().hide() self.horizontalHeader().setStretchLastSection(True)
[docs] def create(self, selected, available, itemnames=None): """ populates table :param selected: all selected aliases :type selected: :obj:`list` < :obj:`str`> :param available: all available aliases :type available: :obj:`list` < :obj:`str`> :param itemnames: dictionary of alias names :type itemnames: :obj:`dict` < :obj:`str`, :obj:`str`> """ self.__checkboxdata = [] itemnames = itemnames or {} self.__nameitems = {v: k for k, v in itemnames.items()} for sel in selected: if sel in available: self.__checkboxdata.append([sel, True]) if self.__checkboxdata: for av in available: if av not in selected: self.__checkboxdata.append([av, False]) else: for av in available: self.__checkboxdata.append([av, True]) self.setRowCount(len(self.__checkboxdata)) for i, (name, checked) in enumerate(self.__checkboxdata): nm = str(name) iname = itemnames[nm] if nm in itemnames else nm item = QtWidgets.QTableWidgetItem(iname) item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable) item.setCheckState(QtCore.Qt.Checked if checked else QtCore.Qt.Unchecked) self.setItem(i, 0, item)
[docs] def getChecks(self, available): """ update checks in checkboxdata :param available: all available aliases :type available: :obj:`list` < :obj:`str`> :returns: all selected aliases :rtype: :obj:`list` < :obj:`str`> """ selected = [] for ri, (name, checked) in enumerate(self.__checkboxdata): ridx = self.model().index(ri, 0) chst = self.model().data(ridx, QtCore.Qt.CheckStateRole) if hasattr(chst, "toBool"): chst = chst.toBool() self.__checkboxdata[ri][1] = bool(chst) name = self.model().data(ridx, QtCore.Qt.DisplayRole) if hasattr(name, "toString"): name = name.toString() name = str(name) self.__checkboxdata[ri][0] = self.__nameitems[name] \ if name in self.__nameitems else name if self.__checkboxdata[ri][1]: selected.append(str(self.__checkboxdata[ri][0])) if selected == available: selected = [] return selected
[docs] def dropEvent(self, event): """ replaces rows in the table :param event: drop event :type event: :class:`pyqtgraph.QtCore.QEvent`: """ if not event.isAccepted(): if event.source() == self: targetidx = self._target_row(event) selrows = sorted( set(item.row() for item in self.selectedItems())) tomove = [ QtWidgets.QTableWidgetItem(self.item(idx, 0)) for idx in selrows ] for idx in reversed(selrows): self.removeRow(idx) if idx < targetidx: targetidx -= 1 for idx, data in enumerate(tomove): idx += targetidx self.insertRow(idx) self.setItem(idx, 0, data) event.accept() QtWidgets.QTableWidget.dropEvent(self, event)
def _target_row(self, event): """ provides target row index to drop :param event: drop event :type event: :class:`pyqtgraph.QtCore.QEvent` :returns: target row index to drop :rtype: :obj:`int` """ idx = self.indexAt(event.pos()) if not idx.isValid(): return self.rowCount() return idx.row()
[docs]class ConfigDialog(QtWidgets.QDialog): def __init__(self, parent=None): """ constructor :param parent: parent object :type parent: :class:`pyqtgraph.QtCore.QObject` """ QtWidgets.QDialog.__init__(self, parent) #: (:class:`Ui_ConfigDialog') ui_dialog object from qtdesigner self.__ui = _formclass() self.__ui.setupUi(self) self.__ui.isLayout = QtWidgets.QGridLayout(self.__ui.isWidget) self.__ui.isLayout.setContentsMargins(0, 0, 0, 0) self.__ui.isTable = TableWidgetDragCheckBoxes(self) self.__ui.isLayout.addWidget(self.__ui.isTable) self.__ui.twLayout = QtWidgets.QGridLayout(self.__ui.twWidget) self.__ui.twLayout.setContentsMargins(0, 0, 0, 0) self.__ui.twTable = TableWidgetDragCheckBoxes(self) self.__ui.twLayout.addWidget(self.__ui.twTable) #: (:obj:`str`) device name of sardana door self.door = "" #: (:obj:`bool`) sardana enabled self.sardana = True #: (:obj:`bool`) add rois enabled self.addrois = False #: (:obj:`bool`) fetch rois order enabled self.orderrois = False #: (:obj:`bool`) security stream enabled self.secstream = False #: (:obj:`bool`) zmq colon configuration separator self.zmqcolon = False #: (:obj:`bool`) map image sources to color channels self.imagechannels = False #: (:obj:`str`) security stream port self.secport = "5657" #: (:obj:`str`) hidra data port self.hidraport = '["50001"]' #: (:obj:`bool`) find security stream port automatically self.secautoport = True #: (:obj:`float`) refresh time in s self.refreshtime = 0.2 #: (:obj:`bool`) auto enlarge refresh time self.autorefreshtime = True #: (:obj:`float`) tool refresh time is s self.toolrefreshtime = 0.02 #: (:obj:`float`) tool polling interval is s self.toolpollinginterval = 1.0 #: (:obj:`str`) maximal number of images in memory buffer self.maxmbuffersize = "1000" #: (:obj:`str`) float type for pixel intensity self.floattype = "float" #: (:obj:`bool`) show color distribution histogram widget self.showhisto = True #: (:obj:`bool`) show color distribution additional histogram widget self.showaddhisto = False #: (:obj:`bool`) show mask widget self.showmask = False #: (:obj:`bool`) show high value mask widget self.showhighvaluemask = False #: (:obj:`bool`) show intensity overflow widget self.showoverflow = False #: (:obj:`bool`) show statistics widget self.showstats = True #: (:obj:`bool`) show image step widget self.showsteps = True #: (:obj:`bool`) calculate variance self.calcvariance = False #: (:obj:`bool`) zero mask enabled self.zeromask = False #: (:obj:`bool`) nan mask enabled self.nanmask = True #: (:obj:`bool`) adding maximal type value to negative high value mask self.negmask = False #: (:obj:`bool`) show bakcground subtraction widget self.showsub = True #: (:obj:`bool`) show bakcground subtraction scaling factor widget self.showsubsf = False #: (:obj:`bool`) show image normalization widget self.shownorm = True #: (:obj:`bool`) show image normalization scaling factor widget self.shownormsf = False #: (:obj:`bool`) show transformation widget self.showtrans = True #: (:obj:`bool`) show memory buffer widget self.showmbuffer = False #: (:obj:`bool`) show range window widget self.showrange = False #: (:obj:`bool`) show filter widget self.showfilters = False #: (:obj:`bool`) show intensity scale widget self.showscale = True #: (:obj:`bool`) show intensity levels widget self.showlevels = True #: (:obj:`bool`) show frame rate widget self.showframerate = True #: (:obj:`int`) number of image sources self.nrsources = 1 #: (:obj:`int`) image source timeout in ms self.timeout = 3000 #: (:obj:`bool`) aspect ratio locked self.aspectlocked = False #: (:obj:`bool`) statistics without intensity scaling self.statswoscaling = True #: (:obj:`bool`) auto down sample self.autodownsample = False #: (:obj:`bool`) keep original coordinates self.keepcoords = False #: (:obj:`bool`) accelerate buffer sum self.accelbuffersum = False #: (:obj:`bool`) image channels shown with gradient colors self.gradientcolors = False #: (:obj:`bool`) lazy image slider self.lazyimageslider = True #: (:obj:`bool`) crosshair locker switched on self.crosshairlocker = True #: (:obj:`str`) asapo server self.asaposerver = "" #: (:obj:`str`) asapo token self.asapotoken = "" #: (:obj:`str`) asapo beamtime id self.asapobeamtime = "" #: (:obj:`str`) asapo sourcepath self.asaposourcepath = "" #: (:obj:`str`) asapo beamline metadata file self.asapobtmetafile = "/gpfs/current/beamtime-metadata-*.json" #: (:obj:`list` < :obj:`str` > ) asapo datasources self.asapodatasources = [] #: (:obj:`str`) json hidra detector server list self.detservers = "[]" #: (:obj:`bool`) use default detector servers self.defdetservers = True #: (:obj:`list` < :obj:`str`>) list of topics for ZMQ stream source self.zmqtopics = [] #: (:obj:`bool`) topics for ZMQ stream source fetched from the stream self.autozmqtopics = False #: (:obj:`bool`) interrupt on error self.interruptonerror = True #: (:obj:`str`) JSON dictionary with directory and filename translation # for Tango file source self.dirtrans = '{"/ramdisk/": "/gpfs/"}' #: (:obj:`str`) JSON dictionary with {label: tango attribute} # for Tango Attribute source self.tangoattrs = '{}' #: (:obj:`str`) JSON dictionary with {label: tango attribute} # for Tango Attribute Events source self.tangoevattrs = '{}' #: (:obj:`str`) JSON dictionary with {label: file tango attribute} # for Tango Attribute source self.tangofileattrs = '{}' #: (:obj:`str`) JSON dictionary with {label: tina properties} # for Tine Property source self.tineprops = '{}' #: (:obj:`str`) JSON dictionary with {label: dir tango attribute} # for Tango Attribute source self.tangodirattrs = '{}' #: (:obj:`str`) JSON dictionary with {label: doocs property} # for DOOCS Property source self.doocsprops = '{}' #: (:obj:`str`) JSON dictionary with {label: epics PV name} # for Epics PV source self.epicspvnames = '{}' #: (:obj:`str`) JSON dictionary with {label: epics PV shape} # for Epics PV source self.epicspvshapes = '{}' #: (:obj:`str`) JSON dictionary with {label: url} # for HTTP responce source self.httpurls = '{}' #: (:obj:`str`) JSON dictionary with {label: <server:port>} # for ZMQ source self.zmqservers = '{}' #: (:obj:`bool`) nexus file source keeps the file open self.nxsopen = False #: (:obj:`bool`) nexus file source starts from the last image self.nxslast = False #: (:obj:`bool`) store detector geometry self.storegeometry = False #: (:obj:`bool`) fetch geometry from source self.geometryfromsource = False #: (:obj:`str`) json list with filters self.filters = "[]" #: (:obj:`str`) json list with rois colors self.roiscolors = "[]" #: (:obj:`list`<:class:`pyqtgraph.ColorButton`>) # list with rois color widgets self.__roiswidgets = [] #: (:obj:`str`) json list with overflow color self.overflowcolor = "[255, 255, 255]" #: (:class:`pyqtgraph.ColorButton`) # list with rois color widgets self.__overflowcolorwidget = None #: (:obj:`bool`) show all rois flag self.showallrois = False #: (:obj:`bool`) send rois to LavueController flag self.sendrois = False #: (:obj:`bool`) send results to LavueController flag self.sendresults = False #: (:obj:`bool`) set roi1, roi2, roi3, ... when alias names are missing self.singlerois = False #: (:obj:`int`) number of points for diffractogram self.diffnpt = 1000 #: (:obj:`bool`) correct solid angle flag self.correctsolidangle = True #: (:obj:`bool`) store display parameters for specific sources self.sourcedisplay = False #: (:obj:`dict` <:obj: `str`, :obj: `str` >) object title dictionary self.__objtitles = {} #: (:obj:`str`) list with available image source widget names self.availimagesources = [] #: (:obj:`str`) json list with image source widget names self.imagesources = "[]" #: (:obj:`dict` < :obj:`str`, :obj:`str`>) json list with # image source widget names self.imagesourcenames = {} #: (:obj:`str`) list with available tool widget names self.availtoolwidgets = [] #: (:obj:`str`) json list with tool widget names self.toolwidgets = "[]" #: (:obj:`dict` < :obj:`str`, :obj:`str`>) json list with # tool widget names self.toolwidgetnames = {}
[docs] def eventFilter(self, obj, event): """ event filter :param obj: qt object :type obj: :class: `pyqtgraph.QtCore.QObject` :param event: qt event :type event: :class: `pyqtgraph.QtCore.QEvent` :returns: status flag :rtype: :obj:`bool` """ if repr(obj) not in self.__objtitles.keys(): return False if event.type() in \ [QtCore.QEvent.MouseButtonPress, QtCore.QEvent.KeyPress]: if event.type() == QtCore.QEvent.KeyPress: if event.key() != QtCore.Qt.Key_Space: return False record = json.loads(str(obj.text()).strip() or "{}") if not isinstance(record, dict): record = {} dform = edDictDialog.EdDictDialog(self) dform.record = record dform.title = self.__objtitles[repr(obj)] dform.createGUI() dform.exec_() if dform.dirty: for key in list(record.keys()): if not str(key).strip(): record.pop(key) obj.setText(json.dumps(record)) return True return False
[docs] def createGUI(self): """ create GUI """ self.__ui.rateDoubleSpinBox.setValue(self.refreshtime) self.__ui.enlargeCheckBox.setChecked(self.autorefreshtime) self.__ui.nrsourcesSpinBox.setValue(self.nrsources) self.__ui.diffsizeSpinBox.setValue(self.diffnpt) self.__ui.toolrefreshtimeDoubleSpinBox.setValue(self.toolrefreshtime) self.__ui.pollingintervalDoubleSpinBox.setValue( self.toolpollinginterval) self.__ui.aspectlockedCheckBox.setChecked(self.aspectlocked) self.__ui.downsampleCheckBox.setChecked(self.autodownsample) self.__ui.keepCoordsCheckBox.setChecked(self.keepcoords) self.__ui.buffersumCheckBox.setChecked(self.accelbuffersum) self.__ui.gradientcolorsCheckBox.setChecked(self.gradientcolors) self.__ui.lazyimageCheckBox.setChecked(self.lazyimageslider) self.__ui.statsscaleCheckBox.setChecked(not self.statswoscaling) self.__ui.sardanaCheckBox.setChecked(self.sardana) self.__ui.doorLineEdit.setText(self.door) self.__ui.addroisCheckBox.setChecked(self.addrois) self.__ui.orderroisCheckBox.setChecked(self.orderrois) self.__ui.imagechannelsCheckBox.setChecked(self.imagechannels) self.__ui.secstreamCheckBox.setChecked(self.secstream) self.__ui.zmqcolonCheckBox.setChecked(self.zmqcolon) self.__ui.zeromaskCheckBox.setChecked(self.zeromask) self.__ui.nanmaskCheckBox.setChecked(self.nanmask) self.__ui.negmaskCheckBox.setChecked(self.negmask) self.__ui.secautoportCheckBox.setChecked(self.secautoport) self.__ui.secportLineEdit.setText(self.secport) self.__ui.hidraportLineEdit.setText(self.hidraport) self.__ui.hidraportLineEdit.setText( " ".join(json.loads(self.hidraport))) self.__ui.mbufsizeLineEdit.setText(self.maxmbuffersize) self.__ui.showhistoCheckBox.setChecked(self.showhisto) self.__ui.showaddhistoCheckBox.setChecked(self.showaddhisto) self.__ui.showmaskCheckBox.setChecked(self.showmask) self.__ui.showmaskhighCheckBox.setChecked(self.showhighvaluemask) self.__ui.showoverflowCheckBox.setChecked(self.showoverflow) self.__ui.showstatsCheckBox.setChecked(self.showstats) self.__ui.showstepsCheckBox.setChecked(self.showsteps) self.__ui.calcvarianceCheckBox.setChecked(self.calcvariance) self.__ui.showsubCheckBox.setChecked(self.showsub) self.__ui.shownormCheckBox.setChecked(self.shownorm) self.__ui.showsubsfCheckBox.setChecked(self.showsubsf) self.__ui.shownormsfCheckBox.setChecked(self.shownormsf) self.__ui.showtransCheckBox.setChecked(self.showtrans) self.__ui.showmbufferCheckBox.setChecked(self.showmbuffer) self.__ui.showrangeCheckBox.setChecked(self.showrange) self.__ui.showfiltersCheckBox.setChecked(self.showfilters) self.__ui.showscaleCheckBox.setChecked(self.showscale) self.__ui.showlevelsCheckBox.setChecked(self.showlevels) self.__ui.showframerateCheckBox.setChecked(self.showframerate) self.__ui.timeoutLineEdit.setText(str(self.timeout)) self.__ui.zmqtopicsLineEdit.setText(" ".join(self.zmqtopics)) self.__ui.asapodatasourcesLineEdit.setText( " ".join(self.asapodatasources)) self.__ui.detserversLineEdit.setText( " ".join(json.loads(self.detservers))) self.__ui.asaposerverLineEdit.setText(self.asaposerver) self.__ui.asapotokenLineEdit.setText(self.asapotoken) self.__ui.asapobeamtimeLineEdit.setText(self.asapobeamtime) self.__ui.asaposourcepathLineEdit.setText(self.asaposourcepath) self.__ui.asapobtmetafileLineEdit.setText(self.asapobtmetafile) self.__ui.defdetserversCheckBox.setChecked(self.defdetservers) self.__ui.autozmqtopicsCheckBox.setChecked(self.autozmqtopics) self.__ui.interruptCheckBox.setChecked(self.interruptonerror) self.__ui.dirtransLineEdit.setText(self.dirtrans) self.__ui.attrLineEdit.setText(self.tangoattrs) self.__ui.tinepropLineEdit.setText(self.tineprops) self.__ui.doocspropLineEdit.setText(self.doocsprops) self.__ui.pvnameLineEdit.setText(self.epicspvnames) self.__ui.pvshapeLineEdit.setText(self.epicspvshapes) self.__ui.evattrLineEdit.setText(self.tangoevattrs) self.__ui.fileattrLineEdit.setText(self.tangofileattrs) self.__ui.dirattrLineEdit.setText(self.tangodirattrs) self.__ui.zmqserversLineEdit.setText(self.zmqservers) self.__ui.urlsLineEdit.setText(self.httpurls) self.__ui.nxsopenCheckBox.setChecked(self.nxsopen) self.__ui.nxslastCheckBox.setChecked(self.nxslast) self.__ui.storegeometryCheckBox.setChecked(self.storegeometry) self.__ui.fetchgeometryCheckBox.setChecked(self.geometryfromsource) self.__ui.sendroisCheckBox.setChecked(self.sendrois) self.__ui.sendresultsCheckBox.setChecked(self.sendresults) self.__ui.singleroisCheckBox.setChecked(self.singlerois) self.__ui.showallroisCheckBox.setChecked(self.showallrois) self.__ui.sourcedisplayCheckBox.setChecked(self.sourcedisplay) self.__ui.crosshairCheckBox.setChecked(self.crosshairlocker) self.__ui.csaCheckBox.setChecked(self.correctsolidangle) if self.floattype not in ["float", "float32", "float64"]: self.floattype = "float" fid = self.__ui.floatComboBox.findText(self.floattype) if fid < 0: fid = 0 self.__ui.floatComboBox.setCurrentIndex(fid) self.__ui.urlsLineEdit.installEventFilter(self) self.__objtitles[repr(self.__ui.urlsLineEdit)] = \ "HTTP responce url string" self.__ui.attrLineEdit.installEventFilter(self) self.__objtitles[repr(self.__ui.attrLineEdit)] = \ "Tango device/attribute name" self.__ui.evattrLineEdit.installEventFilter(self) self.__objtitles[repr(self.__ui.evattrLineEdit)] = \ "Tango device/attribute name" self.__ui.fileattrLineEdit.installEventFilter(self) self.__objtitles[repr(self.__ui.fileattrLineEdit)] = \ "Tango file device/attribute name" self.__ui.dirattrLineEdit.installEventFilter(self) self.__objtitles[repr(self.__ui.dirattrLineEdit)] = \ "Tango directory device/attribute name" self.__ui.dirtransLineEdit.installEventFilter(self) self.__objtitles[repr(self.__ui.dirtransLineEdit)] = \ "directory translation dictionary" self.__ui.zmqserversLineEdit.installEventFilter(self) self.__objtitles[repr(self.__ui.zmqserversLineEdit)] = \ "zmq server:port name" self.__ui.doocspropLineEdit.installEventFilter(self) self.__objtitles[repr(self.__ui.doocspropLineEdit)] = \ "DOOCS facility/device/location/property name" self._updateSecPortLineEdit(self.secautoport) self.__ui.secautoportCheckBox.stateChanged.connect( self._updateSecPortLineEdit) self.__ui.plusroiPushButton.clicked.connect( self._addROIColorWidgetClicked) self.__ui.minusroiPushButton.clicked.connect( self._removeROIColorWidget) self.__setROIsColorsWidgets() self.__setOverflowColorWidget() self.__setFiltersGroupBox() self.__ui.isTable.create( json.loads(self.imagesources), self.availimagesources, self.imagesourcenames ) self.__ui.twTable.create( json.loads(self.toolwidgets), self.availtoolwidgets, self.toolwidgetnames )
def __setFiltersGroupBox(self): """ updates filter tab widget """ self.__ui.addupPushButton = self.__ui.filterButtonBox.addButton( "Insert Row &Above", QtWidgets.QDialogButtonBox.ActionRole) self.__ui.adddownPushButton = self.__ui.filterButtonBox.addButton( "Insert Row &Below", QtWidgets.QDialogButtonBox.ActionRole) self.__ui.removePushButton = self.__ui.filterButtonBox.addButton( "&Delete Row", QtWidgets.QDialogButtonBox.ActionRole) self.__populateTable(0) self.__ui.addupPushButton.clicked.connect(self.__addup) self.__ui.adddownPushButton.clicked.connect(self.__adddown) self.__ui.filterTableWidget.itemChanged.connect( self.__tableItemChanged) self.__ui.removePushButton.clicked.connect(self.__remove) def __updateRecord(self): fltlist = [] for i in range(self.__ui.filterTableWidget.rowCount()): item = self.__ui.filterTableWidget.item(i, 0) if item is not None: fltname = item.data(QtCore.Qt.EditRole) if hasattr(fltname, "toString"): fltname = fltname.toString() else: fltname = "" item2 = self.__ui.filterTableWidget.item(i, 1) if item2 is not None: params = item2.data(QtCore.Qt.EditRole) if hasattr(params, "toString"): params = params.toString() else: params = "" fltlist.append([fltname or "", params or ""]) filters = json.dumps(fltlist) if self.filters != filters: self.filters = filters return True return False @QtCore.pyqtSlot("QTableWidgetItem*") def __tableItemChanged(self, item): """ changes the current value of the variable :param item: current item :type item: :class:`QtWidgets.QTableWidgetItem` """ self.__updateRecord() @QtCore.pyqtSlot() def __addup(self): """ adds a new record into the table """ row = self.__ui.filterTableWidget.currentRow() fltlist = json.loads(self.filters) if row >= 0 and row <= len(fltlist): fltlist.insert(row, ["", ""]) else: fltlist.insert(0, ["", ""]) self.filters = json.dumps(fltlist) self.__populateTable() self.__updateRecord() @QtCore.pyqtSlot() def __adddown(self): """ adds a new record into the table """ row = self.__ui.filterTableWidget.currentRow() fltlist = json.loads(self.filters) if row >= 0 and row <= len(fltlist): fltlist.insert(row + 1, ["", ""]) else: fltlist.append(["", ""]) self.filters = json.dumps(fltlist) self.__populateTable() self.__updateRecord() @QtCore.pyqtSlot() def __remove(self): """ removes the current record from the table """ row = self.__ui.filterTableWidget.currentRow() fltlist = json.loads(self.filters) if row >= 0 and row < len(fltlist): flt, params = fltlist[row] if QtWidgets.QMessageBox.question( self, "Removing Filter", 'Would you like to remove "%s": "%s" ?' % (flt, params), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.No: return fltlist.pop(row) self.filters = json.dumps(fltlist) self.__populateTable() self.__updateRecord() def __populateTable(self, selected=None): """ populates the group table :param selected: selected property :type selected: :obj:`str` """ fltlist = json.loads(self.filters) self.__ui.filterTableWidget.clear() sitem = None self.__ui.filterTableWidget.setSortingEnabled(False) self.__ui.filterTableWidget.setRowCount(len(fltlist)) headers = ["package.module.class or package.module.function", "initialization parameters"] self.__ui.filterTableWidget.setColumnCount(len(headers)) self.__ui.filterTableWidget.setHorizontalHeaderLabels(headers) for row, fltparams in enumerate(fltlist): flt, params = fltparams item = QtWidgets.QTableWidgetItem(flt or "") item.setData(QtCore.Qt.EditRole, (flt or "")) self.__ui.filterTableWidget.setItem(row, 0, item) item2 = QtWidgets.QTableWidgetItem(params or "") item2.setData(QtCore.Qt.EditRole, (params or "")) self.__ui.filterTableWidget.setItem(row, 1, item2) self.__ui.filterTableWidget.resizeColumnsToContents() self.__ui.filterTableWidget.setSelectionMode( QtWidgets.QAbstractItemView.SingleSelection) # self.__ui.filterTableWidget.horizontalHeader( # ).setStretchLastSection(True) if hasattr(self.__ui.filterTableWidget.horizontalHeader(), "setSectionResizeMode"): self.__ui.filterTableWidget.horizontalHeader().\ setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) else: self.__ui.filterTableWidget.horizontalHeader().\ setResizeMode(1, QtWidgets.QHeaderView.Stretch) if sitem is not None: sitem.setSelected(True) self.__ui.filterTableWidget.setCurrentItem(sitem) def __setROIsColorsWidgets(self): """ updates ROIs colors widgets """ roiscolors = json.loads(self.roiscolors) while len(self.__roiswidgets) > len(roiscolors): self._removeROIColorWidget() for cid, color in enumerate(roiscolors): if cid >= len(self.__roiswidgets): self._addROIColorWidget(tuple(color)) @QtCore.pyqtSlot() def _addROIColorWidgetClicked(self): """ add ROIs colors widgets """ self._addROIColorWidget() def _addROIColorWidget(self, color=None): """ add ROIs colors widgets :param color: color to be added :type color: (int, int, int) """ if color is None: color = (255, 255, 255) cb = _pg.ColorButton(self, color) self.__roiswidgets.append(cb) self.__ui.colorHorizontalLayout.addWidget(cb) def __setOverflowColorWidget(self): """ set Mask color widget """ try: color = tuple(json.loads(self.overflowcolor)) except Exception: color = (255, 255, 255) self.overflowcolor = "[255, 255, 255]" if self.__overflowcolorwidget: cb = self.__overflowcolorwidget self.__overflowcolorwidget = None cb.hide() self.__ui.overflowColorHorizontalLayout.removeWidget(cb) cb = _pg.ColorButton(self, color) self.__overflowcolorwidget = cb self.__ui.overflowColorHorizontalLayout.addWidget(cb) def __readOverflowColor(self): """ takes Mask color from mask color widget """ color = list(self.__overflowcolorwidget.color(mode='byte')[:3]) self.overflowcolor = json.dumps(color) @QtCore.pyqtSlot() def _removeROIColorWidget(self): """ updates ROIs colors widgets """ cb = self.__roiswidgets.pop() cb.hide() self.__ui.colorHorizontalLayout.removeWidget(cb) def __readROIsColors(self): """ takes ROIs colors from rois widgets """ colors = [] for roiswg in self.__roiswidgets: colors.append(list(roiswg.color(mode='byte')[:3])) self.roiscolors = json.dumps(colors) @QtCore.pyqtSlot(int) def _updateSecPortLineEdit(self, value): """ updates zmq security port lineedit widget :param value: if False or 0 set widget enable otherwise disable :param value: :obj:`int` or :obj:`bool` """ if value: self.__ui.secportLineEdit.setEnabled(False) else: self.__ui.secportLineEdit.setEnabled(True)
[docs] @QtCore.pyqtSlot() def accept(self): """ updates class variables with the form content """ self.sardana = self.__ui.sardanaCheckBox.isChecked() self.door = str(self.__ui.doorLineEdit.text()).strip() self.addrois = self.__ui.addroisCheckBox.isChecked() self.orderrois = self.__ui.orderroisCheckBox.isChecked() self.imagechannels = self.__ui.imagechannelsCheckBox.isChecked() self.hidraport = str(self.__ui.hidraportLineEdit.text()).strip() self.maxmbuffersize = str(self.__ui.mbufsizeLineEdit.text()).strip() self.secstream = self.__ui.secstreamCheckBox.isChecked() self.zmqcolon = self.__ui.zmqcolonCheckBox.isChecked() self.zeromask = self.__ui.zeromaskCheckBox.isChecked() self.nanmask = self.__ui.nanmaskCheckBox.isChecked() self.negmask = self.__ui.negmaskCheckBox.isChecked() self.secautoport = self.__ui.secautoportCheckBox.isChecked() self.refreshtime = float(self.__ui.rateDoubleSpinBox.value()) self.autorefreshtime = self.__ui.enlargeCheckBox.isChecked() self.floattype = str(self.__ui.floatComboBox.currentText()) self.toolrefreshtime = float( self.__ui.toolrefreshtimeDoubleSpinBox.value()) self.toolpollinginterval = float( self.__ui.pollingintervalDoubleSpinBox.value()) self.nrsources = int( self.__ui.nrsourcesSpinBox.value()) self.diffnpt = int( self.__ui.diffsizeSpinBox.value()) self.showsub = self.__ui.showsubCheckBox.isChecked() self.shownorm = self.__ui.shownormCheckBox.isChecked() self.showsubsf = self.__ui.showsubsfCheckBox.isChecked() self.shownormsf = self.__ui.shownormsfCheckBox.isChecked() self.showtrans = self.__ui.showtransCheckBox.isChecked() self.showmbuffer = self.__ui.showmbufferCheckBox.isChecked() self.showrange = self.__ui.showrangeCheckBox.isChecked() self.showfilters = self.__ui.showfiltersCheckBox.isChecked() self.showscale = self.__ui.showscaleCheckBox.isChecked() self.showlevels = self.__ui.showlevelsCheckBox.isChecked() self.showframerate = self.__ui.showframerateCheckBox.isChecked() self.showhisto = self.__ui.showhistoCheckBox.isChecked() self.showaddhisto = self.__ui.showaddhistoCheckBox.isChecked() self.showmask = self.__ui.showmaskCheckBox.isChecked() self.showhighvaluemask = self.__ui.showmaskhighCheckBox.isChecked() self.showoverflow = self.__ui.showoverflowCheckBox.isChecked() self.showstats = self.__ui.showstatsCheckBox.isChecked() self.showsteps = self.__ui.showstepsCheckBox.isChecked() self.calcvariance = self.__ui.calcvarianceCheckBox.isChecked() self.aspectlocked = self.__ui.aspectlockedCheckBox.isChecked() self.autodownsample = self.__ui.downsampleCheckBox.isChecked() self.keepcoords = self.__ui.keepCoordsCheckBox.isChecked() self.accelbuffersum = self.__ui.buffersumCheckBox.isChecked() self.gradientcolors = self.__ui.gradientcolorsCheckBox.isChecked() self.lazyimageslider = self.__ui.lazyimageCheckBox.isChecked() self.statswoscaling = not self.__ui.statsscaleCheckBox.isChecked() self.nxsopen = self.__ui.nxsopenCheckBox.isChecked() self.nxslast = self.__ui.nxslastCheckBox.isChecked() self.storegeometry = self.__ui.storegeometryCheckBox.isChecked() self.geometryfromsource = self.__ui.fetchgeometryCheckBox.isChecked() self.sendrois = self.__ui.sendroisCheckBox.isChecked() self.sendresults = self.__ui.sendresultsCheckBox.isChecked() self.singlerois = self.__ui.singleroisCheckBox.isChecked() self.showallrois = self.__ui.showallroisCheckBox.isChecked() self.sourcedisplay = self.__ui.sourcedisplayCheckBox.isChecked() self.defdetservers = self.__ui.defdetserversCheckBox.isChecked() self.crosshairlocker = self.__ui.crosshairCheckBox.isChecked() self.correctsolidangle = self.__ui.csaCheckBox.isChecked() try: dirtrans = str(self.__ui.dirtransLineEdit.text()).strip() mytr = json.loads(dirtrans) if isinstance(mytr, dict): self.dirtrans = dirtrans except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(3) self.__ui.dirtransLineEdit.setFocus(True) return try: attr = str(self.__ui.attrLineEdit.text()).strip() mytr = json.loads(attr) if isinstance(mytr, dict): self.tangoattrs = attr except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(3) self.__ui.attrLineEdit.setFocus(True) return try: prop = str(self.__ui.tinepropLineEdit.text()).strip() mytr = json.loads(prop) if isinstance(mytr, dict): self.tineprops = prop except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(3) self.__ui.tinepropLineEdit.setFocus(True) return try: prop = str(self.__ui.doocspropLineEdit.text()).strip() mytr = json.loads(prop) if isinstance(mytr, dict): self.doocsprops = prop except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(3) self.__ui.doocspropLineEdit.setFocus(True) return try: attr = str(self.__ui.evattrLineEdit.text()).strip() mytr = json.loads(attr) if isinstance(mytr, dict): self.tangoevattrs = attr except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(3) self.__ui.evattrLineEdit.setFocus(True) return try: attr = str(self.__ui.pvnameLineEdit.text()).strip() mytr = json.loads(attr) if isinstance(mytr, dict): self.epicspvnames = attr except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(3) self.__ui.pvnameLineEdit.setFocus(True) return try: attr = str(self.__ui.pvshapeLineEdit.text()).strip() mytr = json.loads(attr) if isinstance(mytr, dict): self.epicspvshapes = attr except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(3) self.__ui.pvshapeLineEdit.setFocus(True) return try: fileattr = str(self.__ui.fileattrLineEdit.text()).strip() mytr = json.loads(fileattr) if isinstance(mytr, dict): self.tangofileattrs = fileattr except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(3) self.__ui.fileattrLineEdit.setFocus(True) return try: dirattr = str(self.__ui.dirattrLineEdit.text()).strip() mytr = json.loads(dirattr) if isinstance(mytr, dict): self.tangodirattrs = dirattr except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(3) self.__ui.dirattrLineEdit.setFocus(True) return try: zmqservers = str(self.__ui.zmqserversLineEdit.text()).strip() mytr = json.loads(zmqservers) if isinstance(mytr, dict): self.zmqservers = zmqservers except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(2) self.__ui.zmqserversLineEdit.setFocus(True) return try: urls = str(self.__ui.urlsLineEdit.text()).strip() mytr = json.loads(urls) if isinstance(mytr, dict): self.httpurls = urls except Exception as e: logger.warning(str(e)) # print(str(e)) self.__ui.tabWidget.setCurrentIndex(2) self.__ui.urlsLineEdit.setFocus(True) return zmqtopics = str(self.__ui.zmqtopicsLineEdit.text()).strip().split(" ") self.zmqtopics = [tp for tp in zmqtopics if tp] self.interruptonerror = self.__ui.interruptCheckBox.isChecked() self.autozmqtopics = self.__ui.autozmqtopicsCheckBox.isChecked() datasources = str( self.__ui.asapodatasourcesLineEdit.text()).strip().split(" ") self.asapodatasources = [tp for tp in datasources if tp] self.asaposerver = str( self.__ui.asaposerverLineEdit.text()).strip() self.asapotoken = str( self.__ui.asapotokenLineEdit.text()).strip() self.asapobeamtime = str( self.__ui.asapobeamtimeLineEdit.text()).strip() self.asaposourcepath = str( self.__ui.asaposourcepathLineEdit.text()).strip() self.asapobtmetafile = str( self.__ui.asapobtmetafileLineEdit.text()).strip() detservers = str( self.__ui.detserversLineEdit.text()).strip().split(" ") self.detservers = json.dumps([ds for ds in detservers if ds]) try: self.timeout = int(self.__ui.timeoutLineEdit.text()) except Exception: self.__ui.tabWidget.setCurrentIndex(2) self.__ui.timeoutLineEdit.setFocus(True) return try: self.secport = str(self.__ui.secportLineEdit.text()).strip() int(self.secport) except Exception: self.__ui.tabWidget.setCurrentIndex(0) self.__ui.secportLineEdit.setFocus(True) return try: hidraport = str( self.__ui.hidraportLineEdit.text()).strip().split(" ") for pt in hidraport: int(pt) self.hidraport = json.dumps([pt for pt in hidraport if pt]) except Exception: self.__ui.tabWidget.setCurrentIndex(2) self.__ui.hidraportLineEdit.setFocus(True) return try: self.maxmbuffersize = str( self.__ui.mbufsizeLineEdit.text()).strip() int(self.maxmbuffersize) except Exception: self.__ui.tabWidget.setCurrentIndex(0) self.__ui.mbufsizeLineEdit.setFocus(True) return self.__readROIsColors() self.__readOverflowColor() self.imagesources = json.dumps( self.__ui.isTable.getChecks(self.availimagesources)) self.toolwidgets = json.dumps( self.__ui.twTable.getChecks(self.availtoolwidgets)) QtWidgets.QDialog.accept(self)