Esempio n. 1
0
    def __init__(self, parent=None, noconfig=False):
        super(Jansen, self).__init__(parent)
        self.setupUi(self)
        self.configuration = Configuration(self)

        # Setup vision tab
        try:
            self.vision.close()
            self.vision.setObjectName("vision")
            self.vision = QVision(self.tabVision)
            self.visionLayout.addWidget(self.vision)
            self.setupVision = True
        except Exception as ex2:
            err = ex2 if ex1 is None else ex1
            msg = 'Could not import Machine Vision pipeline: {}'
            logger.warning(msg.format(err))
            self.tabWidget.setTabEnabled(2, False)
            self.setupVision = False

        # Setup camera
        self.camera.close()  # remove placeholder widget from UI
        camera = QCamera()
        self.camera = camera
        self.screen.camera = camera
        self.cameraLayout.addWidget(camera)

        self.configureUi()
        self.connectSignals()

        self.doconfig = not noconfig
        if self.doconfig:
            self.restoreSettings()
Esempio n. 2
0
    def __init__(self, parent=None, doconfig=True):
        super(PyFab, self).__init__(parent)

        self.setupUi(self)
        self.configuration = Configuration(self)

        # Camera
        self.camera.close()  # remove placeholder widget from UI
        camera = QCamera()
        self.camera = camera
        self.screen.camera = camera
        self.cameraLayout.addWidget(camera)

        # Setup vision tab
        try:
            self.vision.close()
            self.vision.setObjectName("vision")
            self.vision = QVision(self.tabVision)
            self.visionLayout.addWidget(self.vision)
            self.setupVision = True
        except Exception as ex2:
            err = ex2 if ex1 is None else ex1
            msg = 'Could not import Machine Vision pipeline: {}'
            logger.warning(msg.format(err))
            self.tabWidget.setTabEnabled(2, False)
            self.setupVision = False

        # Spatial light modulator
        self.slm = QSLM(self)

        # Computation pipeline
        self.cgh.device = CGH(self, shape=self.slm.shape)
        self.cgh.device.start()

        # Trapping pattern is an interactive overlay
        # that translates user actions into hologram computations
        self.pattern = QTrappingPattern(parent=self)
        self.screen.addOverlay(self.pattern)

        # Trap automated assembly framework
        self.assembler = TrapAssemble(parent=self)
        self.mover = TrapMove(parent=self)

        # Process automation
        self.tasks = Taskmanager(self)

        self.configureUi()
        self.connectSignals()

        self.doconfig = doconfig
        if self.doconfig:
            self.restoreSettings()
Esempio n. 3
0
    def __init__(self, serialProtocol, parent=None):
        QMainWindow.__init__(self)

        # setup member variables
        self.serialProtocol = serialProtocol
        self.servos = {}
        self.columns = {}
        self.updating = False
        self.listenOnly = False
        self.timerDataRequest = QTimer(self)
        self.timerDataRequest.timeout.connect(self.timerDataRequest_timeout)

        # setup ui
        self.setupUi(self)
        self.buttonDataLog.setVisible(False)
        self.setWindowIcon(
            QIcon(os.path.join(BASE_PATH, 'res', 'SerialTool.png')))
        self.comboProtocolName.addItems(
            self.serialProtocol.availableProtocolNames)
        self.restoreGuiSettings()

        # open configuration file
        pathToScript = os.path.abspath(
            os.path.realpath(os.path.dirname(sys.argv[0])))
        nameOfScript = os.path.basename(sys.argv[0])
        self.configuration = Configuration(
            os.path.join(pathToScript, '%s.conf' % nameOfScript))

        self.converter = DataConverter(bigEndian=False)

        # restore data from configuration file
        self.restoreData()

        # init log view
        self.logView = LogView(self, self.textLogView)
        self.spinLogLevel.valueChanged.connect(self.logView.logLevelChanged)
        self.logView.logLevelChanged.emit(self.spinLogLevel.value(
        ))  # emit signal manually to set initial value

        # init data plot
        self.spinDataPlotInterval.valueChanged.connect(
            self.dataPlotIntervalChanged)
        self.buttonDataPlotClear.clicked.connect(self.dataPlotClear)
        self.buttonDataPlotPause.toggled.connect(self.dataPlotTogglePause)
        self.buttonDataPlotOsciMode.toggled.connect(
            self.dataPlot.toggleOscilloscopeMode)

        self.subscribedData = {}
        self.initTable()
Esempio n. 4
0
    def __init__(self, parent=None, noconfig=False):
        super(Jansen, self).__init__(parent)

        uifile = Path('jansenlib').joinpath('JansenWidget.ui')
        uic.loadUi(uifile, self)

        self.configuration = Configuration(self)

        self.setupCamera()
        self.configureUi()
        self.connectSignals()

        self.doconfig = not noconfig
        if self.doconfig:
            self.restoreSettings()
Esempio n. 5
0
    def __init__(self, parent=None, doconfig=True):
        super(PyFab, self).__init__(parent)

        uifile = Path('pyfablib').joinpath('FabWidget.ui')
        uic.loadUi(uifile, self)

        self.configuration = Configuration(self)

        # Camera
        self.camera.close()  # remove placeholder widget from UI
        self.camera = QCamera()
        self.screen.camera = self.camera
        self.cameraLayout.addWidget(self.camera)

        # Spatial light modulator
        self.slm = QSLM(self)

        # Computation pipeline
        self.cgh.device = CGH(self, shape=self.slm.shape).start()

        # Trapping pattern is an interactive overlay
        # that translates user actions into hologram computations
        self.pattern = QTrappingPattern(parent=self)
        self.screen.addOverlay(self.pattern)

        # Process automation
        self.tasks = QTaskmanager(self)
        self.TaskManagerView.setModel(self.tasks)
        self.TaskManagerView.setSelectionMode(3)

        self.configureUi()
        self.connectSignals()

        self.doconfig = doconfig
        if self.doconfig:
            self.restoreSettings()
Esempio n. 6
0
    def __init__(self, serialProtocol, parent=None):
        QMainWindow.__init__(self)

        # setup member variables
        self.serialProtocol = serialProtocol
        self.servos = {}
        self.columns = {}
        self.updating = False
        self.listenOnly = False
        self.timerDataRequest = QTimer(self)
        self.timerDataRequest.timeout.connect(self.timerDataRequest_timeout)

        # setup ui
        self.setupUi(self)
        self.buttonDataLog.setVisible(False)
        self.setWindowIcon(QIcon(os.path.join(BASE_PATH, 'res', 'SerialTool.png')))
        self.comboProtocolName.addItems(self.serialProtocol.availableProtocolNames)
        self.restoreGuiSettings()

        # open configuration file
        pathToScript = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
        nameOfScript = os.path.basename(sys.argv[0])
        self.configuration = Configuration(os.path.join(pathToScript, '%s.conf' % nameOfScript))

        self.converter = DataConverter(bigEndian=False)

        # restore data from configuration file
        self.restoreData()

        # init log view
        self.logView = LogView(self, self.textLogView)
        self.spinLogLevel.valueChanged.connect(self.logView.logLevelChanged)
        self.logView.logLevelChanged.emit(self.spinLogLevel.value()) # emit signal manually to set initial value

        # init data plot
        self.spinDataPlotInterval.valueChanged.connect(self.dataPlotIntervalChanged)
        self.buttonDataPlotClear.clicked.connect(self.dataPlotClear)
        self.buttonDataPlotPause.toggled.connect(self.dataPlotTogglePause)
        self.buttonDataPlotOsciMode.toggled.connect(self.dataPlot.toggleOscilloscopeMode)

        self.subscribedData = {}
        self.initTable()
Esempio n. 7
0
class PyFab(QMainWindow):
    def __init__(self, parent=None, doconfig=True):
        super(PyFab, self).__init__(parent)

        uifile = Path('pyfablib').joinpath('FabWidget.ui')
        uic.loadUi(uifile, self)

        self.configuration = Configuration(self)

        # Camera
        self.camera.close()  # remove placeholder widget from UI
        self.camera = QCamera()
        self.screen.camera = self.camera
        self.cameraLayout.addWidget(self.camera)

        # Spatial light modulator
        self.slm = QSLM(self)

        # Computation pipeline
        self.cgh.device = CGH(self, shape=self.slm.shape).start()

        # Trapping pattern is an interactive overlay
        # that translates user actions into hologram computations
        self.pattern = QTrappingPattern(parent=self)
        self.screen.addOverlay(self.pattern)

        # Process automation
        self.tasks = QTaskmanager(self)
        self.TaskManagerView.setModel(self.tasks)
        self.TaskManagerView.setSelectionMode(3)

        self.configureUi()
        self.connectSignals()

        self.doconfig = doconfig
        if self.doconfig:
            self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        self.pattern.clearTraps()
        self.screen.close()
        self.slm.close()
        self.cgh.device.stop()
        self.deleteLater()

    def configureUi(self):
        self.filters.screen = self.screen
        self.histogram.screen = self.screen
        self.dvr.screen = self.screen
        self.dvr.source = self.screen.default
        self.dvr.filename = self.configuration.datadir + 'pyfab.avi'

        self.TaskPropertiesLayout = QStackedLayout(self.TaskPropertiesView)
        index = self.tabWidget.indexOf(self.hardware.parent())
        self.tabWidget.setTabEnabled(index, self.hardware.has_content())
        self.slmView.setRange(xRange=[0, self.slm.width()],
                              yRange=[0, self.slm.height()],
                              padding=0)
        buildTaskMenu(self)
        self.adjustSize()

    def connectSignals(self):
        # Signals associated with arrival of images from camera
        newframe = self.screen.source.sigNewFrame
        # 1. Update histograms from image data
        newframe.connect(self.histogram.updateHistogram)
        # 2. CGH computations are coordinated with camera
        newframe.connect(self.pattern.refresh)

        # Signals associated with the CGH pipeline
        # 1. Screen events trigger requests for trap updates
        self.screen.sigMousePress.connect(self.pattern.mousePress)
        self.screen.sigMouseRelease.connect(self.pattern.mouseRelease)
        self.screen.sigMouseMove.connect(self.pattern.mouseMove)
        self.screen.sigMouseWheel.connect(self.pattern.mouseWheel)
        # 2. Trap widget reflects changes to trapping pattern
        self.pattern.sigCompute.connect(self.cgh.device.compute)
        self.pattern.trapAdded.connect(self.traps.registerTrap)
        # 3. Project result when calculation is complete
        self.cgh.device.sigHologramReady.connect(self.slm.setData)
        self.cgh.device.sigHologramReady.connect(self.slmView.setData)

        # Signals associated with GUI controls
        # 1. DVR Source
        self.bcamera.clicked.connect(
            lambda: self.setDvrSource(self.screen.default))
        self.bfilters.clicked.connect(lambda: self.setDvrSource(self.screen))

        # 2. Tab expose events
        self.tabWidget.currentChanged.connect(self.hardware.expose)
        self.tabWidget.currentChanged.connect(
            lambda n: self.slmView.setData(self.cgh.device.phi))

        # 3. Task pipeline
        self.bpausequeue.clicked.connect(self.pauseTasks)
        self.bclearqueue.clicked.connect(self.stopTasks)

        self.bpausesel.clicked.connect(self.tasks.toggleSelected)
        self.bclearsel.clicked.connect(self.tasks.removeSelected)
        self.bserialize.clicked.connect(
            lambda: self.tasks.serialize(self.experimentPath.text()))
        self.bdeserialize.clicked.connect(
            lambda: self.tasks.registerTask('QExperiment',
                                            info=self.experimentPath.text(),
                                            loop=self.loop.value()))

        self.TaskManagerView.clicked.connect(self.tasks.displayProperties)
        self.TaskManagerView.doubleClicked.connect(self.tasks.toggleCurrent)

    @pyqtSlot()
    def setDvrSource(self, source):
        self.dvr.source = source

    #
    # Slots for menu actions
    #
    def saveImage(self, qimage, select=False):
        if qimage is None:
            return
        filename = self.configuration.filename(suffix='.png')
        if select:
            getname = QFileDialog.getSaveFileName
            filename, _ = getname(self,
                                  'Save Image',
                                  directory=filename,
                                  filter='Image files (*.png)')
        if filename:
            qimage.save(filename)
            self.statusBar().showMessage('Saved ' + filename)

    @pyqtSlot()
    def savePhoto(self, select=False):
        qimage = self.screen.imageItem.qimage
        self.saveImage(qimage, select=select)

    @pyqtSlot()
    def savePhotoAs(self):
        self.savePhoto(select=True)

    @pyqtSlot()
    def saveHologram(self, select=False):
        self.saveImage(self.slm.qimage, select=select)

    @pyqtSlot()
    def saveHologramAs(self):
        self.saveHologram(select=True)

    @pyqtSlot()
    def saveSettings(self):
        if self.doconfig:
            self.configuration.save(self.camera)
            self.configuration.save(self.cgh)

    @pyqtSlot()
    def restoreSettings(self):
        if self.doconfig:
            self.configuration.restore(self.camera)
            self.configuration.restore(self.cgh)

    @pyqtSlot()
    def pauseTasks(self):
        self.tasks.pauseTasks()
        msg = 'Tasks paused' if self.tasks.paused else 'Tasks running'
        self.statusBar().showMessage(msg)

    @pyqtSlot()
    def stopTasks(self):
        self.tasks.clearTasks()
        self.statusBar().showMessage('Task queue cleared')
Esempio n. 8
0
from common.Configuration import Configuration
from jira import JIRA
import importlib

FETCHER_CLASS = "fetcher.class"

EXECUTOR_CLASS = "executor.class"

USER_NAME = "user.name"
PASSWD = "password"

JIRA_URL = "jira.url"

if __name__ == '__main__':
    if len(sys.argv) == 2:
        config = Configuration(sys.argv[1])
        config.print_conf()

        user = config.get(USER_NAME)[0]
        password = config.get(PASSWD)[0]
        jira_url = config.get(JIRA_URL)[0]
        jira = JIRA(jira_url, basic_auth=(user, password))

        fetcher_module = importlib.import_module('Fetcher.' +
                                                 config.get(FETCHER_CLASS)[0])
        fetcher_class = getattr(fetcher_module, config.get(FETCHER_CLASS)[0])
        fetcher = fetcher_class(jira, config)
        objects = fetcher.fetch()
        print objects
        executor_module = importlib.import_module(
            'Executor.' + config.get(EXECUTOR_CLASS)[0])
Esempio n. 9
0
class PyFab(QMainWindow, Ui_PyFab):
    def __init__(self, parent=None, doconfig=True):
        super(PyFab, self).__init__(parent)

        self.setupUi(self)
        self.configuration = Configuration(self)

        # Camera
        self.camera.close()  # remove placeholder widget from UI
        camera = QCamera()
        self.camera = camera
        self.screen.camera = camera
        self.cameraLayout.addWidget(camera)

        # Setup vision tab
        try:
            self.vision.close()
            self.vision.setObjectName("vision")
            self.vision = QVision(self.tabVision)
            self.visionLayout.addWidget(self.vision)
            self.setupVision = True
        except Exception as ex2:
            err = ex2 if ex1 is None else ex1
            msg = 'Could not import Machine Vision pipeline: {}'
            logger.warning(msg.format(err))
            self.tabWidget.setTabEnabled(2, False)
            self.setupVision = False

        # Spatial light modulator
        self.slm = QSLM(self)

        # Computation pipeline
        self.cgh.device = CGH(self, shape=self.slm.shape)
        self.cgh.device.start()

        # Trapping pattern is an interactive overlay
        # that translates user actions into hologram computations
        self.pattern = QTrappingPattern(parent=self)
        self.screen.addOverlay(self.pattern)

        # Trap automated assembly framework
        self.assembler = TrapAssemble(parent=self)
        self.mover = TrapMove(parent=self)

        # Process automation
        self.tasks = Taskmanager(self)

        self.configureUi()
        self.connectSignals()

        self.doconfig = doconfig
        if self.doconfig:
            self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        self.pattern.clearTraps()
        self.screen.close()
        self.slm.close()
        self.cgh.device.stop()
        self.deleteLater()

    def configureUi(self):
        self.filters.screen = self.screen
        self.histogram.screen = self.screen
        self.dvr.screen = self.screen
        self.dvr.source = self.screen.default
        self.dvr.filename = self.configuration.datadir + 'pyfab.avi'
        if self.setupVision:
            self.vision.jansen = self
        index = 3
        self.hardware.index = index
        self.tabWidget.currentChanged.connect(self.hardware.expose)
        self.tabWidget.setTabEnabled(index, self.hardware.has_content())
        self.slmView.setRange(xRange=[0, self.slm.width()],
                              yRange=[0, self.slm.height()],
                              padding=0)
        self.slmView.setYRange(0, self.slm.height())
        buildTaskMenu(self)
        self.adjustSize()

    def connectSignals(self):
        # Signals associated with GUI controls
        self.bcamera.clicked.connect(
            lambda: self.setDvrSource(self.screen.default))
        self.bfilters.clicked.connect(lambda: self.setDvrSource(self.screen))

        # Signals associated with handling images
        self.screen.source.sigNewFrame.connect(self.histogram.updateHistogram)
        self.screen.source.sigNewFrame.connect(self.assembler.move)
        self.screen.source.sigNewFrame.connect(self.mover.move)
        if self.setupVision:
            self.screen.sigNewFrame.connect(self.vision.process)

        # Signals associated with the CGH pipeline
        # 1. Screen events trigger requests for trap updates
        self.screen.sigMousePress.connect(self.pattern.mousePress)
        self.screen.sigMouseRelease.connect(self.pattern.mouseRelease)
        self.screen.sigMouseMove.connect(self.pattern.mouseMove)
        self.screen.sigMouseWheel.connect(self.pattern.mouseWheel)
        # 2. Updates to trapping pattern require hologram calculation
        self.pattern.sigCompute.connect(self.cgh.device.setTraps)
        self.pattern.trapAdded.connect(self.traps.registerTrap)
        # 3. Suppress requests while hologram is being computed
        self.cgh.device.sigComputing.connect(self.screen.pauseSignals)
        # 4. Project result when calculation is complete
        self.cgh.device.sigHologramReady.connect(self.slm.setData)
        self.cgh.device.sigHologramReady.connect(self.slmView.setData)

    @pyqtSlot()
    def setDvrSource(self, source):
        self.dvr.source = source

    #
    # Slots for menu actions
    #
    def saveImage(self, qimage, select=False):
        if qimage is None:
            return
        if select:
            getname = QFileDialog.getSaveFileName
            directory = self.configuration.datadir
            filename, _ = getname(self,
                                  'Save Image',
                                  directory=directory,
                                  filter='Image files (*.png)')
        else:
            filename = self.configuration.filename(suffix='.png')
        if filename:
            qimage.save(filename)
            self.statusBar().showMessage('Saved ' + filename)

    @pyqtSlot()
    def savePhoto(self, select=False):
        qimage = self.screen.imageItem.qimage.mirrored(vertical=True)
        self.saveImage(qimage, select=select)

    @pyqtSlot()
    def savePhotoAs(self):
        self.savePhoto(select=True)

    @pyqtSlot()
    def saveHologram(self, select=False):
        self.saveImage(self.slm.qimage, select=select)

    @pyqtSlot()
    def saveHologramAs(self):
        self.saveHologram(select=True)

    @pyqtSlot()
    def saveSettings(self):
        if self.doconfig:
            self.configuration.save(self.camera)
            self.configuration.save(self.cgh)
            if self.setupVision:
                self.configuration.save(self.vision)

    @pyqtSlot()
    def restoreSettings(self):
        if self.doconfig:
            self.configuration.restore(self.camera)
            self.configuration.restore(self.cgh)
            if self.setupVision:
                self.configuration.restore(self.vision)

    @pyqtSlot()
    def pauseTasks(self):
        self.tasks.pauseTasks()
        msg = 'Tasks paused' if self.tasks.paused() else 'Tasks running'
        self.statusBar().showMessage(msg)

    @pyqtSlot()
    def stopTasks(self):
        self.tasks.clearTasks()
        self.statusBar().showMessage('Task queue cleared')
Esempio n. 10
0
class MainWindow(QMainWindow, MainWindowClass):
    serialConnectionOpen = Signal(str, int)
    serialConnectionClose = Signal()
    serialConnectionStartListening = Signal()
    serialConnectionPing = Signal(list)
    serialConnectionScan = Signal()
    serialConnectionScanSlow = Signal()
    serialConnectionReadAllData = Signal(list)
    serialConnectionReadData = Signal(list, int, int)
    serialConnectionWriteData = Signal(list, int, list)
    serialConnectionSendData = Signal(list)
    serialConnectionSendCustomPacket = Signal(int, str, list)

    def __init__(self, serialProtocol, parent=None):
        QMainWindow.__init__(self)

        # setup member variables
        self.serialProtocol = serialProtocol
        self.servos = {}
        self.columns = {}
        self.updating = False
        self.listenOnly = False
        self.timerDataRequest = QTimer(self)
        self.timerDataRequest.timeout.connect(self.timerDataRequest_timeout)

        # setup ui
        self.setupUi(self)
        self.buttonDataLog.setVisible(False)
        self.setWindowIcon(QIcon(os.path.join(BASE_PATH, 'res', 'SerialTool.png')))
        self.comboProtocolName.addItems(self.serialProtocol.availableProtocolNames)
        self.restoreGuiSettings()

        # open configuration file
        pathToScript = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
        nameOfScript = os.path.basename(sys.argv[0])
        self.configuration = Configuration(os.path.join(pathToScript, '%s.conf' % nameOfScript))

        self.converter = DataConverter(bigEndian=False)

        # restore data from configuration file
        self.restoreData()

        # init log view
        self.logView = LogView(self, self.textLogView)
        self.spinLogLevel.valueChanged.connect(self.logView.logLevelChanged)
        self.logView.logLevelChanged.emit(self.spinLogLevel.value()) # emit signal manually to set initial value

        # init data plot
        self.spinDataPlotInterval.valueChanged.connect(self.dataPlotIntervalChanged)
        self.buttonDataPlotClear.clicked.connect(self.dataPlotClear)
        self.buttonDataPlotPause.toggled.connect(self.dataPlotTogglePause)
        self.buttonDataPlotOsciMode.toggled.connect(self.dataPlot.toggleOscilloscopeMode)

        self.subscribedData = {}
        self.initTable()


    def initTable(self):
        # stop the update timer
        self.timerDataRequest.stop()

        # init servo memory data table
        self.tableServoData.clear()
        self.tableServoData.setColumnCount(1)
        self.tableServoData.setHorizontalHeaderItem(0, QTableWidgetItem('Parameter'))
        self.tableServoData.setRowCount(len(self.serialProtocol.memoryInfo['fieldNames']))
        rowNumber = 0
        for fieldName in self.serialProtocol.memoryInfo['fieldNames']:
            fieldInfo = self.serialProtocol.memoryInfo[fieldName]
            nameItem = QTableWidgetItem(fieldInfo['name'])
            if fieldInfo['writable']:
                nameItem.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
            else:
                nameItem.setFlags(Qt.ItemFlag())
            self.tableServoData.setItem(rowNumber, 0, nameItem)
            self.tableServoData.resizeRowToContents(rowNumber)
            self.tableServoData.setRowHeight(rowNumber, self.tableServoData.rowHeight(rowNumber) - 7)
            rowNumber += 1
        self.tableServoData.resizeColumnToContents(0)

        # restart the update timer
        self.timerDataRequest.start(20)


    def closeEvent(self, event):
        self.saveGuiSettings()
        self.storeData()


    def storeData(self):
        # save baudrate combo
        baudrateList = []
        for i in range(self.comboSerialBaudrate.count()):
            baudrateList.append(int(self.comboSerialBaudrate.itemText(i)))
        baudrate = int(self.comboSerialBaudrate.currentText())

        baudrateList.sort()
        self.configuration.set('baudrateList', baudrateList)
        self.configuration.set('baudrate', baudrate)

        # save serial port combo
        portNameList = []
        for i in range(self.comboSerialPort.count()):
            portNameList.append(str(self.comboSerialPort.itemText(i)))

        portName = str(self.comboSerialPort.currentText())

        self.configuration.set('portNameList_%s' % os.name, portNameList)
        self.configuration.set('portName_%s' % os.name, portName)

        protocolName = str(self.comboProtocolName.currentText())
        self.configuration.set('protocolName', protocolName)


    def restoreData(self):
        # init baudrate combo
        baudrateList = self.configuration.get('baudrateList', [57600, 500000, 1000000])
        baudrate = self.configuration.get('baudrate', baudrateList[0])

        if not baudrate in baudrateList:
            baudrateList.append(baudrate)
            baudrateList.sort()

        currentIndex = baudrateList.index(baudrate)
        self.comboSerialBaudrate.addItems(map(str, baudrateList))
        self.comboSerialBaudrate.setCurrentIndex(currentIndex)

        # init serial port combo
        portNameList = self.configuration.get('portNameList_%s' % os.name, ['/dev/ttyUSB0'])
        if os.name == 'posix':
            portNameList = list(set(portNameList + glob.glob('/dev/ttyUSB*')))
        portName = self.configuration.get('portName_%s' % os.name, portNameList[0])
        portNameList.sort()

        self.comboSerialPort.addItems(portNameList)

        if portName in portNameList:
            self.comboSerialPort.setCurrentIndex(portNameList.index(portName))
        elif self.comboSerialPort.count > 0:
            self.comboSerialPort.setCurrentIndex(0)

        protocolName = self.configuration.get('protocolName', 'RobotisServo')
        self.comboProtocolName.setCurrentIndex(self.comboProtocolName.findText(protocolName))


    def saveGuiSettings(self):
        settings = QSettings('sim.informatik.tu-darmstadt.de', 'Servo Tool')
        settings.beginGroup('MainWindow')
        settings.setValue('state', QVariant(self.saveState()))
        settings.setValue('size', QVariant(self.size()))
        settings.setValue('pos', QVariant(self.pos()))
        settings.setValue('splitter', QVariant(self.splitter.saveState()))
        settings.setValue('splitter_2', QVariant(self.splitter_2.saveState()))
        settings.setValue('logLevel', QVariant(self.spinLogLevel.value()))
        settings.endGroup()


    def restoreGuiSettings(self):
        settings = QSettings('sim.informatik.tu-darmstadt.de', 'Servo Tool')
        settings.beginGroup('MainWindow')
        self.restoreState(settings.value('state', QVariant(QByteArray())).toByteArray())
        self.resize(settings.value('size', QVariant(QSize(800, 600))).toSize())
        self.move(settings.value('pos', QVariant(QPoint(200, 200))).toPoint())
        self.splitter.restoreState(settings.value('splitter', QVariant(QByteArray())).toByteArray())
        self.splitter_2.restoreState(settings.value('splitter_2', QVariant(QByteArray())).toByteArray())
        self.spinLogLevel.setValue(settings.value('logLevel', QVariant(3)).toInt()[0])
        settings.endGroup()


    def log(self, level, message):
        self.logView.logMessage.emit(level, message)


    def packetSent(self, packetBytes):
        # clear received data field, so unanswered packets don't show the last received packet
        self.textDataReceived.clear()
        formatString = '%02x ' * len(packetBytes)
        packetString = formatString % tuple(packetBytes)
        self.textDataSent.clear()
        self.textDataSent.appendPlainText(packetString)

    def packetReceived(self, packetBytes):
        formatString = '%02x ' * len(packetBytes)
        packetString = formatString % tuple(packetBytes)
        self.textDataReceived.clear()
        self.textDataReceived.appendPlainText(packetString)

    def servoChangedId(self, oldServoId, newServoId):
        self.comboServoId.setItemText(self.comboServoId.findText('%d' % oldServoId), '%d' % newServoId)
        columnNumber = self.servos[oldServoId]['columnNumber']
        self.tableServoData.setHorizontalHeaderItem(columnNumber, QTableWidgetItem('Id %d' % newServoId))
        self.tableServoData.resizeColumnToContents(columnNumber)
        self.servos[newServoId] = self.servos[oldServoId]
        self.servos[newServoId]['id'] = newServoId
        del self.servos[oldServoId]

    def servoDelete(self, servoId):
        self.comboServoId.removeItem(self.comboServoId.findText('%d' % servoId))
        columnNumber = self.servos[servoId]['columnNumber']
        # remove table column
        self.tableServoData.removeColumn(columnNumber)
        # remove servo mapping
        del self.servos[servoId]
        # correct other servo->column->servo mappings
        for servo in self.servos.values():
            if servo['columnNumber'] > columnNumber:
                del self.columns[servo['columnNumber']]
                servo['columnNumber'] -= 1
                self.columns[servo['columnNumber']] = servo

    def servoAdd(self, servoId):
        if self.servos.has_key(servoId):
            return
        self.comboServoId.addItem('%d' % servoId)
        columnNumber = self.tableServoData.columnCount()
        self.tableServoData.setColumnCount(columnNumber + 1)
        self.tableServoData.setHorizontalHeaderItem(columnNumber, QTableWidgetItem('Id %d' % servoId))
        self.tableServoData.resizeColumnToContents(columnNumber)
        self.servos[servoId] = {'id' : servoId, 'columnNumber': columnNumber}
        self.columns[columnNumber] = self.servos[servoId]
        self.labelNumServosFound.setText('%d found' % len(self.servos))


    def servoDataUpdate(self, servoId, addressOffset, servoData):
        if not self.servos.has_key(servoId):
            self.servoAdd(servoId)
        columnNumber = self.servos[servoId]['columnNumber']
        self.updating = True
        servoDataString = ('%c' * len(servoData)) % tuple(chr(c) for c in servoData)
        index = 0
        while index < len(servoDataString):
            fieldInfo = self.serialProtocol.memoryInfo[addressOffset + index]

            if fieldInfo['numElements'] != 1:
                self.log(0, 'ERROR: MainWindow.servoDataUpdate(): numElements != 1 -> Arrays are not supported, yet...')

            value = self.converter.fromString(servoDataString[index:], fieldInfo['type'])
            index += fieldInfo['size']

            # check if the item is being plotted
            subscribeId = '[%d].%s' % (servoId, fieldInfo['name'])
            if self.subscribedData.has_key(subscribeId):
                self.dataPlot.updateValue(subscribeId, float(value))

            # check for existing item, or create a new one
            dataItem = self.tableServoData.item(fieldInfo['index'], columnNumber)
            if not dataItem:
                dataItem = QTableWidgetItem()
                if fieldInfo['writable']:
                    dataItem.setFlags(Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable)
                else:
                    dataItem.setFlags(Qt.ItemFlag())
                self.tableServoData.setItem(fieldInfo['index'], columnNumber, dataItem)

            if type(value) == float:
                valueString = ('%.7f' % value).rstrip('0')
            else:
                valueString = str(value)
            dataItem.setText(valueString) # update item text
            dataItem.setToolTip(fieldInfo['makeToolTip'](value)) # update item tool tip

        self.tableServoData.resizeColumnToContents(columnNumber)
        self.updating = False


    def serialConnectionError(self):
        if self.buttonSerialConnect.isChecked():
            self.buttonSerialConnect.click()


    @Slot(str)
    def on_comboProtocolName_currentIndexChanged(self, text):
        self.serialProtocol.setProtocol(str(text))
        self.comboCustomCommand.clear()
        self.comboCustomCommand.addItems(self.serialProtocol.instructionName.values())
        servoIdList = self.servos.keys()
        self.servos = {}
        self.columns = {}
        self.initTable()
        for servoId in servoIdList:
            self.servoAdd(servoId)


    def enableButtons(self, enable):
        self.buttonServoScan.setEnabled(enable)
        self.buttonServoReadAll.setEnabled(enable)
        self.buttonServoRead.setEnabled(enable)
        self.buttonServoPing.setEnabled(enable)
        self.buttonCustomPacketSend.setEnabled(enable)


    @Slot(bool)
    def on_buttonSerialConnect_toggled(self, checked):
        self.comboSerialPort.setEnabled(not checked)
        self.comboSerialBaudrate.setEnabled(not checked)
        self.checkListenOnly.setEnabled(not checked)
        if checked:
            self.listenOnly = self.checkListenOnly.isChecked()
            self.enableButtons(not self.listenOnly)
            portName = str(self.comboSerialPort.currentText()).strip()
            if self.comboSerialPort.findText(portName) < 0:
                self.comboSerialPort.addItem(portName)
            self.serialConnectionOpen.emit(portName, int(self.comboSerialBaudrate.currentText()))
            if self.listenOnly:
                self.serialConnectionStartListening.emit()

        else:
            self.enableButtons(True)
            self.listenOnly = False
            self.dataPlotClear()
            self.servos = {}
            self.columns = {}
            self.tableServoData.setColumnCount(1)
            self.serialConnectionClose.emit()


    @Slot()
    def on_buttonServoScan_clicked(self):
        if not self.buttonSerialConnect.isChecked():
            self.buttonSerialConnect.click()
        self.servos = {}
        self.columns = {}
        self.tableServoData.setColumnCount(1)
        self.serialConnectionScan.emit()

    @Slot()
    def on_buttonServoScanSlow_clicked(self):
        if not self.buttonSerialConnect.isChecked():
            self.buttonSerialConnect.click()
        self.servos = {}
        self.columns = {}
        self.tableServoData.setColumnCount(1)
        self.serialConnectionScanSlow.emit()

    @Slot()
    def on_buttonServoReadAll_clicked(self):
        if not self.servos:
            self.on_buttonServoScan_clicked()
        self.serialConnectionReadAllData.emit(self.servos.keys())

    def getServoIdFrom_comboServoId(self):
        servoIdString = str(self.comboServoId.currentText()).strip()
        if len(servoIdString) == 0:
            self.log(0, 'Please enter a servo id.')
            return None
        try:
            servoId = int(servoIdString)
        except Exception, e:
            self.log(0, 'Error: %s' % e)
            return None
        return servoId
Esempio n. 11
0
class Jansen(QMainWindow, Ui_Jansen):

    def __init__(self, parent=None, noconfig=False):
        super(Jansen, self).__init__(parent)
        self.setupUi(self)
        self.configuration = Configuration(self)

        # Setup vision tab
        try:
            self.vision.close()
            self.vision.setObjectName("vision")
            self.vision = QVision(self.tabVision)
            self.visionLayout.addWidget(self.vision)
            self.setupVision = True
        except Exception as ex2:
            err = ex2 if ex1 is None else ex1
            msg = 'Could not import Machine Vision pipeline: {}'
            logger.warning(msg.format(err))
            self.tabWidget.setTabEnabled(2, False)
            self.setupVision = False

        # Setup camera
        self.camera.close()  # remove placeholder widget from UI
        camera = QCamera()
        self.camera = camera
        self.screen.camera = camera
        self.cameraLayout.addWidget(camera)

        self.configureUi()
        self.connectSignals()

        self.doconfig = not noconfig
        if self.doconfig:
            self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        self.screen.close()
        self.deleteLater()

    def configureUi(self):
        self.filters.screen = self.screen
        self.histogram.screen = self.screen
        self.dvr.screen = self.screen
        self.dvr.source = self.screen.default
        self.dvr.filename = self.configuration.datadir + 'jansen.avi'
        if self.setupVision:
            self.vision.jansen = self
        self.adjustSize()

    def connectSignals(self):
        self.bcamera.clicked.connect(
            lambda: self.setDvrSource(self.screen.default))
        self.bfilters.clicked.connect(
            lambda: self.setDvrSource(self.screen))
        self.actionSavePhoto.triggered.connect(self.savePhoto)
        self.actionSavePhotoAs.triggered.connect(
            lambda: self.savePhoto(True))

        # Signals associated with handling images
        self.screen.source.sigNewFrame.connect(self.histogram.updateHistogram)
        if self.setupVision:
            self.screen.sigNewFrame.connect(self.vision.process)

    @pyqtSlot()
    def setDvrSource(self, source):
        self.dvr.source = source

    #
    # Slots for menu actions
    #
    def saveImage(self, qimage, select=False):
        if qimage is None:
            return
        if select:
            getname = QFileDialog.getSaveFileName
            filename, _ = getname(self, 'Save Image',
                                  directory=filename,
                                  filter='Image files (*.png)')
        else:
            filename = self.configuration.filename(suffix='.png')
        if filename:
            qimage.save(filename)
            self.statusBar().showMessage('Saved ' + filename)

    @pyqtSlot()
    def savePhoto(self, select=False):
        qimage = self.screen.imageItem.qimage.mirrored(vertical=True)
        self.saveImage(qimage, select=select)

    @pyqtSlot()
    def savePhotoAs(self):
        self.savePhoto(select=True)

    @pyqtSlot()
    def saveSettings(self):
        if self.doconfig:
            self.configuration.save(self.camera)
            if self.setupVision:
                self.configuration.save(self.vision)

    @pyqtSlot()
    def restoreSettings(self):
        if self.doconfig:
            self.configuration.restore(self.camera)
            if self.setupVision:
                self.configuration.restore(self.vision)
Esempio n. 12
0
class MainWindow(QMainWindow, MainWindowClass):
    serialConnectionOpen = Signal(str, int)
    serialConnectionClose = Signal()
    serialConnectionStartListening = Signal()
    serialConnectionPing = Signal(list)
    serialConnectionScan = Signal()
    serialConnectionScanSlow = Signal()
    serialConnectionReadAllData = Signal(list)
    serialConnectionReadData = Signal(list, int, int)
    serialConnectionWriteData = Signal(list, int, list)
    serialConnectionSendData = Signal(list)
    serialConnectionSendCustomPacket = Signal(int, str, list)

    def __init__(self, serialProtocol, parent=None):
        QMainWindow.__init__(self)

        # setup member variables
        self.serialProtocol = serialProtocol
        self.servos = {}
        self.columns = {}
        self.updating = False
        self.listenOnly = False
        self.timerDataRequest = QTimer(self)
        self.timerDataRequest.timeout.connect(self.timerDataRequest_timeout)

        # setup ui
        self.setupUi(self)
        self.buttonDataLog.setVisible(False)
        self.setWindowIcon(
            QIcon(os.path.join(BASE_PATH, 'res', 'SerialTool.png')))
        self.comboProtocolName.addItems(
            self.serialProtocol.availableProtocolNames)
        self.restoreGuiSettings()

        # open configuration file
        pathToScript = os.path.abspath(
            os.path.realpath(os.path.dirname(sys.argv[0])))
        nameOfScript = os.path.basename(sys.argv[0])
        self.configuration = Configuration(
            os.path.join(pathToScript, '%s.conf' % nameOfScript))

        self.converter = DataConverter(bigEndian=False)

        # restore data from configuration file
        self.restoreData()

        # init log view
        self.logView = LogView(self, self.textLogView)
        self.spinLogLevel.valueChanged.connect(self.logView.logLevelChanged)
        self.logView.logLevelChanged.emit(self.spinLogLevel.value(
        ))  # emit signal manually to set initial value

        # init data plot
        self.spinDataPlotInterval.valueChanged.connect(
            self.dataPlotIntervalChanged)
        self.buttonDataPlotClear.clicked.connect(self.dataPlotClear)
        self.buttonDataPlotPause.toggled.connect(self.dataPlotTogglePause)
        self.buttonDataPlotOsciMode.toggled.connect(
            self.dataPlot.toggleOscilloscopeMode)

        self.subscribedData = {}
        self.initTable()

    def initTable(self):
        # stop the update timer
        self.timerDataRequest.stop()

        # init servo memory data table
        self.tableServoData.clear()
        self.tableServoData.setColumnCount(1)
        self.tableServoData.setHorizontalHeaderItem(
            0, QTableWidgetItem('Parameter'))
        self.tableServoData.setRowCount(
            len(self.serialProtocol.memoryInfo['fieldNames']))
        rowNumber = 0
        for fieldName in self.serialProtocol.memoryInfo['fieldNames']:
            fieldInfo = self.serialProtocol.memoryInfo[fieldName]
            nameItem = QTableWidgetItem(fieldInfo['name'])
            if fieldInfo['writable']:
                nameItem.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
            else:
                nameItem.setFlags(Qt.ItemFlag())
            self.tableServoData.setItem(rowNumber, 0, nameItem)
            self.tableServoData.resizeRowToContents(rowNumber)
            self.tableServoData.setRowHeight(
                rowNumber,
                self.tableServoData.rowHeight(rowNumber) - 7)
            rowNumber += 1
        self.tableServoData.resizeColumnToContents(0)

        # restart the update timer
        self.timerDataRequest.start(20)

    def closeEvent(self, event):
        self.saveGuiSettings()
        self.storeData()

    def storeData(self):
        # save baudrate combo
        baudrateList = []
        for i in range(self.comboSerialBaudrate.count()):
            baudrateList.append(int(self.comboSerialBaudrate.itemText(i)))
        baudrate = int(self.comboSerialBaudrate.currentText())

        baudrateList.sort()
        self.configuration.set('baudrateList', baudrateList)
        self.configuration.set('baudrate', baudrate)

        # save serial port combo
        portNameList = []
        for i in range(self.comboSerialPort.count()):
            portNameList.append(str(self.comboSerialPort.itemText(i)))

        portName = str(self.comboSerialPort.currentText())

        self.configuration.set('portNameList_%s' % os.name, portNameList)
        self.configuration.set('portName_%s' % os.name, portName)

        protocolName = str(self.comboProtocolName.currentText())
        self.configuration.set('protocolName', protocolName)

    def restoreData(self):
        # init baudrate combo
        baudrateList = self.configuration.get('baudrateList',
                                              [57600, 500000, 1000000])
        baudrate = self.configuration.get('baudrate', baudrateList[0])

        if not baudrate in baudrateList:
            baudrateList.append(baudrate)
            baudrateList.sort()

        currentIndex = baudrateList.index(baudrate)
        self.comboSerialBaudrate.addItems(map(str, baudrateList))
        self.comboSerialBaudrate.setCurrentIndex(currentIndex)

        # init serial port combo
        portNameList = self.configuration.get('portNameList_%s' % os.name,
                                              ['/dev/ttyUSB0'])
        if os.name == 'posix':
            portNameList = list(set(portNameList + glob.glob('/dev/ttyUSB*')))
        portName = self.configuration.get('portName_%s' % os.name,
                                          portNameList[0])
        portNameList.sort()

        self.comboSerialPort.addItems(portNameList)

        if portName in portNameList:
            self.comboSerialPort.setCurrentIndex(portNameList.index(portName))
        elif self.comboSerialPort.count > 0:
            self.comboSerialPort.setCurrentIndex(0)

        protocolName = self.configuration.get('protocolName', 'RobotisServo')
        self.comboProtocolName.setCurrentIndex(
            self.comboProtocolName.findText(protocolName))

    def saveGuiSettings(self):
        settings = QSettings('sim.informatik.tu-darmstadt.de', 'Servo Tool')
        settings.beginGroup('MainWindow')
        settings.setValue('state', QVariant(self.saveState()))
        settings.setValue('size', QVariant(self.size()))
        settings.setValue('pos', QVariant(self.pos()))
        settings.setValue('splitter', QVariant(self.splitter.saveState()))
        settings.setValue('splitter_2', QVariant(self.splitter_2.saveState()))
        settings.setValue('logLevel', QVariant(self.spinLogLevel.value()))
        settings.endGroup()

    def restoreGuiSettings(self):
        settings = QSettings('sim.informatik.tu-darmstadt.de', 'Servo Tool')
        settings.beginGroup('MainWindow')
        self.restoreState(
            settings.value('state', QVariant(QByteArray())).toByteArray())
        self.resize(settings.value('size', QVariant(QSize(800, 600))).toSize())
        self.move(settings.value('pos', QVariant(QPoint(200, 200))).toPoint())
        self.splitter.restoreState(
            settings.value('splitter', QVariant(QByteArray())).toByteArray())
        self.splitter_2.restoreState(
            settings.value('splitter_2', QVariant(QByteArray())).toByteArray())
        self.spinLogLevel.setValue(
            settings.value('logLevel', QVariant(3)).toInt()[0])
        settings.endGroup()

    def log(self, level, message):
        self.logView.logMessage.emit(level, message)

    def packetSent(self, packetBytes):
        # clear received data field, so unanswered packets don't show the last received packet
        self.textDataReceived.clear()
        formatString = '%02x ' * len(packetBytes)
        packetString = formatString % tuple(packetBytes)
        self.textDataSent.clear()
        self.textDataSent.appendPlainText(packetString)

    def packetReceived(self, packetBytes):
        formatString = '%02x ' * len(packetBytes)
        packetString = formatString % tuple(packetBytes)
        self.textDataReceived.clear()
        self.textDataReceived.appendPlainText(packetString)

    def servoChangedId(self, oldServoId, newServoId):
        self.comboServoId.setItemText(
            self.comboServoId.findText('%d' % oldServoId), '%d' % newServoId)
        columnNumber = self.servos[oldServoId]['columnNumber']
        self.tableServoData.setHorizontalHeaderItem(
            columnNumber, QTableWidgetItem('Id %d' % newServoId))
        self.tableServoData.resizeColumnToContents(columnNumber)
        self.servos[newServoId] = self.servos[oldServoId]
        self.servos[newServoId]['id'] = newServoId
        del self.servos[oldServoId]

    def servoDelete(self, servoId):
        self.comboServoId.removeItem(self.comboServoId.findText('%d' %
                                                                servoId))
        columnNumber = self.servos[servoId]['columnNumber']
        # remove table column
        self.tableServoData.removeColumn(columnNumber)
        # remove servo mapping
        del self.servos[servoId]
        # correct other servo->column->servo mappings
        for servo in self.servos.values():
            if servo['columnNumber'] > columnNumber:
                del self.columns[servo['columnNumber']]
                servo['columnNumber'] -= 1
                self.columns[servo['columnNumber']] = servo

    def servoAdd(self, servoId):
        if self.servos.has_key(servoId):
            return
        self.comboServoId.addItem('%d' % servoId)
        columnNumber = self.tableServoData.columnCount()
        self.tableServoData.setColumnCount(columnNumber + 1)
        self.tableServoData.setHorizontalHeaderItem(
            columnNumber, QTableWidgetItem('Id %d' % servoId))
        self.tableServoData.resizeColumnToContents(columnNumber)
        self.servos[servoId] = {'id': servoId, 'columnNumber': columnNumber}
        self.columns[columnNumber] = self.servos[servoId]
        self.labelNumServosFound.setText('%d found' % len(self.servos))

    def servoDataUpdate(self, servoId, addressOffset, servoData):
        if not self.servos.has_key(servoId):
            self.servoAdd(servoId)
        columnNumber = self.servos[servoId]['columnNumber']
        self.updating = True
        servoDataString = ('%c' * len(servoData)) % tuple(
            chr(c) for c in servoData)
        index = 0
        while index < len(servoDataString):
            fieldInfo = self.serialProtocol.memoryInfo[addressOffset + index]

            if fieldInfo['numElements'] != 1:
                self.log(
                    0,
                    'ERROR: MainWindow.servoDataUpdate(): numElements != 1 -> Arrays are not supported, yet...'
                )

            value = self.converter.fromString(servoDataString[index:],
                                              fieldInfo['type'])
            index += fieldInfo['size']

            # check if the item is being plotted
            subscribeId = '[%d].%s' % (servoId, fieldInfo['name'])
            if self.subscribedData.has_key(subscribeId):
                self.dataPlot.updateValue(subscribeId, float(value))

            # check for existing item, or create a new one
            dataItem = self.tableServoData.item(fieldInfo['index'],
                                                columnNumber)
            if not dataItem:
                dataItem = QTableWidgetItem()
                if fieldInfo['writable']:
                    dataItem.setFlags(Qt.ItemIsEnabled | Qt.ItemIsEditable
                                      | Qt.ItemIsSelectable)
                else:
                    dataItem.setFlags(Qt.ItemFlag())
                self.tableServoData.setItem(fieldInfo['index'], columnNumber,
                                            dataItem)

            if type(value) == float:
                valueString = ('%.7f' % value).rstrip('0')
            else:
                valueString = str(value)
            dataItem.setText(valueString)  # update item text
            dataItem.setToolTip(
                fieldInfo['makeToolTip'](value))  # update item tool tip

        self.tableServoData.resizeColumnToContents(columnNumber)
        self.updating = False

    def serialConnectionError(self):
        if self.buttonSerialConnect.isChecked():
            self.buttonSerialConnect.click()

    @Slot(str)
    def on_comboProtocolName_currentIndexChanged(self, text):
        self.serialProtocol.setProtocol(str(text))
        self.comboCustomCommand.clear()
        self.comboCustomCommand.addItems(
            self.serialProtocol.instructionName.values())
        servoIdList = self.servos.keys()
        self.servos = {}
        self.columns = {}
        self.initTable()
        for servoId in servoIdList:
            self.servoAdd(servoId)

    def enableButtons(self, enable):
        self.buttonServoScan.setEnabled(enable)
        self.buttonServoReadAll.setEnabled(enable)
        self.buttonServoRead.setEnabled(enable)
        self.buttonServoPing.setEnabled(enable)
        self.buttonCustomPacketSend.setEnabled(enable)

    @Slot(bool)
    def on_buttonSerialConnect_toggled(self, checked):
        self.comboSerialPort.setEnabled(not checked)
        self.comboSerialBaudrate.setEnabled(not checked)
        self.checkListenOnly.setEnabled(not checked)
        if checked:
            self.listenOnly = self.checkListenOnly.isChecked()
            self.enableButtons(not self.listenOnly)
            portName = str(self.comboSerialPort.currentText()).strip()
            if self.comboSerialPort.findText(portName) < 0:
                self.comboSerialPort.addItem(portName)
            self.serialConnectionOpen.emit(
                portName, int(self.comboSerialBaudrate.currentText()))
            if self.listenOnly:
                self.serialConnectionStartListening.emit()

        else:
            self.enableButtons(True)
            self.listenOnly = False
            self.dataPlotClear()
            self.servos = {}
            self.columns = {}
            self.tableServoData.setColumnCount(1)
            self.serialConnectionClose.emit()

    @Slot()
    def on_buttonServoScan_clicked(self):
        if not self.buttonSerialConnect.isChecked():
            self.buttonSerialConnect.click()
        self.servos = {}
        self.columns = {}
        self.tableServoData.setColumnCount(1)
        self.serialConnectionScan.emit()

    @Slot()
    def on_buttonServoScanSlow_clicked(self):
        if not self.buttonSerialConnect.isChecked():
            self.buttonSerialConnect.click()
        self.servos = {}
        self.columns = {}
        self.tableServoData.setColumnCount(1)
        self.serialConnectionScanSlow.emit()

    @Slot()
    def on_buttonServoReadAll_clicked(self):
        if not self.servos:
            self.on_buttonServoScan_clicked()
        self.serialConnectionReadAllData.emit(self.servos.keys())

    def getServoIdFrom_comboServoId(self):
        servoIdString = str(self.comboServoId.currentText()).strip()
        if len(servoIdString) == 0:
            self.log(0, 'Please enter a servo id.')
            return None
        try:
            servoId = int(servoIdString)
        except Exception, e:
            self.log(0, 'Error: %s' % e)
            return None
        return servoId
Esempio n. 13
0
class Jansen(QMainWindow):
    def __init__(self, parent=None, noconfig=False):
        super(Jansen, self).__init__(parent)

        uifile = Path('jansenlib').joinpath('JansenWidget.ui')
        uic.loadUi(uifile, self)

        self.configuration = Configuration(self)

        self.setupCamera()
        self.configureUi()
        self.connectSignals()

        self.doconfig = not noconfig
        if self.doconfig:
            self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        self.screen.close()
        self.deleteLater()

    def setupCamera(self):
        self.camera.close()  # remove placeholder widget from UI
        camera = QCamera()
        self.camera = camera
        self.screen.camera = camera
        self.cameraLayout.addWidget(camera)

    def configureUi(self):
        self.filters.screen = self.screen
        self.histogram.screen = self.screen
        self.dvr.screen = self.screen
        self.dvr.source = self.screen.default
        self.dvr.filename = self.configuration.datadir + 'jansen.avi'
        self.adjustSize()

    def connectSignals(self):
        self.bcamera.clicked.connect(
            lambda: self.setDvrSource(self.screen.default))
        self.bfilters.clicked.connect(lambda: self.setDvrSource(self.screen))
        self.actionSavePhoto.triggered.connect(self.savePhoto)
        self.actionSavePhotoAs.triggered.connect(lambda: self.savePhoto(True))

        # Signals associated with handling images
        self.screen.source.sigNewFrame.connect(self.histogram.updateHistogram)

    @pyqtSlot()
    def setDvrSource(self, source):
        self.dvr.source = source

    #
    # Slots for menu actions
    #
    def saveImage(self, qimage, select=False):
        if qimage is None:
            return
        filename = self.configuration.filename(suffix='.png')
        if select:
            getname = QFileDialog.getSaveFileName
            filename, _ = getname(self,
                                  'Save Image',
                                  directory=filename,
                                  filter='Image files (*.png)')
        if filename:
            qimage.save(filename)
            self.statusBar().showMessage('Saved ' + filename)

    @pyqtSlot()
    def savePhoto(self, select=False):
        qimage = self.screen.imageItem.qimage.mirrored(vertical=True)
        self.saveImage(qimage, select=select)

    @pyqtSlot()
    def savePhotoAs(self):
        self.savePhoto(select=True)

    @pyqtSlot()
    def saveSettings(self):
        if self.doconfig:
            self.configuration.save(self.camera)

    @pyqtSlot()
    def restoreSettings(self):
        if self.doconfig:
            self.configuration.restore(self.camera)