def init(): QtGui.QDialog.__init__(self, parent) self.setWindowTitle('%s edit dialog' % channel) layout = QtGui.QFormLayout() self.setLayout(layout) PARAM_KEYS, PARAM_NAMES = zip(*VM.PARAMETERS) setParameter = partial(protocol.sendCommand, 'set-channel-parameter', channel) print channel parameters = {} for parameter in PARAM_KEYS: value = yield protocol.sendCommand('get-channel-parameter', channel, parameter) parameters[parameter] = value layout.addRow(PARAM_NAMES[PARAM_KEYS.index(VM.PHYSICAL_CHANNEL)], QtGui.QLabel(parameters[VM.PHYSICAL_CHANNEL])) descriptionLineEdit = QtGui.QLineEdit(parameters[VM.DESCRIPTION]) descriptionLineEdit.returnPressed.connect( compose(partial(setParameter, VM.DESCRIPTION), descriptionLineEdit.text)) layout.addRow(PARAM_NAMES[PARAM_KEYS.index(VM.DESCRIPTION)], descriptionLineEdit) trmCfgComboBox = QtGui.QComboBox() for trmCfgKey, _, trmCfgName in VM.TERMINAL_CONFIGS: trmCfgComboBox.addItem(trmCfgName, trmCfgKey) trmCfgComboBox.setCurrentIndex( trmCfgComboBox.findData(parameters[VM.TERMINAL_CONFIG])) def onConfigChange(): newConfig = trmCfgComboBox.itemData( trmCfgComboBox.currentIndex()) setParameter(VM.TERMINAL_CONFIG, newConfig) trmCfgComboBox.currentIndexChanged.connect(onConfigChange) layout.addRow(PARAM_NAMES[PARAM_KEYS.index(VM.TERMINAL_CONFIG)], trmCfgComboBox) vrngComboBox = QtGui.QComboBox() vrngKeys, vrngVals = zip(*VM.VOLTAGE_RANGES) for key, val in VM.VOLTAGE_RANGES: vrngComboBox.addItem('%.2f (V)' % val, key) vrngComboBox.setCurrentIndex( vrngComboBox.findData(parameters[VM.VOLTAGE_RANGE])) vrngComboBox.currentIndexChanged.connect( compose(partial(setParameter, VM.VOLTAGE_RANGE), vrngComboBox.itemData)) layout.addRow(PARAM_NAMES[PARAM_KEYS.index(VM.VOLTAGE_RANGE)], vrngComboBox) colorEditButton = QtGui.QPushButton('edit') colorEditButton.pressed.connect( compose(self.colorChanged.emit, partial(QtGui.QColorDialog.getColor, color))) layout.addRow('color', colorEditButton)
def __init__(self): ToggleObject.__init__(self, False) self.activationRequested.connect(self.toggle) self.activated.connect( compose(self.loopRequested.emit, partial(Looper.LoopRequest, self))) self.deactivationRequested.connect( partial(setattr, self, 'aborted', True)) self.aborted = False
def setPosition(self, position): self.stepping = True self.abort = False start = yield self.getPosition() stop = position rate = yield self.getStepRate() step = rate * self.duration def onStep(input, output): print 'i:%s,\to:%s' % (input, output) return not self.abort yield Scan( IntervalScanInput( compose(partial(StepperMotorClient.setPosition, self), compose(int, round)), start, stop, step).next, lambda: None, lambda a, b: not self.abort).start() self.stepping = False position = yield self.getPosition() returnValue(position)
def __init__(self, positions=None): QtGui.QWidget.__init__(self) layout = QtGui.QVBoxLayout() self.setLayout(layout) self.loadPosListButton = QtGui.QPushButton('load queue') self.loadPosListButton.clicked.connect( compose(self.setPositions, self.loadPositions)) layout.addWidget(self.loadPosListButton) self.queueWidget = QtGui.QListWidget() self.queueWidget.setMaximumSize(200, 150) layout.addWidget(self.queueWidget) self.setPositions([] if positions is None else positions)
def __init__(self): ToggleObject.__init__(self,False) self.activationRequested.connect(self.toggle) self.activated.connect( compose( self.loopRequested.emit, partial( Looper.LoopRequest, self ) ) ) self.deactivationRequested.connect(partial(setattr,self,'aborted',True)) self.aborted = False
def __init__(self,positions = None): QtGui.QWidget.__init__(self) layout = QtGui.QVBoxLayout() self.setLayout(layout) self.loadPosListButton = QtGui.QPushButton('load queue') self.loadPosListButton.clicked.connect( compose( self.setPositions, self.loadPositions ) ) layout.addWidget(self.loadPosListButton) self.queueWidget = QtGui.QListWidget() self.queueWidget.setMaximumSize(200,150) layout.addWidget(self.queueWidget) self.setPositions([] if positions is None else positions)
def __init__(self,toggleObject,labels=('start','stop')): QtGui.QWidget.__init__(self) layout = QtGui.QHBoxLayout() self.setLayout(layout) def toggle(state): self.setEnabled(True) for toggle, button in buttons.items(): button.setEnabled(state is not toggle) toggleObject.toggled.connect(compose(toggle,toggleObject.isToggled)) buttons = {} for label, state in zip(labels,(True,False)): button = QtGui.QPushButton(label) button.clicked.connect(partial(self.setEnabled,False)) button.clicked.connect(partial(toggleObject.requestToggle)) layout.addWidget(button) buttons[state] = button toggle(toggleObject.isToggled())
def __init__(self, toggleObject, labels=('start', 'stop')): QtGui.QWidget.__init__(self) layout = QtGui.QHBoxLayout() self.setLayout(layout) def toggle(state): self.setEnabled(True) for toggle, button in buttons.items(): button.setEnabled(state is not toggle) toggleObject.toggled.connect(compose(toggle, toggleObject.isToggled)) buttons = {} for label, state in zip(labels, (True, False)): button = QtGui.QPushButton(label) button.clicked.connect(partial(self.setEnabled, False)) button.clicked.connect(partial(toggleObject.requestToggle)) layout.addWidget(button) buttons[state] = button toggle(toggleObject.isToggled())
def test(): ## BOILERPLATE ## import sys from PySide import QtGui, QtCore from math import sin if QtCore.QCoreApplication.instance() is None: app = QtGui.QApplication(sys.argv) import qt4reactor qt4reactor.install() ## BOILERPLATE ## #create the widget name even if you're not using it so that onStepped doesn't error listScanInputWidget = None def log(x): print x #configure a layout for the plot widget & controls to go side by side on widget = QtGui.QWidget() widget.show() layout = QtGui.QHBoxLayout() widget.setLayout(layout) # create a plot and associated widget from pyqtgraph import PlotWidget plotWidget = PlotWidget() plot = plotWidget.plot() layout.addWidget(plotWidget) #configure a control panel layout controlPanel = QtGui.QWidget() cpLayout = QtGui.QVBoxLayout() controlPanel.setLayout(cpLayout) #create a scanToggleObject scanToggle = ScanToggleObject() ''' #create a list scan input & widget listScanInput = ListScanInput(lambda(x):x,None) listScanInputWidget = ListScanInputWidget(listScanInput) cpLayout.addWidget(listScanInputWidget) scanToggle.toggled.connect( compose( listScanInputWidget.setDisabled, scanToggle.isToggled ) ) scanToggle.toggled.connect(partial(log,listScanInputWidget.listScanInput.positions)) scanToggle.setInput(listScanInput.next) ''' #create an interval scan input & widget intScanInput = IntervalScanInput(lambda (x): x, 0, 1000, 10) scanToggle.setInput(intScanInput.next) intScanInputWidget = IntervalScanInputWidget(intScanInput, DEFAULTS) cpLayout.addWidget(intScanInputWidget) scanToggle.toggled.connect( compose(intScanInputWidget.setDisabled, scanToggle.isToggled)) #create scan output, for now a sine wave, this is where voltmeter would go def output(): result = sin(float(output.i) / output.res) output.i += 1 return result output.i = 0 output.res = 10 scanToggle.setOutput(output) # create a scan toggle x, y = [], [] def onActivationRequested(x, y): while x: x.pop() while y: y.pop() scanToggle.toggle() # not performing any setup, so go ahead and connect activation requests to toggle scanToggle.activationRequested.connect(partial(onActivationRequested, x, y)) # create a toggle widget from qtutils.toggle import ToggleWidget cpLayout.addWidget(ToggleWidget(scanToggle)) # handle the stepped signal from ab.abbase import sleep @inlineCallbacks def onStepped(data): input, output = data x.append(input) y.append(output) plot.setData(x, y) yield sleep(.05) scanToggle.completeStep() if listScanInputWidget is not None: listScanInputWidget.updateQueue() scanToggle.stepped.connect(onStepped) #for debug purposes, connect to toggle signal scanToggle.toggled.connect(partial(log, 'toggled')) scanToggle.toggleRequested.connect(partial(log, 'toggleRequested')) #add the control panel to the window and execute layout.addWidget(controlPanel) app.exec_()
def onInit(): config = yield protocol.sendCommand('get-configuration') self.show() #sort the list of dgNames based on guiOrder key in config sorted_sms = list() for smName in config.keys(): sorted_sms.append((smName,config[smName]['guiOrder'],config[smName])) sorted_sms = sorted(sorted_sms, key=lambda x:x[1]) #create a vertical layout for each sm (thisLayout), when done add to the full horizontal layout (self.layout()) for id, guiOrder, config in sorted_sms: thisLayout = QtGui.QVBoxLayout() sm = ChunkedStepperMotorClient(protocol,id) self.sms[id] = sm #create a goto widget for this steppermotor PARAMS[POI] = config['pts_of_int'] gotoWidget = GotoWidget(PARAMS) self.gotoWids[sm.id] = gotoWidget thisLayout.addWidget(gotoWidget) @inlineCallbacks def onGotoRequested(sm,payload): position, deferred = payload yield sm.setPosition(int(position)) deferred.callback(None) gotoWidget.gotoRequested.connect(partial(onGotoRequested,sm)) #gotoWidget.spin.editingFinished.connect(partial(onGotoRequested,sm)) sm.addListener(sm.POSITION,gotoWidget.setPosition) def onUpdateRequested(stepperMotor,gw): stepperMotor.getPosition().addCallback(gw.setPosition) gotoWidget.updateRequested.connect(partial(onUpdateRequested,sm,gotoWidget)) gotoWidget.cancelRequested.connect(sm.cancel) position = yield sm.getPosition() gotoWidget.setPosition(position) #create an enable toggle button for this sm enableButton = QtGui.QPushButton('enable', self) self.enbButtons[sm.id] = enableButton enableButton.clicked.connect(sm.toggleStatus) #handle external application toggling this sm def adjustText(sm,status): if status == 'enabled': self.enbButtons[sm.id].setText('disable') self.gotoWids[sm.id].setEnabled(True) elif status == 'disabled': self.enbButtons[sm.id].setText('enable') self.gotoWids[sm.id].setEnabled(False) sm.addListener(sm.ENABLE,partial(adjustText,sm)) #disable enable button if this sm doesn't have that functionality if config['enable_channel'] == None: enableButton.setEnabled(False) else: gotoWidget.setEnabled(False) thisLayout.addWidget(enableButton) #create a spinbox to control the step rate for this sm rate = yield sm.getStepRate() rateSpin = QtGui.QSpinBox() thisLayout.addWidget(LabelWidget('rate',rateSpin)) rateSpin.editingFinished.connect( compose( sm.setStepRate, rateSpin.value ) ) rateSpin.setRange( RATE_MIN if rate > RATE_MIN else rate, RATE_MAX if rate < RATE_MAX else rate ) rateSpin.setValue(rate) sm.addListener(sm.RATE,rateSpin.setValue) #add this steppermotor panel to the gui self.layout().addWidget( LabelWidget( config['name'], thisLayout ) )
def onInit(): config = yield protocol.sendCommand('get-configuration') self.show() #sort the list of dgNames based on guiOrder key in config sorted_sms = list() for smName in config.keys(): sorted_sms.append( (smName, config[smName]['guiOrder'], config[smName])) sorted_sms = sorted(sorted_sms, key=lambda x: x[1]) #create a vertical layout for each sm (thisLayout), when done add to the full horizontal layout (self.layout()) for id, guiOrder, config in sorted_sms: thisLayout = QtGui.QVBoxLayout() sm = ChunkedStepperMotorClient(protocol, id) self.sms[id] = sm #create a goto widget for this steppermotor PARAMS[POI] = config['pts_of_int'] gotoWidget = GotoWidget(PARAMS) self.gotoWids[sm.id] = gotoWidget thisLayout.addWidget(gotoWidget) @inlineCallbacks def onGotoRequested(sm, payload): position, deferred = payload yield sm.setPosition(int(position)) deferred.callback(None) gotoWidget.gotoRequested.connect(partial(onGotoRequested, sm)) #gotoWidget.spin.editingFinished.connect(partial(onGotoRequested,sm)) sm.addListener(sm.POSITION, gotoWidget.setPosition) def onUpdateRequested(stepperMotor, gw): stepperMotor.getPosition().addCallback(gw.setPosition) gotoWidget.updateRequested.connect( partial(onUpdateRequested, sm, gotoWidget)) gotoWidget.cancelRequested.connect(sm.cancel) position = yield sm.getPosition() gotoWidget.setPosition(position) #create an enable toggle button for this sm enableButton = QtGui.QPushButton('enable', self) self.enbButtons[sm.id] = enableButton enableButton.clicked.connect(sm.toggleStatus) #handle external application toggling this sm def adjustText(sm, status): if status == 'enabled': self.enbButtons[sm.id].setText('disable') self.gotoWids[sm.id].setEnabled(True) elif status == 'disabled': self.enbButtons[sm.id].setText('enable') self.gotoWids[sm.id].setEnabled(False) sm.addListener(sm.ENABLE, partial(adjustText, sm)) #disable enable button if this sm doesn't have that functionality if config['enable_channel'] == None: enableButton.setEnabled(False) else: gotoWidget.setEnabled(False) thisLayout.addWidget(enableButton) #create a spinbox to control the step rate for this sm rate = yield sm.getStepRate() rateSpin = QtGui.QSpinBox() thisLayout.addWidget(LabelWidget('rate', rateSpin)) rateSpin.editingFinished.connect( compose(sm.setStepRate, rateSpin.value)) rateSpin.setRange(RATE_MIN if rate > RATE_MIN else rate, RATE_MAX if rate < RATE_MAX else rate) rateSpin.setValue(rate) sm.addListener(sm.RATE, rateSpin.setValue) #add this steppermotor panel to the gui self.layout().addWidget(LabelWidget(config['name'], thisLayout))
def init(): QtGui.QDialog.__init__(self,parent) self.setWindowTitle('%s properties' % channel) layout = QtGui.QFormLayout() self.setLayout(layout) # create two lists pertaining to this channel's properties PARAM_KEYS,PARAM_NAMES = zip(*VM.PARAMETERS) # build a dictionary of dictionaries of the form [propertyKey]:{[propertyItems]:[value]} propDict = {} for propKey, propName in zip(PARAM_KEYS,PARAM_NAMES): value = yield protocol.sendCommand('get-channel-parameter',channel,propKey) propDict[propKey] = {} propDict[propKey]['name'] = propName propDict[propKey]['value'] = value if propKey == 0: # physical channel property propDict[propKey]['editor'] = None propDict[propKey]['display'] = QtGui.QLabel(value) if propKey != 0: # all other properties can be changed propDict[propKey]['editor'] = partial(protocol.sendCommand,'set-channel-parameter',channel,propKey) if type(value) is UnicodeType: thisDisplayObj = QtGui.QLineEdit() thisDisplayObj.setText(value) thisDisplayObj.editingFinished.connect( compose( propDict[propKey]['editor'], thisDisplayObj.text ) ) propDict[propKey]['display'] = thisDisplayObj if type(value) is IntType: thisDisplayObj = QtGui.QComboBox() if propKey == 3: #voltage range for voltConfKey, voltConfVal in VM.VOLTAGE_RANGES: thisDisplayObj.addItem( '%.2f (V)' % voltConfVal, voltConfKey ) if propKey == 2: #terminal configuration for termConfKey, _, termConfName in VM.TERMINAL_CONFIGS: thisDisplayObj.addItem( termConfName,termConfKey ) thisDisplayObj.setCurrentIndex( thisDisplayObj.findData(value) ) thisDisplayObj.currentIndexChanged.connect( compose( propDict[propKey]['editor'], thisDisplayObj.itemData ) ) propDict[propKey]['display'] = thisDisplayObj layout.addRow(propDict[propKey]['name'],propDict[propKey]['display']) colorEditButton = QtGui.QPushButton('edit') colorEditButton.pressed.connect( compose( self.colorChanged.emit, partial( QtGui.QColorDialog.getColor, color ) ) ) layout.addRow('color',colorEditButton)
def init(): QtGui.QDialog.__init__(self,parent) self.setWindowTitle('%s edit dialog' % channel) layout = QtGui.QFormLayout() self.setLayout(layout) PARAM_KEYS,PARAM_NAMES = zip(*VM.PARAMETERS) setParameter = partial( protocol.sendCommand, 'set-channel-parameter', channel ) print channel parameters = {} for parameter in PARAM_KEYS: value = yield protocol.sendCommand('get-channel-parameter',channel,parameter) parameters[parameter] = value layout.addRow( PARAM_NAMES[ PARAM_KEYS.index( VM.PHYSICAL_CHANNEL ) ], QtGui.QLabel(parameters[VM.PHYSICAL_CHANNEL]) ) descriptionLineEdit = QtGui.QLineEdit(parameters[VM.DESCRIPTION]) descriptionLineEdit.returnPressed.connect( compose( partial( setParameter, VM.DESCRIPTION ), descriptionLineEdit.text ) ) layout.addRow( PARAM_NAMES[ PARAM_KEYS.index( VM.DESCRIPTION ) ], descriptionLineEdit ) trmCfgComboBox = QtGui.QComboBox() for trmCfgKey, _, trmCfgName in VM.TERMINAL_CONFIGS: trmCfgComboBox.addItem( trmCfgName,trmCfgKey ) trmCfgComboBox.setCurrentIndex( trmCfgComboBox.findData( parameters[ VM.TERMINAL_CONFIG ] ) ) def onConfigChange(): newConfig = trmCfgComboBox.itemData(trmCfgComboBox.currentIndex()) setParameter(VM.TERMINAL_CONFIG, newConfig) trmCfgComboBox.currentIndexChanged.connect(onConfigChange) layout.addRow( PARAM_NAMES[ PARAM_KEYS.index( VM.TERMINAL_CONFIG ) ], trmCfgComboBox ) vrngComboBox = QtGui.QComboBox() vrngKeys, vrngVals = zip(*VM.VOLTAGE_RANGES) for key, val in VM.VOLTAGE_RANGES: vrngComboBox.addItem( '%.2f (V)' % val, key ) vrngComboBox.setCurrentIndex( vrngComboBox.findData( parameters[ VM.VOLTAGE_RANGE ] ) ) vrngComboBox.currentIndexChanged.connect( compose( partial( setParameter, VM.VOLTAGE_RANGE ), vrngComboBox.itemData ) ) layout.addRow( PARAM_NAMES[ PARAM_KEYS.index( VM.VOLTAGE_RANGE ) ], vrngComboBox ) colorEditButton = QtGui.QPushButton('edit') colorEditButton.pressed.connect( compose( self.colorChanged.emit, partial( QtGui.QColorDialog.getColor, color ) ) ) layout.addRow('color',colorEditButton)
def test(): ## BOILERPLATE ## import sys from PySide import QtGui, QtCore from math import sin if QtCore.QCoreApplication.instance() is None: app = QtGui.QApplication(sys.argv) import qt4reactor qt4reactor.install() ## BOILERPLATE ## #create the widget name even if you're not using it so that onStepped doesn't error listScanInputWidget = None def log(x): print x #configure a layout for the plot widget & controls to go side by side on widget = QtGui.QWidget() widget.show() layout = QtGui.QHBoxLayout() widget.setLayout(layout) # create a plot and associated widget from pyqtgraph import PlotWidget plotWidget = PlotWidget() plot = plotWidget.plot() layout.addWidget(plotWidget) #configure a control panel layout controlPanel = QtGui.QWidget() cpLayout = QtGui.QVBoxLayout() controlPanel.setLayout(cpLayout) #create a scanToggleObject scanToggle = ScanToggleObject() ''' #create a list scan input & widget listScanInput = ListScanInput(lambda(x):x,None) listScanInputWidget = ListScanInputWidget(listScanInput) cpLayout.addWidget(listScanInputWidget) scanToggle.toggled.connect( compose( listScanInputWidget.setDisabled, scanToggle.isToggled ) ) scanToggle.toggled.connect(partial(log,listScanInputWidget.listScanInput.positions)) scanToggle.setInput(listScanInput.next) ''' #create an interval scan input & widget intScanInput = IntervalScanInput(lambda(x):x,0,1000,10) scanToggle.setInput(intScanInput.next) intScanInputWidget = IntervalScanInputWidget(intScanInput,DEFAULTS) cpLayout.addWidget(intScanInputWidget) scanToggle.toggled.connect( compose( intScanInputWidget.setDisabled, scanToggle.isToggled ) ) #create scan output, for now a sine wave, this is where voltmeter would go def output(): result = sin(float(output.i)/output.res) output.i+=1 return result output.i = 0 output.res = 10 scanToggle.setOutput(output) # create a scan toggle x, y = [], [] def onActivationRequested(x,y): while x: x.pop() while y: y.pop() scanToggle.toggle() # not performing any setup, so go ahead and connect activation requests to toggle scanToggle.activationRequested.connect( partial( onActivationRequested, x, y ) ) # create a toggle widget from qtutils.toggle import ToggleWidget cpLayout.addWidget(ToggleWidget(scanToggle)) # handle the stepped signal from ab.abbase import sleep @inlineCallbacks def onStepped(data): input, output = data x.append(input) y.append(output) plot.setData(x,y) yield sleep(.05) scanToggle.completeStep() if listScanInputWidget is not None: listScanInputWidget.updateQueue() scanToggle.stepped.connect(onStepped) #for debug purposes, connect to toggle signal scanToggle.toggled.connect(partial(log,'toggled')) scanToggle.toggleRequested.connect(partial(log,'toggleRequested')) #add the control panel to the window and execute layout.addWidget(controlPanel) app.exec_()