# -*- coding: utf-8 -*- """ GEPARD - Gepard-Enabled PARticle Detection Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für Polymerforschung Dresden e. V. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program, see COPYING. If not, see . """ from PyQt5 import QtCore, QtWidgets, QtGui from sampleview import SampleView from scalebar import ScaleBar from ramancom.ramancontrol import defaultPath from ramancom.ramanSwitch import RamanSwitch from analysis.colorlegend import ColorLegend import os class GEPARDMainWindow(QtWidgets.QMainWindow): def __init__(self, logpath): super(GEPARDMainWindow, self).__init__() self.setWindowTitle("GEPARD") self.resize(900, 700) self.view = SampleView(logpath) self.view.imparent = self self.view.ScalingChanged.connect(self.scalingChanged) self.scalebar = ScaleBar(self) self.legend = ColorLegend(self) self.ramanSwitch = RamanSwitch(self) self.view.ScalingChanged.connect(self.scalebar.updateScale) mdiarea = QtWidgets.QMdiArea(self) mdiarea.addSubWindow(self.scalebar) mdiarea.addSubWindow(self.legend) mdiarea.addSubWindow(self.ramanSwitch) self.legend.hide() self.ramanSwitch.hide() subview = mdiarea.addSubWindow(self.view) subview.showMaximized() subview.setWindowFlags(QtCore.Qt.FramelessWindowHint) mdiarea.setOption(QtWidgets.QMdiArea.DontMaximizeSubWindowOnActivation) self.setCentralWidget(mdiarea) self.createActions() self.createMenus() self.createToolBar() self.updateModes() def resizeEvent(self, event): self.scalebar.move(0,self.height()-self.scalebar.height()-30) self.legend.move(self.width()-self.legend.width()-130, 10) self.ramanSwitch.move(5, 5) def closeEvent(self, event): self.view.closeEvent(event) @QtCore.pyqtSlot(float) def scalingChanged(self, scale): self.zoomInAct.setEnabled(self.view.scaleFactor < 20.0) self.zoomOutAct.setEnabled(self.view.scaleFactor > .01) self.normalSizeAct.setEnabled(self.view.scaleFactor != 1.) @QtCore.pyqtSlot() def open(self, fileName=False): if fileName is False: fileName = QtWidgets.QFileDialog.getOpenFileName(self, "Open Project", defaultPath, "*.pkl")[0] if fileName: self.fname = str(fileName) self.view.open(self.fname) self.scalingChanged(1.) @QtCore.pyqtSlot() def importProject(self, fileName=False): if fileName is False: fileName = QtWidgets.QFileDialog.getOpenFileName(self, "Import Zeiss Zen Project", defaultPath, "*.xml")[0] if fileName: self.fname = str(fileName) self.view.importProject(self.fname) self.scalingChanged(1.) @QtCore.pyqtSlot() def new(self, fileName=False): if fileName is False: fileName = QtWidgets.QFileDialog.getSaveFileName(self, "Create New Project", defaultPath, "*.pkl")[0] if fileName: isValid, msg = self.testFilename(fileName) if isValid: self.fname = str(fileName) #TODO: No spaces for Renishaw Interface!! self.view.new(self.fname) self.scalingChanged(1.) else: QtWidgets.QMessageBox.critical(self, "Error", msg) def testFilename(self, fileName): if self.view.ramanctrl.name == 'RenishawCOM': #the renishawCom does not allow Spaces within filePath if fileName.find(' ') == 0: return False, "File path must not contain spaces." else: return True, "" else: return True, "" @QtCore.pyqtSlot() def about(self): QtWidgets.QMessageBox.about(self, 'GEPARD', "Developed by Complex Fiber Structures GmbH on behalf of Leibniz-IPF Dresden") def createActions(self): fname = os.path.join(os.path.split(__file__)[0], os.path.join("data","brand.png")) self.aboutAct = QtWidgets.QAction(QtGui.QIcon(fname), "About Particle Measurment", self) self.aboutAct.triggered.connect(self.about) self.openAct = QtWidgets.QAction("&Open Project...", self) self.openAct.setShortcut("Ctrl+O") self.openAct.triggered.connect(self.open) self.importAct = QtWidgets.QAction("&Import Project...", self) self.importAct.setShortcut("Ctrl+I") self.importAct.triggered.connect(self.importProject) self.newAct = QtWidgets.QAction("&New Measurement...", self) self.newAct.setShortcut("Ctrl+N") self.newAct.triggered.connect(self.new) self.exitAct = QtWidgets.QAction("E&xit", self) self.exitAct.setShortcut("Ctrl+Q") self.exitAct.triggered.connect(self.close) self.zoomInAct = QtWidgets.QAction("Zoom &In (25%)", self) self.zoomInAct.setShortcut("Ctrl++") self.zoomInAct.setEnabled(False) self.zoomInAct.triggered.connect(self.view.zoomIn) self.zoomOutAct = QtWidgets.QAction("Zoom &Out (25%)", self) self.zoomOutAct.setShortcut("Ctrl+-") self.zoomOutAct.setEnabled(False) self.zoomOutAct.triggered.connect(self.view.zoomOut) self.normalSizeAct = QtWidgets.QAction("&Normal Size", self) self.normalSizeAct.setShortcut("Ctrl+S") self.normalSizeAct.setEnabled(False) self.normalSizeAct.triggered.connect(self.view.normalSize) self.fitToWindowAct = QtWidgets.QAction("&Fit to Window", self) self.fitToWindowAct.setShortcut("Ctrl+E") self.fitToWindowAct.setEnabled(True) self.fitToWindowAct.triggered.connect(self.view.fitToWindow) self.connectRamanAct = QtWidgets.QAction("Connect to Microscope", self) self.connectRamanAct.setEnabled(True) self.connectRamanAct.triggered.connect(self.view.connectRaman) self.disconnectRamanAct = QtWidgets.QAction("Release Microscope", self) self.disconnectRamanAct.setEnabled(False) self.disconnectRamanAct.triggered.connect(self.view.disconnectRaman) self.opticalScanAct = QtWidgets.QAction("Optical Scan", self) self.opticalScanAct.setEnabled(False) self.opticalScanAct.setCheckable(True) self.opticalScanAct.triggered.connect(QtCore.pyqtSlot()(lambda :self.view.switchMode("OpticalScan"))) self.detectParticleAct = QtWidgets.QAction("Detect Particles", self) self.detectParticleAct.setEnabled(False) self.detectParticleAct.setCheckable(True) self.detectParticleAct.triggered.connect(QtCore.pyqtSlot()(lambda :self.view.switchMode("ParticleDetection"))) self.ramanScanAct = QtWidgets.QAction("Raman Scan", self) self.ramanScanAct.setEnabled(False) self.ramanScanAct.setCheckable(True) self.ramanScanAct.triggered.connect(QtCore.pyqtSlot()(lambda :self.view.switchMode("RamanScan"))) self.particelAnalysisAct = QtWidgets.QAction("Particle analysis", self) self.particelAnalysisAct.setEnabled(False) self.particelAnalysisAct.setCheckable(True) self.particelAnalysisAct.triggered.connect(QtCore.pyqtSlot()(lambda :self.view.switchMode("ParticleAnalysis"))) self.snapshotAct = QtWidgets.QAction("Save Screenshot", self) self.snapshotAct.triggered.connect(self.view.takeScreenshot) self.snapshotAct.setDisabled(True) self.configRamanCtrlAct = QtWidgets.QAction("Configure Raman Control", self) self.configRamanCtrlAct.triggered.connect(self.view.configureRamanControl) if self.view.simulatedRaman: self.configRamanCtrlAct.setDisabled(True) def updateModes(self, active=None, maxenabled=None): ose, osc, pde, pdc, rse, rsc, pae, pac = [False]*8 if maxenabled=="OpticalScan": ose = True elif maxenabled=="ParticleDetection": ose, pde = True, True elif maxenabled=="RamanScan": ose, pde, rse = True, True, True elif maxenabled=="ParticleAnalysis": ose, pde, rse, pae = True, True, True, True if active=="OpticalScan" and ose: osc = True elif active=="ParticleDetection" and pde: pdc = True elif active=="RamanScan" and rse: rsc = True elif active=="ParticleAnalysis" and pae: pac = True self.opticalScanAct.setEnabled(ose) self.opticalScanAct.setChecked(osc) self.detectParticleAct.setEnabled(pde) self.detectParticleAct.setChecked(pdc) self.ramanScanAct.setEnabled(rse) self.ramanScanAct.setChecked(rsc) self.particelAnalysisAct.setEnabled(pae) self.particelAnalysisAct.setChecked(pac) def unblockUI(self, connected): self.openAct.setEnabled(True) self.importAct.setEnabled(True) self.newAct.setEnabled(True) self.updateConnected(connected) self.exitAct.setEnabled(True) def blockUI(self): self.openAct.setEnabled(False) self.importAct.setEnabled(False) self.newAct.setEnabled(False) self.connectRamanAct.setEnabled(False) self.disconnectRamanAct.setEnabled(False) self.exitAct.setEnabled(False) self.opticalScanAct.setEnabled(False) self.detectParticleAct.setEnabled(False) self.ramanScanAct.setEnabled(False) self.particelAnalysisAct.setEnabled(False) def updateConnected(self, connected): if connected: self.connectRamanAct.setEnabled(False) self.disconnectRamanAct.setEnabled(True) else: self.connectRamanAct.setEnabled(True) self.disconnectRamanAct.setEnabled(False) def createMenus(self): self.fileMenu = QtWidgets.QMenu("&File", self) self.fileMenu.addAction(self.newAct) self.fileMenu.addAction(self.importAct) self.fileMenu.addAction(self.openAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAct) self.viewMenu = QtWidgets.QMenu("&View", self) self.viewMenu.addAction(self.zoomInAct) self.viewMenu.addAction(self.zoomOutAct) self.viewMenu.addAction(self.normalSizeAct) self.viewMenu.addSeparator() self.viewMenu.addAction(self.fitToWindowAct) self.modeMenu = QtWidgets.QMenu("&Mode", self) self.modeMenu.addAction(self.opticalScanAct) self.modeMenu.addAction(self.detectParticleAct) self.modeMenu.addAction(self.particelAnalysisAct) self.toolsMenu = QtWidgets.QMenu("&Tools") self.toolsMenu.addAction(self.snapshotAct) self.toolsMenu.addAction(self.configRamanCtrlAct) self.helpMenu = QtWidgets.QMenu("&Help", self) self.helpMenu.addAction(self.aboutAct) self.menuBar().addMenu(self.fileMenu) self.menuBar().addMenu(self.viewMenu) self.menuBar().addMenu(self.modeMenu) self.menuBar().addMenu(self.toolsMenu) self.menuBar().addMenu(self.helpMenu) def createToolBar(self): self.toolbar = QtWidgets.QToolBar("Tools") self.toolbar.setIconSize(QtCore.QSize(100,50)) self.toolbar.addAction(self.aboutAct) self.toolbar.addAction(self.newAct) self.toolbar.addAction(self.importAct) self.toolbar.addAction(self.openAct) self.toolbar.addSeparator() self.toolbar.addAction(self.connectRamanAct) self.toolbar.addAction(self.disconnectRamanAct) self.toolbar.addSeparator() self.toolbar.addAction(self.opticalScanAct) self.toolbar.addAction(self.detectParticleAct) self.toolbar.addAction(self.ramanScanAct) self.toolbar.addAction(self.particelAnalysisAct) self.toolbar.addSeparator() self.toolbar.addAction(self.exitAct) self.toolbar.setOrientation(QtCore.Qt.Vertical) self.addToolBar(QtCore.Qt.LeftToolBarArea, self.toolbar) if __name__ == '__main__': import sys from time import localtime, strftime app = QtWidgets.QApplication(sys.argv) app.setApplicationName("GEPARD") # appname needed for logpath logpath = QtCore.QStandardPaths.writableLocation( QtCore.QStandardPaths.AppLocalDataLocation) fp = None if logpath != "": if not os.path.exists(logpath): os.mkdir(logpath) logname = os.path.join(logpath, 'logfile.txt') fp = open(logname, "a") sys.stderr = fp sys.stdout = fp print("starting GEPARD at: " + strftime("%d %b %Y %H:%M:%S", localtime()), flush=True) gepard = GEPARDMainWindow(logpath) gepard.showMaximized() ret = app.exec_() if fp is not None: fp.close()