def __init__(self, wintitle): super(Window, self).__init__() self.default_tool = None self.plots = [] self.itemlist = PlotItemList(None) self.contrast = ContrastAdjustment(None) self.xcsw = XCrossSection(None) self.ycsw = YCrossSection(None) self.manager = PlotManager(self) self.toolbar = QToolBar(_("Tools"), self) self.manager.add_toolbar(self.toolbar, "default") self.toolbar.setMovable(True) self.toolbar.setFloatable(True) self.addToolBar(Qt.TopToolBarArea, self.toolbar) frame = QFrame(self) self.setCentralWidget(frame) self.layout = QGridLayout() layout = QVBoxLayout(frame) frame.setLayout(layout) layout.addLayout(self.layout) self.frame = frame self.setWindowTitle(wintitle) self.setWindowIcon(get_icon('guiqwt.svg'))
def __init__(self, item, parent_layout): super(TabGroupWidget, self).__init__(item, parent_layout) self.tabs = QTabWidget() items = item.item.group self.widgets = [] for item in items: if item.get_prop_value("display", parent_layout.instance, "hide", False): continue item.set_prop("display", embedded=True) widget = parent_layout.build_widget(item) frame = QFrame() label = widget.item.get_prop_value("display", "label") icon = widget.item.get_prop_value("display", "icon", None) if icon is not None: self.tabs.addTab(frame, get_icon(icon), label) else: self.tabs.addTab(frame, label) layout = QGridLayout() layout.setAlignment(Qt.AlignTop) frame.setLayout(layout) widget.place_on_grid(layout, 0, 0, 1) try: widget.get() except Exception: print("Error building item :", item.item._name) raise self.widgets.append(widget)
class GroupWidget(AbstractDataSetWidget): """ GroupItem widget """ def __init__(self, item, parent_layout): super(GroupWidget, self).__init__(item, parent_layout) embedded = item.get_prop_value("display", "embedded", False) if not embedded: self.group = QGroupBox(item.get_prop_value("display", "label")) else: self.group = QFrame() self.layout = QGridLayout() EditLayoutClass = parent_layout.__class__ self.edit = EditLayoutClass(self.group, item.instance, self.layout, item.item.group) self.group.setLayout(self.layout) def get(self): """Override AbstractDataSetWidget method""" self.edit.update_widgets() def set(self): """Override AbstractDataSetWidget method""" self.edit.accept_changes() def check(self): """Override AbstractDataSetWidget method""" return self.edit.check_all_values() def place_on_grid(self, layout, row, label_column, widget_column, row_span=1, column_span=1): """Override AbstractDataSetWidget method""" layout.addWidget(self.group, row, label_column, row_span, column_span+1)
class DataSetWidget(AbstractDataSetWidget): """ DataSet widget """ def __init__(self, item, parent_layout): super(DataSetWidget, self).__init__(item, parent_layout) self.dataset = self.klass() # Création du layout contenant les champs d'édition du signal embedded = item.get_prop_value("display", "embedded", False) if not embedded: self.group = QGroupBox(item.get_prop_value("display", "label")) else: self.group = QFrame() self.layout = QGridLayout() self.group.setLayout(self.layout) EditLayoutClass = parent_layout.__class__ self.edit = EditLayoutClass(self.parent_layout.parent, self.dataset, self.layout) def get(self): """Override AbstractDataSetWidget method""" self.get_dataset() for widget in self.edit.widgets: widget.get() def set(self): """Override AbstractDataSetWidget method""" for widget in self.edit.widgets: widget.set() self.set_dataset() def get_dataset(self): """update's internal parameter representation from the item's stored value default behavior uses update_dataset and assumes internal dataset class is the same as item's value class""" item = self.item.get() update_dataset(self.dataset, item) def set_dataset(self): """update the item's value from the internal data representation default behavior uses restore_dataset and assumes internal dataset class is the same as item's value class""" item = self.item.get() restore_dataset(self.dataset, item) def place_on_grid(self, layout, row, label_column, widget_column, row_span=1, column_span=1): """Override AbstractDataSetWidget method""" layout.addWidget(self.group, row, label_column, row_span, column_span+1)
def __init__(self, item, parent_layout): super(GroupWidget, self).__init__(item, parent_layout) embedded = item.get_prop_value("display", "embedded", False) if not embedded: self.group = QGroupBox(item.get_prop_value("display", "label")) else: self.group = QFrame() self.layout = QGridLayout() EditLayoutClass = parent_layout.__class__ self.edit = EditLayoutClass(self.group, item.instance, self.layout, item.item.group) self.group.setLayout(self.layout)
def __init__(self, parent=None): QFrame.__init__(self, parent) layout = QGridLayout() self.setLayout(layout) angle = 0 for row in range(7): for column in range(7): layout.addWidget(RotatedLabel("Label %03d°" % angle, angle=angle, color=Qt.blue, bold=True), row, column, Qt.AlignCenter) angle += 10
def __init__(self, item, parent_layout): super(DataSetWidget, self).__init__(item, parent_layout) self.dataset = self.klass() # Création du layout contenant les champs d'édition du signal embedded = item.get_prop_value("display", "embedded", False) if not embedded: self.group = QGroupBox(item.get_prop_value("display", "label")) else: self.group = QFrame() self.layout = QGridLayout() self.group.setLayout(self.layout) EditLayoutClass = parent_layout.__class__ self.edit = EditLayoutClass(self.parent_layout.parent, self.dataset, self.layout)
def __init__(self, parent=None): QFrame.__init__(self, parent) layout = QGridLayout() self.setLayout(layout) angle = 0 for row in range(7): for column in range(7): layout.addWidget( RotatedLabel("Label %03d°" % angle, angle=angle, color=Qt.blue, bold=True), row, column, Qt.AlignCenter) angle += 10
def _generateFrame(self): ''' Return the frame containing the presentation, check if the frame was created, otherwise it is created :return: ''' # generate the frame if necessary if self._frame is None: # Generate frame and define the layout based on the frame self._frame = QFrame(self._parentFrame) _layout = QVBoxLayout() self._frame.setLayout(_layout) # Add the "Main" group box for this view, if present. It is rendered in foreground if self._generateGroupBox() is not None: _layout.addWidget(self._groupbox) else: self._frame.setFrameStyle(QFrame.Panel|QFrame.Raised) self._frame.setLineWidth(1) # Add to layout eventually the other subview if self._viewtype == 'Tabs': _tabs = QTabWidget() _layout.addWidget(_tabs) elif self._viewtype == 'Splitter': _splitter =QSplitter() _layout.addWidget(_splitter) else: _sub_frame = QFrame() _sub_frame_layout = QHBoxLayout() _sub_frame.setLayout(_sub_frame_layout) _layout.addWidget(_sub_frame) # Add all the sub view as sub frames in the layout for sw in self._subViewDictionary.values(): sw.setParentView(self._frame) if self._viewtype == 'Tabs': _tabs.addTab(sw.getFrame(), sw.viewname) elif self._viewtype == 'Splitter': _splitter.addWidget(sw.getFrame()) else: _sub_frame_layout.addWidget(sw.getFrame()) return self._frame
class GuidataView(view.GenericView): _CONST_Views = ['Splitter', 'Tabs', 'Standard'] def __init__(self, viewname = '', viewtype ='Standard', qtapp=None): super().__init__(viewname) self._app = qtapp self._frame = None self._parentFrame = None self._viewtype = viewtype self._groupbox = None self._previousValues = OrderedDict() def getViewType(self): return self._viewtype viewtype = property(getViewType, doc='The view type, see _CONST_Views for available views. Readonly') def setParentView(self, parentview): ''' Set the parent widget associated to this view (GenericView) :param parentview: :return: ''' if self._parentFrame is not None: raise view.ViewInternalError(self, self._viewname, 'Parent was already set') # self._parentFrame = parentview.getViewContainer() self._parentFrame = parentview def show(self): # QT Stuff if self._app is None: self._app = QApplication([]) if self._parentFrame is None: self._parentFrame = QMainWindow() # self._parentFrame.setWindowIcon(get_icon('python.png')) self._parentFrame.setWindowTitle(self.viewname) # Add the frame to this frame self._parentFrame.setCentralWidget(self.getFrame()) self._parentFrame.setContentsMargins(10, 5, 10, 5) self._parentFrame.show() self._forceRefreshFromWidgets() self._previousValues = self._dumpValues() def close(self, closeapp=False): ''' Implement the close view in the GerericView class, furthermore close the QT application which this view belongs :param closeapp: :return: ''' if self._parentFrame is not None: self._parentFrame.close() del self._parentFrame if self._app is not None and closeapp: del self._app def getFrame(self): ''' Return the frame containing the presentation, check if the frame was created, otherwise it is created :return: ''' if self._frame is None: self._generateFrame() return self._frame def _generateFrame(self): ''' Return the frame containing the presentation, check if the frame was created, otherwise it is created :return: ''' # generate the frame if necessary if self._frame is None: # Generate frame and define the layout based on the frame self._frame = QFrame(self._parentFrame) _layout = QVBoxLayout() self._frame.setLayout(_layout) # Add the "Main" group box for this view, if present. It is rendered in foreground if self._generateGroupBox() is not None: _layout.addWidget(self._groupbox) else: self._frame.setFrameStyle(QFrame.Panel|QFrame.Raised) self._frame.setLineWidth(1) # Add to layout eventually the other subview if self._viewtype == 'Tabs': _tabs = QTabWidget() _layout.addWidget(_tabs) elif self._viewtype == 'Splitter': _splitter =QSplitter() _layout.addWidget(_splitter) else: _sub_frame = QFrame() _sub_frame_layout = QHBoxLayout() _sub_frame.setLayout(_sub_frame_layout) _layout.addWidget(_sub_frame) # Add all the sub view as sub frames in the layout for sw in self._subViewDictionary.values(): sw.setParentView(self._frame) if self._viewtype == 'Tabs': _tabs.addTab(sw.getFrame(), sw.viewname) elif self._viewtype == 'Splitter': _splitter.addWidget(sw.getFrame()) else: _sub_frame_layout.addWidget(sw.getFrame()) return self._frame def _generateGroupBox(self): ''' Generate if necessary the group box for this :return: ''' if self._groupbox is None: # from widgets create the view containing the datasets _dataSetView = self._generateGuidataDataset() if len(_dataSetView._items) > 0: if self._viewtype == 'Tabs': self._groupbox = DataSetEditGroupBox(self.viewname, _dataSetView, comment='') else: self._groupbox = DataSetEditGroupBox(self.viewname, _dataSetView, comment='') self._groupbox.SIG_APPLY_BUTTON_CLICKED.connect(self._updatedView) return self._groupbox def getViewContainer(self): ''' This method must be reimplemented returning the proper window/frame etc.. It is based on the GUI implementation :return: a reference to the window container ''' return self._parentFrame def getQTApp(self): ''' Return the associated QT application, which is mandatory for guidata framework :return: ''' return self._app def addWidget(self, widgetinstance): if not isinstance(widgetinstance, GuidataWidget): raise view.WrongWidgetClass(self, self._viewname, widgetinstance, GuidataWidget) super().addWidget(widgetinstance) def _dumpValues(self): widgetvalue = OrderedDict() for n, w in self._widgetDictionary.items(): # I need to store the widget value and NOT the value returned (for example in a combo box I need to store # the index, not the value # widgetvalue[n] = w.getWidgetValue() widgetvalue[n] = GuidataWidget.convertValueToWidgetValue(w, w.getWidgetValue()) return widgetvalue def _updatedViewHook(self): # En Widget ' + str(wtry point for a change... differences = {} differencesConverted = {} self._groupbox.get() dataset = self._groupbox.dataset for n, w in self._widgetDictionary.items(): # if nameProp in vars(dataset): # TODO: workaround, the mechanism in the guidata framework is not very well documented. # TODO: then in order to get the proper value this is collected through the groupbox insteadm the value. # So i check in dataset every nameprop nameProp = w.name actualValue = getattr(dataset, nameProp) #, w.getWidgetValue()) prevValue = self._previousValues.get(n) logging.debug('--widgetname=' + w.name) if not (prevValue == actualValue): differences[n] = actualValue differencesConverted[n] = GuidataWidget.convertWidgetValueToValue(w, actualValue) #w._setWidgetValueHook(actualValue) logging.debug(' DIFFERENCE viewname={0} prevvalue={1} - newvalue={2}'.format(n, prevValue, actualValue)) logging.debug(' DIFFERENCE CONVERTED viewname={0} prevvalue={1} - newvalue={2}'.format (n, GuidataWidget.convertWidgetValueToValue(w, prevValue), differencesConverted[n])) else: logging.debug(' NO DIFFERENCE viewname={0} prevvalue={1} - newvalue={2}'.format(n, prevValue, actualValue)) if len(differences): self._forceRefreshToWidgets(differences) self._previousValues = self._dumpValues() return differencesConverted def _forceRefreshToWidgets(self, widget_to_set): ''' A refresh to update the widget with the values stored in the groupbox associated This is a workaround relative to the guidata framework. (should be improved) :return: ''' if self._groupbox == None: return #for key, w in self._widgetDictionary.items(): for wname, valuetoconvert in widget_to_set.items(): w = self.getWidget(wname) if w is None: raise RuntimeError('Widget cannot\'t be None') # TODO: this is horrible, but need a workaround for guidata to get the value from data set and force it in the GUI #valuetoconvert = getattr(self._groupbox.dataset, wname) converteddataset = GuidataWidget.convertWidgetValueToValue(w, valuetoconvert) logging.debug('For widget['+wname+'] Converted value from '+str(valuetoconvert)+' to ' + str(converteddataset)) w.setWidgetValue(converteddataset) # Convertire from index to value logging.debug('\tValue set is '+str(w.getWidgetValue())) def _forceRefreshFromWidgets(self): ''' A refresh to update the whole groupbox with the proper value associated in the widget A workaround in the bad documented guidata in order to force the refresh from the data stored in the widget :return: ''' if self._groupbox == None: return for key, w in self._widgetDictionary.items(): value = w.getWidgetValue() valueconverted = w._getGuidataWidgetValue() logging.debug('For widget ['+key+'] Converted value from '+str(value)+' to ' + str(valueconverted)) setattr(self._groupbox.dataset, key, valueconverted) logging.debug('\tRead back value '+str(getattr(self._groupbox.dataset, key))) #PROBLEM IN GET!!! se faccio la get nelle combo box setto il valore del ITEM id e non del valore vero # in prarice il setattr dovrebbe settare l'ITEM ID per le combo box self._groupbox.get() def _userWidgetUpdatedHandler(self, sender): # WORKAROUND: the guidata need to be forced to update the UI if the underlay widget is changed if not isinstance(sender, widget.GenericWidget): raise view.WrongWidgetClass(self,self.viewname, sender, widget.GenericWidget) self._forceRefreshFromWidgets() super()._userWidgetUpdatedHandler(sender) def _generateGuidataDataset(self): class DataSetView(DataSet): key = None value = None for key, value in self._widgetDictionary.items(): locals()[key] = value.getDataSet() del key, value return DataSetView
def __init__(self, parent): #super(ObjectFT, self).__init__(Qt.Vertical, parent) super().__init__(parent) self.stage = None self.offset = 0. # offset from 0 where t0 is (mm) self.newOff = 0. self.stageRange = (0, 0) layoutWidget = QWidget() layout = QGridLayout() layoutWidget.setLayout(layout) # put layout together self.openStageBtn = QPushButton("Open stage") self.initStageBtn = QPushButton("Init stage") #absolute move #current position self.currentPos = QLabel('') #self.currentPos.setValidator(QDoubleValidator()) #relative move (mm) self.deltaMove_mm = QLineEdit() self.deltaMove_mm.setText('0') self.deltaMove_mm.setValidator(QDoubleValidator()) self.deltaMovePlus_mm = QPushButton('+') self.deltaMoveMinus_mm = QPushButton('-') #relative move (fs) self.deltaMove_fs = QLineEdit() self.deltaMovePlus_fs = QPushButton('+') self.deltaMoveMinus_fs = QPushButton('-') #velocity self.velocityLabel = QLabel('Velocity:') self.velocity = QSlider(Qt.Horizontal) self.velocity.setMinimum(0) self.velocity.setMaximum( 2000) # unit in µm; TODO: try to get max vel. from controller # scan from (fs) self.scanFrom = QLineEdit() self.scanFrom.setText('-100') self.scanFrom.setValidator(QIntValidator()) # scan to (fs) self.scanTo = QLineEdit() self.scanTo.setText('100') self.scanTo.setValidator(QIntValidator()) # scan stepsize (fs) self.scanStep = QLineEdit() self.scanStep.setText('10') self.scanStep.setValidator(QDoubleValidator()) # center here button self.centerBtn = QPushButton('Center here') self.centerBtn.setToolTip('Center scan at current stage position') self.startScanBtn = QPushButton("Start scan") self.stopScanBtn = QPushButton("Stop scan") self.niceBtn = QPushButton('Make it nice') # spacer line hLine = QFrame() hLine.setFrameStyle(QFrame.HLine) hLine.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) # put layout together layout.addWidget(self.openStageBtn, 0, 0) layout.addWidget(self.initStageBtn, 0, 1) layout.addWidget(QLabel("Current pos (mm):"), 1, 0) layout.addWidget(self.currentPos, 1, 1) layout.addWidget(self.velocityLabel, 2, 0) layout.addWidget(self.velocity, 3, 0, 1, 2) layout.addWidget(QLabel('Move relative (mm)'), 4, 0) layout.addWidget(self.deltaMove_mm, 5, 0, 1, 2) layout.addWidget(self.deltaMoveMinus_mm, 6, 0) layout.addWidget(self.deltaMovePlus_mm, 6, 1) layout.addWidget(QLabel('Move relative (fs)'), 7, 0) layout.addWidget(self.deltaMove_fs, 8, 0, 1, 2) layout.addWidget(self.deltaMoveMinus_fs, 9, 0) layout.addWidget(self.deltaMovePlus_fs, 9, 1) layout.addWidget(hLine, 10, 0, 1, 2) layout.addWidget(QLabel('Scan from (fs)'), 11, 0) layout.addWidget(self.scanFrom, 11, 1) layout.addWidget(QLabel('Scan to (fs)'), 12, 0) layout.addWidget(self.scanTo, 12, 1) layout.addWidget(QLabel('Stepsize (fs)'), 13, 0) layout.addWidget(self.scanStep, 13, 1) layout.addWidget(self.startScanBtn, 14, 0) layout.addWidget(self.stopScanBtn, 14, 1) layout.addWidget(self.centerBtn, 15, 1) layout.addWidget(self.niceBtn, 16, 1) layout.setRowStretch(17, 10) layout.setColumnStretch(2, 10) self.addWidget(layoutWidget) # make button and stuff functional self.openStageBtn.released.connect(self.connectStage) self.initStageBtn.released.connect(self.initStage) self.scanFrom.returnPressed.connect(self._xAxeChanged) self.scanTo.returnPressed.connect(self._xAxeChanged) self.centerBtn.released.connect(self._centerHere) self.deltaMovePlus_mm.released.connect( lambda x=1: self.moveRel_mm(float(self.deltaMove_mm.text()))) self.deltaMoveMinus_mm.released.connect( lambda x=-1: self.moveRel_mm(float(self.deltaMove_mm.text()), x)) ################ # thread for updating position #self.currPosThr = GenericThread(self.__getCurrPos) self.updateCurrPos.connect(self.__updateCurrPos) self.currPos_thread = QThread() # create the QThread self.currPos_thread.start() # This causes my_worker.run() to eventually execute in my_thread: self.currPos_worker = GenericWorker(self.__getCurrPos) self.currPos_worker.moveToThread(self.currPos_thread)