Ejemplo n.º 1
0
class StackedPage(QWidget):
    def __init__(self, parent = None):
        super(StackedPage, self).__init__(parent)
        layout = QHBoxLayout(self)
        leftpane = QVBoxLayout()
        self.buttongroup = QButtonGroup(self)
        self.buttongroup.setExclusive(True)
        self.groupbox = QGroupBox(self)
        self.groupbox.setMinimumWidth(200)
        QVBoxLayout(self.groupbox)
        leftpane.addWidget(self.groupbox)
        leftpane.addStretch(1)
        layout.addLayout(leftpane)
        self.rightpane = QStackedWidget(self)
        layout.addWidget(self.rightpane)
        self.buttongroup.buttonClicked[int].connect(self.rightpane.setCurrentIndex)
        self.rightpane.currentChanged[int].connect(self.activate)
         
    def addPage(self, buttontext, widget):
        button = QPushButton(buttontext)
        button.setCheckable(True)
        button.setChecked(self.rightpane.count() == 0)
        self.buttongroup.addButton(button, self.rightpane.count())
        self.groupbox.layout().addWidget(button)
        self.rightpane.addWidget(widget)
        
    def pages(self):
        return [ self.rightpane.widget(i) for i in range(self.rightpane.count()) ]

    def activate(self, ix):
        page = self.rightpane.currentWidget()
        if hasattr(page, "activate") and callable(page.activate):
            page.activate()
            
    def showEvent(self, *args, **kwargs):
        self.activate(0)
        return QWidget.showEvent(self, *args, **kwargs)
Ejemplo n.º 2
0
class GeometryWizardPage(_ExpandableOptionsWizardPage):

    def __init__(self, options, parent=None):
        _ExpandableOptionsWizardPage.__init__(self, options, parent)
        self.setTitle('Geometry')

    def _initUI(self):
        # Variables
        self._widgets = {}

        # Widgets
        self._cb_geometry = QComboBox()

        self._wdg_geometry = QStackedWidget()
        policy = self._wdg_geometry.sizePolicy()
        policy.setVerticalStretch(True)
        self._wdg_geometry.setSizePolicy(policy)

        # Layouts
        layout = _ExpandableOptionsWizardPage._initUI(self)
        layout.addRow("Type of geometry", self._cb_geometry)
        layout.addRow(self._wdg_geometry)

        # Signals
        self._cb_geometry.currentIndexChanged.connect(self._onGeometryChanged)
        self._cb_geometry.currentIndexChanged.connect(self.valueChanged)

        return layout

    def _onGeometryChanged(self):
        newindex = self._cb_geometry.currentIndex()
        oldwidget = self._wdg_geometry.currentWidget()
        newwidget = self._wdg_geometry.widget(newindex)
        if newwidget is None:
            return

        try:
            newwidget.setValue(oldwidget.value())
        except:
            newwidget.setValue(self.options().geometry)

        self._wdg_geometry.setCurrentIndex(newindex)

        # See https://qt-project.org/faq/answer/how_can_i_get_a_qstackedwidget_to_automatically_switch_size_depending_on_th
        oldwidget.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        newwidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._wdg_geometry.adjustSize()

    def _find_material_class(self, programs):
        highest_class = Material

        for program in programs:
            converter = program.converter_class
            for clasz in converter.MATERIALS:
                if issubclass(clasz, highest_class):
                    highest_class = clasz

        return highest_class

    def initializePage(self):
        _ExpandableOptionsWizardPage.initializePage(self)

        # Clear
        self._widgets.clear()
        for i in reversed(range(self._cb_geometry.count())):
            self._cb_geometry.removeItem(i)
            self._wdg_geometry.removeWidget(self._wdg_geometry.widget(i))

        # Populate combo box
        it = self._iter_widgets('pymontecarlo.ui.gui.options.geometry',
                                'GEOMETRIES')
        for clasz, widget_class, programs in it:
            widget = widget_class()
            widget.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
            widget.setMaterialClass(self._find_material_class(programs))

            self._widgets[clasz] = widget

            program_text = ', '.join(map(attrgetter('name'), programs))
            text = '{0} ({1})'.format(widget.accessibleName(), program_text)
            self._cb_geometry.addItem(text)
            self._wdg_geometry.addWidget(widget)

            widget.valueChanged.connect(self.valueChanged)

        # Select geometry
        geometry = self.options().geometry

        widget = self._widgets.get(geometry.__class__)
        if widget is None:
            widget = next(iter(self._widgets.values()))

        widget.setValue(geometry)
        self._wdg_geometry.setCurrentWidget(widget)
        self._cb_geometry.setCurrentIndex(self._wdg_geometry.currentIndex())

    def validatePage(self):
        if not self._wdg_geometry.currentWidget().hasAcceptableInput():
            return False

        self.options().geometry = self._wdg_geometry.currentWidget().value()

        return True

    def expandCount(self):
        try:
            return len(expand(self._wdg_geometry.currentWidget().value()))
        except:
            return 0
Ejemplo n.º 3
0
class BeamWizardPage(_ExpandableOptionsWizardPage):
    def __init__(self, options, parent=None):
        _ExpandableOptionsWizardPage.__init__(self, options, parent)
        self.setTitle("Beam")

    def _initUI(self):
        # Variables
        self._widgets = {}

        # Widgets
        self._cb_beam = QComboBox()
        self._wdg_beam = QStackedWidget()

        # Layouts
        layout = _ExpandableOptionsWizardPage._initUI(self)
        layout.addRow("Type of beam", self._cb_beam)
        layout.addRow(self._wdg_beam)

        # Signals
        self._cb_beam.currentIndexChanged.connect(self._onBeamChanged)
        self._cb_beam.currentIndexChanged.connect(self.valueChanged)

        return layout

    def _onBeamChanged(self):
        newindex = self._cb_beam.currentIndex()
        oldwidget = self._wdg_beam.currentWidget()
        newwidget = self._wdg_beam.widget(newindex)
        if newwidget is None:
            return

        try:
            newwidget.setValue(oldwidget.value())
        except:
            newwidget.setValue(self.options().beam)

        self._wdg_beam.setCurrentIndex(newindex)

    def initializePage(self):
        _ExpandableOptionsWizardPage.initializePage(self)

        # Clear
        self._widgets.clear()
        for i in reversed(range(self._cb_beam.count())):
            self._cb_beam.removeItem(i)
            self._wdg_beam.removeWidget(self._wdg_beam.widget(i))

        # Populate combo box
        it = self._iter_widgets("pymontecarlo.ui.gui.options.beam", "BEAMS")
        for clasz, widget_class, programs in it:
            widget = widget_class()
            self._widgets[clasz] = widget

            program_text = ", ".join(map(attrgetter("name"), programs))
            text = "{0} ({1})".format(widget.accessibleName(), program_text)
            self._cb_beam.addItem(text)
            self._wdg_beam.addWidget(widget)

            widget.setParticlesEnabled(False)
            for program in programs:
                converter = program.converter_class
                for particle in converter.PARTICLES:
                    widget.setParticleEnabled(particle, True)

            widget.valueChanged.connect(self.valueChanged)

        # Select beam
        beam = self.options().beam

        widget = self._widgets.get(beam.__class__)
        if widget is None:
            widget = next(iter(self._widgets.values()))

        widget.setValue(beam)

        self._wdg_beam.setCurrentWidget(widget)
        self._cb_beam.setCurrentIndex(self._wdg_beam.currentIndex())

    def validatePage(self):
        if not self._wdg_beam.currentWidget().hasAcceptableInput():
            return False

        self.options().beam = self._wdg_beam.currentWidget().value()

        return True

    def expandCount(self):
        try:
            return len(expand(self._wdg_beam.currentWidget().value()))
        except:
            return 0
Ejemplo n.º 4
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """Main interface"""

    # Custom Signals
    dock_destroyed = Signal(str)

    def __init__(self, user_data, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.set_username(user_data[0])
        self._docks = []
        self._stackedWidget = QStackedWidget()
        self.setCentralWidget(self._stackedWidget)
        self._overview = OverviewDock()
        self._stackedWidget.addWidget(self._overview)
        self._edit_mode = False
        self._stackedWidget.currentChanged.connect(self.dock_changed)
        # permission stuff
        self.set_access(user_data[1])

    def dock_changed(self, new_index):
        new_dock = self._stackedWidget.widget(new_index).objectName()
        if "Edit" in new_dock:
            # it's an editing dock
            self.set_editing(True)

    def set_editing(self, state):
        self._edit_mode = state

    def is_editing(self):
        return self._edit_mode

    def set_username(self, username):
        statics.username = username
        message = QLabel(unicode("Usuário: ".decode('utf-8')) + username)
        self.statusbar.addWidget(message)

    def set_access(self, access_level):
        statics.access_level = access_level
        # set availability for QAction objects
        for action in self.findChildren(QAction):
             action.setVisible(check_access(access_level, action.objectName()))
        for menu in self.findChildren(QMenu):
            if menu.isEmpty():
                # no visible actions under this menu
                menu.menuAction().setVisible(False)

    @QtCore.Slot()
    def on_actionExit_activated(self):
        self.close()

    @QtCore.Slot()
    def on_actionAddBook_activated(self):
        self.show_on_top(AddBookDock, self.actionAddBook)

    @QtCore.Slot()
    def on_actionAddAssociate_activated(self):
        self.show_on_top(AddAssociateDock, self.actionAddAssociate)

    @QtCore.Slot()
    def on_actionAddActivity_activated(self):
        self.show_on_top(AddActivityDock, self.actionAddActivity)

    @QtCore.Slot()
    def on_actionPendencies_activated(self):
        self.show_on_top(PendenciesDock, self.actionPendencies)

    @QtCore.Slot()
    def on_actionSellProduct_activated(self):
        self.show_on_top(OrderProductDock, self.actionSellProduct)

    @QtCore.Slot()
    def on_actionSellBook_activated(self):
        self.show_on_top(OrderBookDock, self.actionSellBook)


    def show_on_top(self, widget_type, related_action=None, param=None):
        """ makes the dock related to 'widget_type' the central widget of the mainwindow
            (by stacking it on front of other widgets), grays out respective action while visible """
        if self.is_editing():
            # edit dock is being swapped out
            message = unicode("Todos os dados não salvos serão perdidos".decode('utf-8'))
            reply = QMessageBox.warning(self, unicode("Atenção".decode('utf-8')), message, QMessageBox.Yes, QMessageBox.No)
            if reply == QMessageBox.No:
                return
            else:
                self.remove_instance(self._stackedWidget.currentWidget())
        # there's a need to gray out the corresponding menu option
        if related_action:
            related_action.setDisabled(True)
        widget = self.get_instance(widget_type)
        if widget is None:
            # create a new instance of referenced widget if it doesn't exist yet
            if param:
                # when a parameter is passed
                widget = widget_type(param)
            else:
                widget = widget_type()
            self._docks.append(widget)
            self._stackedWidget.addWidget(widget)
        # else:
        #     widget.clear()

        # connects a connection cleanup method when needed
        # if hasattr(widget, 'cleanup_conn'):
        #     widget.cleanup_conn.connect(self.clean_connection)
        self._stackedWidget.setCurrentWidget(widget)

    def get_instance(self, type):
        for inst in self._docks:
            if isinstance(inst, type):
                return inst
        return None

    def remove_instance(self, inst):
        if self.is_editing():
            self.set_editing(False)
        self._docks.remove(inst)
        self._stackedWidget.removeWidget(inst)
        self._stackedWidget.setCurrentWidget(self._overview)
        self._overview.refresh()

    def closeEvent(self, event):
        message = unicode("Deseja mesmo sair?".decode('utf-8'))
        reply = QMessageBox.question(self, 'Seareiros', message, QMessageBox.Yes, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()