Esempio n. 1
0
    def on_connect_btn_clicked(self):
        serial_port_txt = self.serialPortEdit.text()
        if len(serial_port_txt) > 0:
            index = self.baudrateComboBox.currentIndex()
            if index == -1:
                error_dialog = QErrorMessage(self)
                error_dialog.setModal(True)                
                error_dialog.showMessage("Please select a baud rate")
            else:
                baud_rate = self.std_baudrates[index]
                try:
                    self.serial_port = serial.Serial(serial_port_txt, timeout=1, baudrate=baud_rate)
                except Exception as ex:
                    error_dialog = QErrorMessage(self)
                    error_dialog.setModal(True)                
                    error_dialog.showMessage(str(ex))
                else:
                    self.connectBtn.setEnabled(False)
                    self.disconnectBtn.setEnabled(True)
                    self.serialInputEdit.setEnabled(True)
                    self.connectionStatusLabelText.setText("Connected")
                    self.connectionStatusLabelIcon.setPixmap(self.connectedImagePixMap)
                    self.baudrateComboBox.setEnabled(False)

                    self.start_reader()
                    self.start_writer()
Esempio n. 2
0
 def show_error_box(title: str, text: str, parent: QWidget = None):
     error_box = QErrorMessage()
     # error_box.setParent(parent)
     error_box.setWindowTitle(title)
     error_box.setModal(True)
     error_box.setMaximumSize(600, 200)
     error_box.setMinimumSize(600, 200)
     x = error_box.showMessage(text)
     x = error_box.exec_()
Esempio n. 3
0
 def crash(self, error_text, save_world=False):
     """
     This constant function opens an QErrorMessage with the given error_text and forces python to
     exit the program. Only call this if a fatal error has happened.
     """
     if save_world:
         self.save_world()
     error_message = QErrorMessage()
     error_message.setModal(True)
     error_message.showMessage(error_text)
     exit(error_message.exec_())
Esempio n. 4
0
 def excepthook_errormsg(exc_type, exc_value, exc_tb):
     error_box = QErrorMessage()
     error_box.setWindowTitle("Błąd")
     tb = "\n".join(traceback.format_exception(exc_type, exc_value, exc_tb))
     error_box.setMaximumSize(600, 200)
     error_box.setMinimumSize(600, 200)
     error_box.setModal(True)
     print(tb, file=sys.stderr, flush=True)
     x = error_box.showMessage(tb)
     x = error_box.exec_()
     QtWidgets.QApplication.quit()
Esempio n. 5
0
 def _saveCfgFile(self,file):
     try:
         self.fileDialog.close()
     except: pass
     try:
         self.config.config["version"] = self.config.config["version"] + 1
         self.config.save(file)
         
         self.mainWindow.statusbar.showMessage("Saved Configufration File: {0}.".format(file),5000)
         
         
     except:
         err = QErrorMessage(self.window)
         err.showMessage("Unable to save config file.")
         err.setModal(True)
         err.show()
Esempio n. 6
0
 def _openCfgFile(self,file):
     self.config.locked = True
     try:
         self.fileDialog.close()
     except: pass
     try:
         self.config.load(file)
         self.mainWindow.statusbar.showMessage("Loaded Configufration File: {0}.".format(file),5000)
         self.syncConfigToUI()
         self.toggleNetParams()
         
     except:
         err = QErrorMessage(self.window)
         err.showMessage("Unable to parse config file.")
         err.setModal(True)
         err.show()
     self.config.locked = False
     self.autoExec()
Esempio n. 7
0
class Gui(QMainWindow):
    """Principal window of the GUI."""
    def __init__(self):
        QMainWindow.__init__(self)
        self.setup()

    def setup(self):
        """Set up the main window."""

        self.setWindowTitle("GeOptics")

        self.statusBar()

        self.show()

        self.current_filename = None

        # main drawing area
        self.scene = Scene()
        self.view = GraphicsView()
        self.view.setScene(self.scene.g)
        # set a default view right now,
        # so no need for the mouse to enter the view
        self.scene.g.active_view = self.view
        self.graphicsView_frame = GraphicsViewFrame(view=self.view)
        self.scene.g.signal_mouse_position_changed.connect(
            self.graphicsView_frame.position_indicator.on_changed_position)
        self.setCentralWidget(self.graphicsView_frame)

        # menus
        # use theme icons whenever possible, names from
        # http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html

        icon = QIcon.fromTheme('document-open')
        open_action = QAction(icon, 'Open', self)
        open_action.setShortcut('Ctrl+O')
        open_action.setStatusTip('Clear scene and load from file')
        open_action.triggered.connect(self.open)

        icon = QIcon.fromTheme('document-open')
        import_action = QAction(icon, 'Import', self)
        import_action.setShortcut('Ctrl+I')
        import_action.setStatusTip('Import from file')
        import_action.triggered.connect(self.import_slot)

        icon = QIcon.fromTheme('document-save')
        save_action = QAction(icon, 'Save', self)
        save_action.setShortcut(QKeySequence.Save)
        save_action.setStatusTip('Save')
        save_action.triggered.connect(self.save)

        icon = QIcon.fromTheme('document-save-as')
        saveas_action = QAction(icon, 'Save As', self)
        saveas_action.setShortcut(QKeySequence.SaveAs)
        saveas_action.setStatusTip('Save As')
        saveas_action.triggered.connect(self.saveas)

        icon = QIcon.fromTheme('application-exit')
        exit_action = QAction(icon, 'Exit', self)
        exit_action.setShortcut(QKeySequence.Quit)
        exit_action.setStatusTip('Exit application')
        exit_action.triggered.connect(self.exit)

        icon = QIcon.fromTheme('text-field')
        display_action = QAction(icon, 'Display', self)
        display_action.setShortcut('Ctrl+D')
        display_action.setStatusTip('Display')
        display_action.triggered.connect(self.display)

        icon = QIcon.fromTheme('edit-select-all')
        select_all_action = QAction(icon, 'Select All', self)
        select_all_action.setShortcut(QKeySequence.SelectAll)
        select_all_action.setStatusTip('Select All')
        select_all_action.triggered.connect(self.select_all)

        menubar = self.menuBar()

        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(open_action)
        fileMenu.addAction(import_action)
        fileMenu.addAction(save_action)
        fileMenu.addAction(saveas_action)
        fileMenu.addAction(exit_action)

        toolsMenu = menubar.addMenu('&Edit')
        toolsMenu.addAction(select_all_action)

        editMenu = menubar.addMenu('&Tools')
        editMenu.addAction(display_action)

        # toolbars
        icon = QIcon.fromTheme('snap-orthogonal')
        move_restrictions_action = QAction(icon,
                                           'Move restrictions',
                                           self,
                                           checkable=True)
        move_restrictions_action.setShortcut('Ctrl+R')
        move_restrictions_action.setStatusTip('Restrict movements')
        move_restrictions_action.toggled.connect(self.set_move_restrictions)

        # name must be unique (it is used internally by saveState()
        name = "Move restrictions"
        move_restrictions_toolbar = QToolBar(name, parent=self)
        move_restrictions_toolbar.setObjectName(name)
        move_restrictions_toolbar.addAction(move_restrictions_action)

        self.addToolBar(move_restrictions_toolbar)

        self.error_dialog = QErrorMessage(parent=self)
        self.error_dialog.setModal(True)
        # to use it, remember to .exec() it :
        #self.error_dialog.showMessage(message_str)
        #self.error_dialog.exec()

        # get windows settings
        # this must be at the end, because toolbar names must have been defined
        self.read_settings()

    def start(self):
        """Start GUI."""

        if app_created_here:
            sys.exit(app.exec_())

    def exit(self):
        """Clean exit."""

        self.close()

    def closeEvent(self, event):
        """Overload QMainWindow."""

        self.write_settings()
        QMainWindow.closeEvent(self, event)
        # we could call a dialog, and on cancel, call event.ignore()

    def display(self):
        """Dump the scene configuration to :obj:`sys.stdout`."""
        self.dump(stream=sys.stdout)

    def dump(self, stream=None):
        """Dump the scene configuration to stream.
		
		Args:
			stream (file object, optional): by default, use :obj:`sys.stdout`
		"""
        if stream is None:
            # do not put stream=sys.stdout in the function header
            # this would yields
            # "AttributeError: 'bool' object has no attribute 'write'"
            stream = sys.stdout
        config = {'Scene': self.scene.config}
        yaml.dump(config, stream=stream)

    @pyqtSlot()
    def import_slot(self):
        """Fire up a file dialog, and append the file content to the scene."""

        self.load_with_dialog(reset_scene=False)

    def import_file(self, filename):
        """Import regions and sources from file.
		
		Previous elements in the scene are left untouched.
		"""
        with open(filename, 'r') as f:
            config = yaml.safe_load(stream=f)
            if 'Scene' in config:
                self.scene.add(config['Scene'])
            else:
                self.scene.add(config)

    @pyqtSlot()
    def open(self):
        """Fire up a file dialog, empty scene, and load the file content."""

        self.load_with_dialog(reset_scene=True)

    def load_file(self, filename, reset_scene=True):
        """Import regions and sources from file.
		
		Args:
			filename (str): path or name of the file to load from
			reset_scene (bool): If True, the scene is emptied before loading
		"""
        config_backup = self.scene.config
        try:
            if reset_scene:
                self.scene.clear()
            self.import_file(filename)
            logger.info("import from {} succeeded".format(filename))
            success = True
            message_str = ""
        except Exception as e:
            # rollback
            message_str = ("import from {} failed\n"
                           "  here is the exception:\n"
                           "  {}\n"
                           "  =>rolling back").format(filename, e)
            logger.info(message_str)
            self.scene.config = config_backup
            success = False
        return success, message_str

    def load_with_dialog(self, reset_scene=True):
        """Open a file dialog and load the file content into the scene.
		
		If the dialog is cancelled, the scene is left untouched.
		
		Args:
			reset_scene (bool): see :meth:`load_file`.
		"""
        if reset_scene:
            caption = "Select file to open"
        else:
            caption = "Select file to import from"

        # discard the filter used
        filename, _ = QFileDialog.getOpenFileName(
            parent=self,
            caption=caption,
            directory="./",
            filter="GeOptics files (*.geoptics);; All files (*)")
        # upon cancel filename is empty and this step is skipped
        if filename:
            success, message_str = self.load_file(filename, reset_scene)
            if not success:
                # tried with self.error_dialog, but
                # the checkbox was not honored (kept showing up);
                # giving up...
                #self.error_dialog.showMessage(message_str)
                #self.error_dialog.exec()
                # a simple QMessageBox is enough
                message_box = QMessageBox()
                message_box.critical(self, "Error", message_str)
                # try again
                self.load_with_dialog(reset_scene)

    def print_(self, *args):
        """Print immediately to stderr.
		
		Same as ``print(*args)``,
		but do not block until exit.
		"""
        str = "".join(["{}".format(arg) for arg in args])
        qDebug(str)

    @pyqtSlot()
    def save(self):
        """Save current session to the current file (overwrite)."""

        self.saveas(self.current_filename)

    # need the @pyqtSlot() decorator,
    # otherwise this slot would be called
    # with an argument, "checked", which is a boolean
    # filename would get this boolean value, instead of the default value
    @pyqtSlot()
    def saveas(self, filename=None):
        """Save session to file.
		
		Args:
			filename (str):
				the path or name of the file to save to.
				If filename is `None`, then open a file dialog.
		"""
        if filename is None:
            # discard the filter used
            filename, _ = QFileDialog.getSaveFileName(
                parent=self,
                caption="Saving as...",
                directory="./",
                filter="GeOptics files (*.geoptics);; All files (*)")
        if filename:
            with open(filename, 'w') as f:
                self.dump(stream=f)
                logger.info("saved to {}".format(filename))
                self.current_filename = filename
        else:
            logger.warning('Filename is "{}", save cancelled'.format(filename))

    @pyqtSlot(bool)
    def set_move_restrictions(self, state):
        """Set move restrictions on/off.
		
		Args:
			state (bool):
				if True, movements are constrained to be horizontal or vertical.
		"""

        #print "move restrictions: ", state
        self.scene.g.move_restrictions_on = state

    def write_settings(self):
        """Store application settings."""

        settings = QSettings()
        settings.beginGroup("MainWindow")
        settings.setValue("size", self.size())
        settings.setValue("pos", self.pos())
        settings.setValue("MainwindowState", self.saveState())
        settings.endGroup()

    def read_settings(self):
        """Read application settings."""

        # remember we use sip.setapi('QVariant', 2)
        # in gui.qt.__init__.py (more info there)
        # hence we _must_ give the "type=" keyword arguments to value()
        settings = QSettings()
        settings.beginGroup("MainWindow")
        self.resize(settings.value("size", QSize(400, 400), type=QSize))
        self.move(settings.value("pos", QPoint(10, 10), type=QPoint))
        old_settings = settings.value("MainwindowState")
        if old_settings:
            self.restoreState(old_settings)
        settings.endGroup()

    def select_all(self):
        """Select all items in the scene."""

        self.scene.g.signal_set_all_selected.emit(True)