Exemple #1
0
    def init(self):
        # Check if this class has been initialized before, and do so if not
        if not self.init_flag:
            self.first_init()

        # Create a layout for this widget
        box_layout = GL.QHBoxLayout(self)
        box_layout.setContentsMargins(0, 0, 0, 0)

        # Create a combobox for cmaps
        cmaps_box = GW.EditableComboBox()
        validator = GW.ComboBoxValidator(cmaps_box)
        cmaps_box.setValidator(validator)

        # Add all colormaps to cmaps_box
        for cmap in self.cmaps_cl:
            cmap_icon = self.cmap_icons[cmap]
            cmaps_box.addItem(cmap_icon, cmap)

        # Add some separators
        for i in reversed(self.cum_len[:-2]):
            cmaps_box.insertSeparator(i)

        # Set remaining properties
        set_box_value(cmaps_box, rcParams['image.cmap'])
        cmaps_box.setIconSize(QC.QSize(*self.cmap_size))
        cmaps_box.completer().popup().setIconSize(QC.QSize(*self.cmap_size))
        get_modified_signal(cmaps_box, str).connect(self.cmap_selected)
        cmaps_box.focusLost.connect(
            lambda: set_box_value(cmaps_box, get_box_value(cmaps_box, int)))

        # Add cmaps_box to layout
        box_layout.addWidget(cmaps_box)
        self.cmaps_box = cmaps_box
Exemple #2
0
    def init(self):
        # Make layout for setting the value range of the histogram
        hist_range_layout = GL.QHBoxLayout(self)
        hist_range_layout.setContentsMargins(0, 0, 0, 0)

        # Make a box for setting the value range of the histogram
        # TODO: Maybe use dual lineedits instead to eliminate range problem?
        hist_range_box = GW.DualSpinBox((float, float),
                                        r"<html>&le; X &le;</html>")
        x_min_box, x_max_box = hist_range_box[:]
        x_min_box.setRange(-9999999, 9999999)
        x_min_box.setToolTip("Minimum value to be included in the histogram")
        x_max_box.setRange(-9999999, 9999999)
        x_max_box.setToolTip("Maximum value to be included in the histogram")
        set_box_value(hist_range_box, (0, 0))
        hist_range_box.setEnabled(False)
        self.range_box = hist_range_box

        # Make a checkbox for enabling/disabling the use of this range
        hist_range_flag = GW.QCheckBox()
        hist_range_flag.setToolTip("Toggle the use of a manual histogram value"
                                   " range")
        set_box_value(hist_range_flag, False)
        self.range_flag = hist_range_flag

        # Connect signals for hist_range_flag
        get_modified_signal(hist_range_flag).connect(hist_range_box.setEnabled)

        # Add everything together
        hist_range_layout.addWidget(hist_range_flag)
        hist_range_layout.addWidget(hist_range_box)
Exemple #3
0
    def init(self, widget, text, tooltip):
        """
        Sets up the togglebox after it has been initialized.

        """

        # Create the box_layout
        box_layout = GL.QHBoxLayout(self)
        box_layout.setContentsMargins(0, 0, 0, 0)

        # Create a checkbox for toggling the widget
        if text is not None:
            checkbox = GW.QCheckBox(text)
        else:
            checkbox = GW.QCheckBox()
        box_layout.addWidget(checkbox)
        self.checkbox = checkbox
        self.left_box = checkbox

        # Set tooltip
        if tooltip is not None:
            checkbox.setToolTip(tooltip)

        # Add the widget to it
        box_layout.addWidget(widget)
        self.widget = widget
        self.right_box = widget

        # Connect some signals
        get_modified_signal(checkbox).connect(widget.setEnabled)

        # Make sure that the checkbox is unchecked
        set_box_value(checkbox, False)
        widget.setEnabled(False)
Exemple #4
0
    def multi_data_box(self):
        """
        Creates a widget box for setting the data for multiple 'DataND' props
        and returns it.

        """

        # Make a tab widget for holding data tabs
        tab_widget = MultiDataTabWidget()
        self.tab_widget = tab_widget

        # Create add button for tabs
        add_but = GW.QToolButton()
        add_but.setToolTip("Add additional data set")
        tab_widget.setCornerWidget(add_but, QC.Qt.TopRightCorner)

        # If this theme has an 'add' icon, use it
        if QG.QIcon.hasThemeIcon('add'):
            add_but.setIcon(QG.QIcon.fromTheme('add'))
        # Else, use a simple plus
        else:
            add_but.setText('+')

        # Connect tab widget signals
        get_modified_signal(add_but).connect(self.add_data_box)
        tab_widget.tabCloseRequested.connect(self.remove_data_box)

        # Add initial data box
        self.add_data_box()

        # Return box
        return (tab_widget, )
Exemple #5
0
    def add_data_box(self):
        """
        Adds a new data tab to this plot property.

        """

        # Create a default widget for the new DataND prop
        data_prop = GW.BaseBox()
        get_modified_signal(data_prop).connect(self.tab_widget.modified)

        # Create a dictionary with all requirements of this property
        prop_kwargs = {
            req: getattr(self, req)
            for req in self.data_prop.REQUIREMENTS
        }

        # Create the DataND prop
        prop_layout = self.data_prop(**prop_kwargs)

        # Set prop_layout as the layout for data_prop
        data_prop.setLayout(prop_layout)

        # Obtain the name of this data_prop
        name = "data_%i" % (self.tab_widget.count())

        # Add data_prop to the tab widget
        index = self.tab_widget.addTab(data_prop, name)

        # Switch focus to the new tab
        set_box_value(self.tab_widget, index)

        # Check if there is now more than a single tab
        self.tab_widget.setTabsClosable(self.tab_widget.count() > 1)
Exemple #6
0
    def add_entry(self):
        """
        Adds a new entry to the entries box.

        """

        # Create a combobox with the name of the entry
        name_box = self.get_entry_name_box()
        name_box.setToolTip("Select or type name for this entry")
        name_box.addItems(self.entry_types.keys())
        set_box_value(name_box, -1)
        get_modified_signal(name_box).connect(
            lambda: self.create_value_box(name_box))

        # Create a 'Delete'-button
        del_but = GW.QToolButton()
        del_but.setFixedSize(self.entry_height, self.entry_height)
        del_but.setToolTip("Delete this entry")
        get_modified_signal(del_but).connect(
            lambda: self.remove_entry(name_box))

        # If this theme has a 'remove' icon, use it
        if QG.QIcon.hasThemeIcon('remove'):
            del_but.setIcon(QG.QIcon.fromTheme('remove'))
        # Else, use a standard icon
        else:
            del_but.setIcon(del_but.style().standardIcon(
                QW.QStyle.SP_DialogCloseButton))

        # Add a new row to the grid layout
        next_row = self.entries_grid.getItemPosition(
            self.entries_grid.count() - 1)[0] + 1
        self.entries_grid.addWidget(del_but, next_row, 0)
        self.entries_grid.addWidget(name_box, next_row, 1)
        self.entries_grid.addWidget(GW.QLabel(), next_row, 2)
Exemple #7
0
    def init(self, *args, **kwargs):
        # Call super setup
        super().init(*args, **kwargs)

        # Extract the two created comboboxes
        tables_box, columns_box = self[:]
        self.tables_box = tables_box
        self.columns_box = columns_box

        # Add items to data tables combobox
        for i, name in enumerate(self.tab_widget.tabNames()):
            tables_box.addItem(name)
            self.set_tables_box_item_tooltip(i, name)

        # Connect signals for tables_box
        self.tab_widget.tabTextChanged.connect(tables_box.setItemText)
        self.tab_widget.tabTextChanged.connect(
            self.set_tables_box_item_tooltip)
        self.tab_widget.tabWasInserted[int, str].connect(tables_box.insertItem)
        self.tab_widget.tabWasInserted[int, str].connect(
            self.set_tables_box_item_tooltip)
        self.tab_widget.tabWasRemoved.connect(tables_box.removeItem)
        get_modified_signal(tables_box,
                            int).connect(self.set_columns_box_table)

        # Set initial contents of columns_box
        self.data_table = None
        self.model = None
        self.set_box_value((None, None))
Exemple #8
0
    def init(self):
        """
        Sets up the entries box after it has been initialized.

        """

        # Set the height of a single entry
        self.entry_height = 24

        # Create empty dict of non-generic entry types
        self.entry_types = {}

        # Create empty dict of entry defaults
        self.entry_defaults = {}

        # Create empty set of banned entry names
        self.banned_names = sset()

        # Create the box_layout
        box_layout = GL.QVBoxLayout(self)
        box_layout.setContentsMargins(0, 0, 0, 0)

        # Create the entries_grid
        entries_grid = GL.QGridLayout()
        entries_grid.setContentsMargins(0, 0, 0, 0)
        entries_grid.setColumnStretch(1, 1)
        entries_grid.setColumnStretch(2, 2)
        box_layout.addLayout(entries_grid)
        self.entries_grid = entries_grid

        # Add a header
        entries_grid.addWidget(GW.QLabel(""), 0, 0)
        entries_grid.addWidget(GW.QLabel("Entry name"), 0, 1)
        entries_grid.addWidget(GW.QLabel("Entry value"), 0, 2)

        # Add an 'Add'-button
        add_but = GW.QToolButton()
        add_but.setFixedSize(self.entry_height, self.entry_height)
        add_but.setToolTip("Add new entry")
        get_modified_signal(add_but).connect(self.add_entry)
        box_layout.addWidget(add_but)

        # If this theme has an 'add' icon, use it
        if QG.QIcon.hasThemeIcon('add'):
            add_but.setIcon(QG.QIcon.fromTheme('add'))
        # Else, use a simple plus
        else:
            add_but.setText('+')

        # Set size policy
        self.setSizePolicy(QW.QSizePolicy.Preferred, QW.QSizePolicy.Fixed)

        # Set a minimum width for the first column
        self.entries_grid.setColumnMinimumWidth(0, self.entry_height)
Exemple #9
0
    def add_options_entry(self, widget):
        """
        Adds the provided `widget` as an options entry to this options dialog.
        This allows for the values of `widget` to be tracked and potentially
        discarded/reverted.

        """

        # Add widget as an entry to options_dict
        self.options_dict[widget] = get_box_value(widget)
        get_modified_signal(widget).connect(self.enable_apply_button)
Exemple #10
0
    def add_config_entry(self, name, widget, restart_flag=False):
        """
        Adds the provided `widget` as a config entry to this config page with
        given `name`.
        This allows for the values of `widget` to be tracked and potentially
        discarded/reverted.

        """

        # Make sure that name is lowercase
        name = name

        # Add widget as an entry to config_entries
        self.config_entries[name] = widget
        get_modified_signal(widget).connect(self.modified)

        # If restart_flag is True, connect set_restart_flag as well
        if restart_flag:
            get_modified_signal(widget).connect(self.set_restart_flag)
Exemple #11
0
    def init(self):
        # Install event filter to catch events that should close the popup
        self.installEventFilter(self)

        # Set dialog flags
        self.setWindowFlags(QC.Qt.Popup | QC.Qt.FramelessWindowHint)

        # Create a form layout
        layout = GL.QFormLayout(self)

        # Add a label stating the base name of the column
        self.base_name_label = GW.QLabel("")
        self.base_name_label.setAlignment(QC.Qt.AlignCenter)
        layout.addRow(self.base_name_label)

        # Create a n_val label
        n_val_box = GW.QLabel()
        n_val_box.setToolTip("Number of values in this column")

        # Add it to the layout
        layout.addRow("# of values", n_val_box)
        self.n_val_box = n_val_box

        # Create a name line-edit
        name_box = GW.QLineEdit()
        name_box.setToolTip("Set a custom name for this column or leave empty "
                            "to use its default name")
        get_modified_signal(name_box).connect(self.column_name_changed)

        # Add it to the layout
        layout.addRow("Name", name_box)
        self.name_box = name_box

        # Create a dtype combobox
        dtype_box = GW.QComboBox()
        dtype_box.setToolTip("Set the data type for this column")
        dtype_box.addItems(self.model.dtypes.values())
        dtype_box.popup_hidden.connect(lambda: name_box.setFocus(True))

        # Add it to the layout
        layout.addRow("Data type", dtype_box)
        self.dtype_box = dtype_box
Exemple #12
0
    def init(self, item_type):
        """
        Sets up the items box after it has been initialized.

        """

        # Obtain the item_box
        if item_type is None:
            self.item_box = GW.LongGenericBox
        else:
            self.item_box = GW.type_box_dict.get(item_type, item_type)

        # Set the height of a single item
        self.entry_height = 24

        # Create the box_layout
        box_layout = GL.QVBoxLayout(self)
        box_layout.setContentsMargins(0, 0, 0, 0)

        # Create the items_layout
        items_layout = GL.QVBoxLayout()
        items_layout.setContentsMargins(0, 0, 0, 0)
        box_layout.addLayout(items_layout)
        self.items_layout = items_layout

        # Add an 'Add'-button
        add_but = GW.QToolButton()
        add_but.setFixedSize(self.entry_height, self.entry_height)
        add_but.setToolTip("Add new item")
        get_modified_signal(add_but).connect(self.add_item)
        box_layout.addWidget(add_but)

        # If this theme has an 'add' icon, use it
        if QG.QIcon.hasThemeIcon('add'):
            add_but.setIcon(QG.QIcon.fromTheme('add'))
        # Else, use a simple plus
        else:
            add_but.setText('+')

        # Set size policy
        self.setSizePolicy(QW.QSizePolicy.Preferred, QW.QSizePolicy.Fixed)
Exemple #13
0
    def create_plots_tab(self):
        # Create a tab
        tab = GW.BaseBox()
        get_modified_signal(tab).connect(self.enable_apply_button)

        # Create layout
        layout = GL.QFormLayout(tab)

        # PLOT
        # Create a plot picker layout
        plot_layout = GL.QHBoxLayout()
        layout.addRow(plot_layout)

        # Create a label
        plot_label = GW.QLabel("Plot")
        plot_label.setSizePolicy(QW.QSizePolicy.Fixed, QW.QSizePolicy.Fixed)
        plot_layout.addWidget(plot_label)

        # Create a combobox for choosing an existing plot
        plot_entries = GW.QComboBox()
        plot_entries.setToolTip("Select the plot entry you wish to edit")
        plot_layout.addWidget(plot_entries)
        get_modified_signal(plot_entries).disconnect(tab.modified)
        self.plot_entries = plot_entries

        # Add a toolbutton for adding a new plot entry
        add_but = GW.QToolButton()
        add_but.setToolTip("Add new plot entry")
        get_modified_signal(add_but).connect(self.add_entry)
        plot_layout.addWidget(add_but)

        # If this theme has an 'add' icon, use it
        if QG.QIcon.hasThemeIcon('add'):
            add_but.setIcon(QG.QIcon.fromTheme('add'))
        # Else, use a simple plus
        else:
            add_but.setText('+')

        # Add a separator
        layout.addSeparator()

        # Add a stacked widget here for dividing the plots
        plot_pages = GW.QStackedWidget()
        get_modified_signal(plot_entries,
                            int).connect(plot_pages.setCurrentIndex)
        layout.addRow(plot_pages)
        self.plot_pages = plot_pages

        # Return tab
        return (tab, "Plots")
Exemple #14
0
    def add_entry(self):
        # Obtain index of this plot entry
        index = self.plot_entries.count()

        # Obtain name
        name = "%i_plot" % (index)

        # Create plot entry box
        plot_entry = FigurePlotEntry(index, name, self.figure_widget)

        # Connect signals
        plot_entry.entryNameChanged.connect(
            lambda x: self.plot_entries.setItemText(index, x))
        plot_entry.entryRemoveRequested.connect(self.remove_entry)

        # Add it to the plot_entries and plot_pages
        self.plot_entries.addItem(name)
        self.plot_pages.addWidget(plot_entry)
        get_modified_signal(plot_entry).connect(self.enable_apply_button)

        # Set the shown entry to the new entry
        set_box_value(self.plot_entries, index)
Exemple #15
0
    def create_entry_layout(self):
        # Create layout
        layout = GL.QFormLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        self.layout = layout

        # Create a name editor layout
        name_layout = GL.QHBoxLayout()
        layout.addRow('Name', name_layout)

        # Create entry name editor
        name_box = GW.QLineEdit()
        name_box.setToolTip("Name of this plot entry")
        set_box_value(name_box, self.name)
        get_modified_signal(name_box).connect(self.entryNameChanged)
        name_layout.addWidget(name_box)
        get_modified_signal(name_box).disconnect(self.modified)
        self.name_box = name_box

        # Add a toolbutton for deleting this plot entry
        del_but = GW.QToolButton()
        del_but.setToolTip("Delete this plot entry")
        get_modified_signal(del_but).connect(self.entryRemoveRequested)
        name_layout.addWidget(del_but)

        # If this theme has a 'remove' icon, use it
        if QG.QIcon.hasThemeIcon('remove'):
            del_but.setIcon(QG.QIcon.fromTheme('remove'))
        # Else, use a standard icon
        else:
            del_but.setIcon(del_but.style().standardIcon(
                QW.QStyle.SP_DialogCloseButton))

        # Create a combobox for choosing a plot type
        plot_types = GW.QComboBox()
        plot_types.addItems(PLOT_TYPES['2D'])
        plot_types.setToolTip("Select the plot type you wish to use for this "
                              "plot entry")
        set_box_value(plot_types, -1)
        get_modified_signal(plot_types).connect(self.set_plot_type)
        layout.addRow('Type', plot_types)
        self.plot_types = plot_types

        # Add a separator
        layout.addSeparator()

        # Create a dummy entry to start off
        self.plot_entry = GW.QWidget()
        layout.addRow(self.plot_entry)
Exemple #16
0
    def add_item(self):
        """
        Adds a new item to the items box.

        """

        # Create an item layout
        item_layout = GL.QHBoxLayout()
        item_layout.setContentsMargins(0, 0, 0, 0)

        # Create a generic box for this item
        item_box = self.item_box()
        item_box.setToolTip("Set value of this item")
        get_modified_signal(item_box).connect(self.modified)

        # Create a 'Delete'-button
        del_but = GW.QToolButton()
        del_but.setFixedSize(self.entry_height, self.entry_height)
        del_but.setToolTip("Delete this item")
        get_modified_signal(del_but).connect(
            lambda: self.remove_item(item_layout))

        # If this theme has a 'remove' icon, use it
        if QG.QIcon.hasThemeIcon('remove'):
            del_but.setIcon(QG.QIcon.fromTheme('remove'))
        # Else, use a standard icon
        else:
            del_but.setIcon(del_but.style().standardIcon(
                QW.QStyle.SP_DialogCloseButton))

        # Add a new row to the items layout
        item_layout.addWidget(del_but)
        item_layout.addWidget(item_box)
        self.items_layout.addLayout(item_layout)

        # Emit signal if item_box is not LongGenericBox
        if not isinstance(item_box, GW.LongGenericBox):
            self.modified.emit()
Exemple #17
0
    def init(self):
        """
        Sets up the generic value box after it has been initialized.

        """

        # Create the box_layout
        box_layout = GL.QHBoxLayout(self)
        box_layout.setContentsMargins(0, 0, 0, 0)
        self.box_layout = box_layout

        # Create a combobox for the type
        type_box = GW.QComboBox()
        type_box.addItems(sorted([x.__name__ for x in self.supported_types]))
        type_box.setSizePolicy(QW.QSizePolicy.Fixed, QW.QSizePolicy.Fixed)
        set_box_value(type_box, -1)
        get_modified_signal(type_box).connect(self.create_value_box)
        box_layout.addWidget(type_box)
        self.type_box = type_box

        # Create a default value box
        value_box = GW.QWidget()
        box_layout.addWidget(value_box)
        self.value_box = value_box
Exemple #18
0
    def add_config_page(self, config_page):
        """
        Adds a provided `config_page` to this dialog, allowing it to be
        modified.
        The name of the config page determines where it will appear in the
        dialog.

        Parameters
        ----------
        config_page : :obj:`~guipy.config.BaseConfigPage` object
            The config page object that must be added to this dialog.

        """

        # Add a stretch to the layout of the page
        config_page.layout().addStretch()

        # Create scrollarea for the config page
        scroll_area = GW.QScrollArea(self)
        scroll_area.setWidgetResizable(True)
        scroll_area.setWidget(config_page)

        # Obtain the page sections of this config page
        main, sub, tab = self.get_page_sections(config_page.section_name)

        # Obtain the full page section for this config page
        page_section = self.config_pages.setdefault(
            main, sdict()).setdefault(sub, sdict())

        # Check if this section existed before
        if(len(page_section) == 0):
            # Add the config page as a widget to the page_section and sections
            self.sections.addWidget(scroll_area)
            self.contents.addItem(main)

            # If this is the first section in contents, select it
            if(self.contents.count() == 1):
                self.contents.setCurrentRow(0)

        elif(len(page_section) == 1):
            # If so, a tab widget will be required
            tab_widget = GW.QTabWidget()
            page_section[''] = tab_widget

            # Obtain the index of the current widget at this section
            prev_page = page_section.values()[1]
            index = self.sections.indexOf(prev_page)

            # Remove this widget
            self.sections.removeWidget(prev_page)

            # Add the tab_widget
            self.sections.insertWidget(index, tab_widget)

            # Add the previous widget and the new config page to the tab_widget
            tab_widget.addTab(prev_page, page_section.keys()[1])
            tab_widget.addTab(scroll_area, tab)

        else:
            # Obtain the current tab widget
            tab_widget = page_section['']
            tab_widget.addTab(scroll_area, tab)

        # Connect signals
        get_modified_signal(config_page).connect(self.enable_apply_button)

        # Add this config page to the proper page section
        page_section[tab] = scroll_area
Exemple #19
0
    def init(self, import_func=None):
        # Create a layout
        layout = GL.QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        # Create a dimensions layout
        dimensions_layout = GL.QHBoxLayout()
        layout.addLayout(dimensions_layout)

        # Add a label to this layout
        dimensions_layout.addWidget(GW.QLabel('Dimensions: '))

        # Create dual spinbox for setting n_rows and n_cols
        dimensions_box = GW.DualSpinBox((int, int), "X")
        dimensions_layout.addWidget(dimensions_box)
        n_rows_box, n_cols_box = dimensions_box[:]
        n_rows_box.setRange(0, 9999999)
        n_rows_box.setToolTip("Number of rows in this data table (max. %i)" %
                              (n_rows_box.maximum()))
        n_cols_box.setRange(0, 702)
        n_cols_box.setToolTip(
            "Number of columns in this data table (max. %i)" %
            (n_cols_box.maximum()))
        self.dimensions_box = dimensions_box

        # Create a layout for applying or reverting the dimensions
        buttons_layout = GL.QHBoxLayout()
        buttons_layout.setContentsMargins(0, 0, 0, 0)
        buttons_layout.setSpacing(0)
        dimensions_layout.addLayout(buttons_layout)

        # If this theme has a 'cancel' icon, use it
        if QG.QIcon.hasThemeIcon('cancel'):
            rev_icon = QG.QIcon.fromTheme('cancel')
        # Else, use a standard icon
        else:
            rev_icon = self.style().standardIcon(
                QW.QStyle.SP_DialogCancelButton)

        # Create a revert toolbutton
        rev_but = GW.QToolButton()
        rev_but.setToolTip("Revert to current data table dimensions")
        rev_but.setIcon(rev_icon)
        get_modified_signal(rev_but).connect(self.revert_table_dimensions)
        buttons_layout.addWidget(rev_but)

        # If this theme has an 'apply' icon, use it
        if QG.QIcon.hasThemeIcon('apply'):
            app_icon = QG.QIcon.fromTheme('apply')
        # Else, use a standard icon
        else:
            app_icon = self.style().standardIcon(
                QW.QStyle.SP_DialogApplyButton)

        # Create an apply toolbutton
        app_but = GW.QToolButton()
        app_but.setToolTip("Apply new data table dimensions")
        app_but.setIcon(app_icon)
        get_modified_signal(app_but).connect(self.apply_table_dimensions)
        buttons_layout.addWidget(app_but)

        # Add a stretcher
        dimensions_layout.addStretch()

        # Create the DataTableView object
        self.view = DataTableView(self, import_func)

        # Set initial values of the spinboxes
        self.revert_table_dimensions()

        # Connect signals from data table view
        self.view.model().rowCountChanged.connect(
            lambda x: set_box_value(n_rows_box, x))
        self.view.model().columnCountChanged.connect(
            lambda x: set_box_value(n_cols_box, x))
        self.view.model().lastColumnRemoved.connect(
            lambda: n_rows_box.setEnabled(False))
        self.view.model().firstColumnInserted.connect(
            lambda: n_rows_box.setEnabled(True))

        # Add data_table to the layout
        layout.addWidget(self.view)
Exemple #20
0
    def create_figure_tab(self):
        # Create a tab
        tab = GW.BaseBox()
        get_modified_signal(tab).connect(self.enable_apply_button)

        # Create layout
        layout = GL.QFormLayout(tab)

        # Make line edit for title
        title_box = GW.FigureLabelBox()
        title_box[0].setToolTip("Figure title")
        title_box[1].setToolTip("Title size")
        set_box_value(title_box, ('', {
            'fontsize': rcParams['figure.titlesize']
        }))
        self.add_options_entry(title_box)
        self.refreshing_figure.connect(
            lambda: self.axis.set_title(*get_box_value(title_box, str, dict)))
        layout.addRow("Title", title_box)
        self.title_box = title_box

        # X-AXIS
        # Create a group box for the X-axis
        x_axis_group = GW.QGroupBox("X-axis")
        layout.addRow(x_axis_group)
        x_axis_layout = GL.QFormLayout(x_axis_group)

        # Make a box for setting the label on the x-axis
        x_label_box = GW.FigureLabelBox()
        x_label_box[0].setToolTip("Label of the X-axis")
        x_label_box[1].setToolTip("Label size")
        set_box_value(x_label_box, ('', {
            'fontsize': rcParams['axes.labelsize']
        }))
        self.add_options_entry(x_label_box)
        self.refreshing_figure.connect(lambda: self.axis.set_xlabel(
            *get_box_value(x_label_box, str, dict)))
        x_axis_layout.addRow("Label", x_label_box)
        self.x_label_box = x_label_box

        # Make a box for setting the range on the x-axis
        # TODO: Allow for a small formula or cell range to be given instead?
        x_range_box = GW.DualLineEdit((float, float),
                                      r"<html>&le; X &le;</html>")
        x_min_box, x_max_box = x_range_box[:]
        x_min_box.setToolTip("Minimum value of the X-axis")
        x_max_box.setToolTip("Maximum value of the X-axis")
        set_box_value(x_range_box, self.axis.get_xlim())

        # Connect signals for x_range_box
        self.refreshing_figure.connect(
            lambda: self.axis.set_xlim(*get_box_value(x_range_box), auto=None))
        self.axis.callbacks.connect(
            'xlim_changed', lambda x: set_box_value(x_range_box, x.get_xlim()))

        # Make togglebox for enabling/disabling the use of this range
        x_range_togglebox = GW.ToggleBox(
            x_range_box, tooltip="Check to manually set the X-axis range")
        self.add_options_entry(x_range_togglebox)
        x_axis_layout.addRow("Range", x_range_togglebox)

        # Connect signals for x_range_togglebox
        self.refreshing_figure.connect(lambda: self.axis.set_autoscalex_on(
            not get_box_value(x_range_togglebox, bool)))

        # Make a box for setting the scale on the x-axis
        x_scale_box = GW.QComboBox()
        x_scale_box.addItems(['linear', 'log', 'symlog', 'logit'])
        x_scale_box.setToolTip("Value scale of the X-axis")
        self.add_options_entry(x_scale_box)
        self.refreshing_figure.connect(
            lambda: self.axis.set_xscale(get_box_value(x_scale_box)))
        x_axis_layout.addRow("Scale", x_scale_box)

        # Y-AXIS
        # Create a group box for the Y-axis
        y_axis_group = GW.QGroupBox("Y-axis")
        layout.addRow(y_axis_group)
        y_axis_layout = GL.QFormLayout(y_axis_group)

        # Make a box for setting the label on the y-axis
        y_label_box = GW.FigureLabelBox()
        y_label_box[0].setToolTip("Label of the Y-axis")
        y_label_box[1].setToolTip("Label size")
        set_box_value(y_label_box, ('', {
            'fontsize': rcParams['axes.labelsize']
        }))
        self.add_options_entry(y_label_box)
        self.refreshing_figure.connect(lambda: self.axis.set_ylabel(
            *get_box_value(y_label_box, str, dict)))
        y_axis_layout.addRow("Label", y_label_box)
        self.y_label_box = y_label_box

        # Make a box for setting the range on the y-axis
        y_range_box = GW.DualLineEdit((float, float),
                                      r"<html>&le; Y &le;</html>")
        y_min_box, y_max_box = y_range_box[:]
        y_min_box.setToolTip("Minimum value of the Y-axis")
        y_max_box.setToolTip("Maximum value of the Y-axis")
        set_box_value(y_range_box, self.axis.get_ylim())

        # Connect signals for y_range_box
        self.refreshing_figure.connect(
            lambda: self.axis.set_ylim(*get_box_value(y_range_box), auto=None))
        self.axis.callbacks.connect(
            'ylim_changed', lambda y: set_box_value(y_range_box, y.get_ylim()))

        # Make togglebox for enabling/disabling the use of this range
        y_range_togglebox = GW.ToggleBox(
            y_range_box, tooltip="Check to manually set the Y-axis range")
        self.add_options_entry(y_range_togglebox)
        y_axis_layout.addRow("Range", y_range_togglebox)

        # Connect signals for y_range_togglebox
        self.refreshing_figure.connect(lambda: self.axis.set_autoscaley_on(
            not get_box_value(y_range_togglebox, bool)))

        # Make a box for setting the scale on the y-axis
        y_scale_box = GW.QComboBox()
        y_scale_box.addItems(['linear', 'log', 'symlog', 'logit'])
        y_scale_box.setToolTip("Value scale of the Y-axis")
        self.add_options_entry(y_scale_box)
        self.refreshing_figure.connect(
            lambda: self.axis.set_yscale(get_box_value(y_scale_box)))
        y_axis_layout.addRow("Scale", y_scale_box)

        # PROPS
        # Create a group box for figure properties
        props_group = GW.QGroupBox("Properties")
        layout.addRow(props_group)
        props_layout = GL.QFormLayout(props_group)

        # Make a combobox for choosing the location of the legend
        legend_loc_box = GW.QComboBox()
        legend_loc_box.addItems(mpl.legend.Legend.codes.keys())
        legend_loc_box.setToolTip("Location of the figure legend")
        set_box_value(legend_loc_box, rcParams['legend.loc'])

        # Make a togglebox for using a legend
        legend_togglebox = GW.ToggleBox(
            legend_loc_box,
            "Legend",
            tooltip="Toggle the use of a figure legend")
        self.add_options_entry(legend_togglebox)
        props_layout.addRow(legend_togglebox)
        self.legend_togglebox = legend_togglebox

        # Return tab
        return (tab, "Figure")
Exemple #21
0
    def create_value_box(self, name_box):
        """
        Creates a value box for the provided `name_box` and its corresponding
        current value, and replaces the current value box with it.

        If the current value of the given `name_box` does not have a specific
        value box defined, a :class:`~guipy.widgets.LongGenericBox` is used
        instead.

        """

        # Determine the current value of the name_box
        entry_name = get_box_value(name_box)

        # Determine at what index the provided name_box currently is in grid
        index = self.entries_grid.indexOf(name_box)

        # Check if the name_box is valid
        valid = self.is_valid(name_box)

        # Retrieve which value_box is currently there
        cur_box = self.entries_grid.itemAt(index + 1).widget()

        # Obtain the widget class associated with this entry_name
        if valid:
            # If the given name is valid, obtain it from dict or use default
            new_box_class = self.entry_types.get(entry_name, GW.LongGenericBox)
        else:
            # If invalid, use a label
            new_box_class = GW.QLabel

        # Check if a modified signal must be emitted later
        emit_signal = False
        if valid or type(cur_box) is not GW.QLabel:
            emit_signal = True

        # If the current value box is not this box type already, replace it
        if type(cur_box) is not new_box_class:
            # If not, create new value box
            new_box = new_box_class()
            new_box.setSizePolicy(QW.QSizePolicy.MinimumExpanding,
                                  QW.QSizePolicy.Fixed)

            # Connect to modified signal
            if valid:
                get_modified_signal(new_box).connect(self.modified)

            # Replace cur_box with new_box
            item = self.entries_grid.replaceWidget(cur_box, new_box)
            cur_box = new_box

            # Close the widget in this item and delete it
            item.widget().close()
            del item

        # If the box is invalid, set its value
        if not valid:
            # If it has a name, set a warning as the value
            if entry_name:
                set_box_value(
                    cur_box, f"Entry <b>{entry_name}</b> is either "
                    "invalid or already in use!")
            # Else, set an empty string as the value
            else:
                set_box_value(cur_box, "")

        # If this entry is valid, perform a few extra tasks
        if valid:
            # Modify tooltip
            cur_box.setToolTip(f"Set value for entry <b>{entry_name}</b>")

            # If this entry has a default value, use it
            if entry_name in self.entry_defaults:
                set_box_value(cur_box, self.entry_defaults[entry_name])

        # Emit modified signal if required
        if emit_signal:
            self.modified.emit()