Пример #1
0
    def __init__(self, parent=None, show_fullpath=True, fullpath_sorting=True,
                 show_all_files=True, show_comments=True):
        QWidget.__init__(self, parent)

        self.treewidget = OutlineExplorerTreeWidget(self,
                                            show_fullpath=show_fullpath,
                                            fullpath_sorting=fullpath_sorting,
                                            show_all_files=show_all_files,
                                            show_comments=show_comments)

        self.visibility_action = create_action(self,
                                           _("Show/hide outline explorer"),
                                           icon='outline_explorer_vis.png',
                                           toggled=self.toggle_visibility)
        self.visibility_action.setChecked(True)
        
        btn_layout = QHBoxLayout()
        btn_layout.setAlignment(Qt.AlignLeft)
        for btn in self.setup_buttons():
            btn_layout.addWidget(btn)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addLayout(btn_layout)
        layout.addWidget(self.treewidget)
        self.setLayout(layout)
Пример #2
0
class JumpList(QWidget):
    """List of buttons to jump to reactions on map"""

    def __init__(self, parent):
        QWidget.__init__(self)
        self.parent = parent
        self.layout = QHBoxLayout()
        self.layout.setAlignment(Qt.AlignLeft)

    def clear(self):
        for i in reversed(range(self.layout.count())):
            self.layout.itemAt(i).widget().setParent(None)

    def add(self, name: str):
        if self.layout.count() == 0:
            label = QLabel("Jump to reaction on map:")
            self.layout.addWidget(label)

        jb = JumpButton(self, name)
        policy = QSizePolicy()
        policy.ShrinkFlag = True
        jb.setSizePolicy(policy)
        self.layout.addWidget(jb)
        self.setLayout(self.layout)

        jb.jumpToMap.connect(self.parent.emit_jump_to_map)

    @ Slot(str)
    def emit_jump_to_map(self: JumpButton, name: str):
        self.parent.emit_jump_to_map(name)

    jumpToMap = Signal(str)
Пример #3
0
    def __init__(self, parent, name_filters=[],
                 show_all=True, show_hscrollbar=True, options_button=None):
        QWidget.__init__(self, parent)

        self.name_filters = name_filters
        self.show_all = show_all
        self.show_hscrollbar = show_hscrollbar

        self.treewidget = ExplorerTreeWidget(self, self.show_hscrollbar)
        self.treewidget.setup(name_filters=self.name_filters,
                              show_all=self.show_all)
        self.treewidget.setup_view()
        self.treewidget.hide()

        self.emptywidget = ExplorerTreeWidget(self)

        if options_button:
            btn_layout = QHBoxLayout()
            btn_layout.setAlignment(Qt.AlignLeft)
            btn_layout.addStretch()
            btn_layout.addWidget(options_button, Qt.AlignRight)
            layout = create_plugin_layout(btn_layout)
        else:
            layout = QVBoxLayout()
            layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.emptywidget)
        layout.addWidget(self.treewidget)
        self.setLayout(layout)
Пример #4
0
    def __init__(self, parent=None, show_fullpath=True, fullpath_sorting=True,
                 show_all_files=True, show_comments=True):
        QWidget.__init__(self, parent)

        self.treewidget = OutlineExplorerTreeWidget(self,
                                            show_fullpath=show_fullpath,
                                            fullpath_sorting=fullpath_sorting,
                                            show_all_files=show_all_files,
                                            show_comments=show_comments)

        self.visibility_action = create_action(self,
                                           _("Show/hide outline explorer"),
                                           icon='outline_explorer_vis.png',
                                           toggled=self.toggle_visibility)
        self.visibility_action.setChecked(True)
        
        btn_layout = QHBoxLayout()
        btn_layout.setAlignment(Qt.AlignLeft)
        for btn in self.setup_buttons():
            btn_layout.addWidget(btn)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addLayout(btn_layout)
        layout.addWidget(self.treewidget)
        self.setLayout(layout)
Пример #5
0
    def add_level_to_table(self, level):
        row_count = self.levelsTable.rowCount()
        self.levelsTable.setRowCount(row_count + 1)

        checkbox_widget = QWidget(self.levelsTable)
        checkbox_widget.setStyleSheet("QWidget { background-color:none;}")

        checkbox = QCheckBox()
        checkbox.setStyleSheet(
            "QCheckBox::indicator { width: 15px; height: 15px;}")
        checkbox.setChecked(level.enabled)
        checkbox.clicked.connect(level.set_enabled)
        checkbox.clicked.connect(self.level_show_changed)
        checkbox.toggled.connect(level.set_enabled)

        checkbox_layout = QHBoxLayout()
        checkbox_layout.setAlignment(Qt.AlignCenter)
        checkbox_layout.setContentsMargins(0, 0, 0, 0)
        checkbox_layout.addWidget(checkbox)
        checkbox_widget.setLayout(checkbox_layout)

        self.levelsTable.setCellWidget(row_count, 0, checkbox_widget)
        self.levelsTable.setItem(row_count, 1,
                                 QTableWidgetItem(level.levelname))
        self.levelsTable.resizeColumnToContents(1)
Пример #6
0
    def _create_propty_layout(self, propty, width=6.0):
        """Return layout that handles a property according to 'propty_type'."""
        layout = QHBoxLayout()
        not_enum = propty.endswith('-SP')
        pv2 = propty.replace('-SP', '-RB').replace('-Sel', '-Sts')

        style = 'min-width:{0}em; max-width:{0}em;\
            min-height:1.29em;'.format(str(width))

        if pv2 != propty:
            chan1 = self.get_pvname(propty)
            if not_enum:
                wid = SiriusSpinbox(self, init_channel=chan1)
                wid.showStepExponent = False
                wid.setAlignment(Qt.AlignCenter)
            else:
                wid = SiriusEnumComboBox(self, init_channel=chan1)
            wid.setStyleSheet(style)
            layout.addWidget(wid)

        label = SiriusLabel(parent=self, init_channel=self.get_pvname(pv2))
        label.setStyleSheet(style)
        label.setAlignment(Qt.AlignCenter)
        label.setObjectName(pv2.replace('-', ''))
        label.showUnits = True
        layout.addWidget(label)

        layout.setAlignment(Qt.AlignVCenter)
        return layout
Пример #7
0
    def __init__(self, parent, name_filters=[],
                 show_all=True, show_hscrollbar=True, options_button=None):
        QWidget.__init__(self, parent)

        self.name_filters = name_filters
        self.show_all = show_all
        self.show_hscrollbar = show_hscrollbar

        self.treewidget = ExplorerTreeWidget(self, self.show_hscrollbar)
        self.treewidget.setup(name_filters=self.name_filters,
                              show_all=self.show_all)
        self.treewidget.setup_view()
        self.treewidget.hide()

        self.emptywidget = ExplorerTreeWidget(self)

        if options_button:
            btn_layout = QHBoxLayout()
            btn_layout.setAlignment(Qt.AlignLeft)
            btn_layout.addStretch()
            btn_layout.addWidget(options_button, Qt.AlignRight)
            layout = create_plugin_layout(btn_layout)
        else:
            layout = QVBoxLayout()
            layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.emptywidget)
        layout.addWidget(self.treewidget)
        self.setLayout(layout)
Пример #8
0
    def __init__(self, parent, name_filters=[], show_hscrollbar=True,
                 options_button=None, single_click_to_open=False):
        # TODO: Remove once Projects is Migrated
        self.CONF_SECTION = parent.CONF_SECTION
        QWidget.__init__(self, parent)

        self.name_filters = name_filters
        self.show_hscrollbar = show_hscrollbar

        self.treewidget = ExplorerTreeWidget(self, self.show_hscrollbar)
        self.treewidget.setup()
        self.treewidget.setup_view()
        self.treewidget.hide()
        self.treewidget.sig_open_file_requested.connect(
            self.sig_open_file_requested)

        self.emptywidget = ExplorerTreeWidget(self)

        if options_button:
            btn_layout = QHBoxLayout()
            btn_layout.setAlignment(Qt.AlignLeft)
            btn_layout.addStretch()
            btn_layout.addWidget(options_button, Qt.AlignRight)
            layout = create_plugin_layout(btn_layout)
        else:
            layout = QVBoxLayout()
            layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.emptywidget)
        layout.addWidget(self.treewidget)
        self.setLayout(layout)
Пример #9
0
    def __init__(self, parent: QWidget, axis: int):
        super().__init__(parent=parent)
        self.axis = axis
        self.qt_dims = parent
        self.dims = parent.dims
        self.axis_label = None
        self.slider = None
        self.play_button = None
        self.curslice_label = QLineEdit(self)
        self.curslice_label.setToolTip(
            trans._('Current slice for axis {axis}', axis=axis))
        # if we set the QIntValidator to actually reflect the range of the data
        # then an invalid (i.e. too large) index doesn't actually trigger the
        # editingFinished event (the user is expected to change the value)...
        # which is confusing to the user, so instead we use an IntValidator
        # that makes sure the user can only enter integers, but we do our own
        # value validation in self.change_slice
        self.curslice_label.setValidator(QIntValidator(0, 999999))

        self.curslice_label.editingFinished.connect(self._set_slice_from_label)
        self.totslice_label = QLabel(self)
        self.totslice_label.setToolTip(
            trans._('Total slices for axis {axis}', axis=axis))
        self.curslice_label.setObjectName('slice_label')
        self.totslice_label.setObjectName('slice_label')
        sep = QFrame(self)
        sep.setFixedSize(1, 14)
        sep.setObjectName('slice_label_sep')

        settings = get_settings()
        self._fps = settings.application.playback_fps
        connect_setattr_value(settings.application.events.playback_fps, self,
                              "fps")

        self._minframe = None
        self._maxframe = None
        self._loop_mode = settings.application.playback_mode
        connect_setattr_value(settings.application.events.playback_mode, self,
                              "loop_mode")

        layout = QHBoxLayout()
        self._create_axis_label_widget()
        self._create_range_slider_widget()
        self._create_play_button_widget()

        layout.addWidget(self.axis_label)
        layout.addWidget(self.play_button)
        layout.addWidget(self.slider, stretch=1)
        layout.addWidget(self.curslice_label)
        layout.addWidget(sep)
        layout.addWidget(self.totslice_label)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(2)
        layout.setAlignment(Qt.AlignVCenter)
        self.setLayout(layout)
        self.dims.events.axis_labels.connect(self._pull_label)
Пример #10
0
    def __init__(self,
                 parent=None,
                 namespace=None,
                 commands=[],
                 message=None,
                 exitfunc=None,
                 profile=False,
                 multithreaded=False):
        SpyderPluginWidget.__init__(self, parent)

        logger.info("Initializing...")
        self.dialog_manager = DialogManager()

        # Shell
        self.shell = InternalShell(parent, namespace, commands, message,
                                   self.get_option('max_line_count'),
                                   self.get_plugin_font(), exitfunc, profile,
                                   multithreaded)
        self.shell.status.connect(lambda msg: self.show_message.emit(msg, 0))
        self.shell.go_to_error.connect(self.go_to_error)
        self.shell.focus_changed.connect(lambda: self.focus_changed.emit())

        # Redirecting some signals:
        self.shell.redirect_stdio.connect(
            lambda state: self.redirect_stdio.emit(state))

        # Initialize plugin
        self.initialize_plugin()

        # Find/replace widget
        self.find_widget = FindReplace(self)
        self.find_widget.set_editor(self.shell)
        self.find_widget.hide()
        self.register_widget_shortcuts(self.find_widget)

        # Main layout
        btn_layout = QHBoxLayout()
        btn_layout.setAlignment(Qt.AlignLeft)
        btn_layout.addStretch()
        btn_layout.addWidget(self.options_button, Qt.AlignRight)
        layout = create_plugin_layout(btn_layout)
        layout.addWidget(self.shell)
        layout.addWidget(self.find_widget)
        self.setLayout(layout)

        # Parameters
        self.shell.toggle_wrap_mode(self.get_option('wrap'))

        # Accepting drops
        self.setAcceptDrops(True)

        # Traceback MessageBox
        self.error_dlg = None
        self.error_traceback = ""
        self.dismiss_error = False
Пример #11
0
    def set_layout(self):
        """Set layout for default widgets."""
        # Icon
        if self.show_icon:
            self._icon = self.get_icon()
            self._pixmap = None
            self._icon_size = QSize(16, 16)  # Should this be adjustable?
            self.label_icon = QLabel()
            self.set_icon()

        # Label
        if self.show_label:
            self.label_value = QLabel()
            self.set_value('')

            # See spyder-ide/spyder#9044.
            self.text_font = QFont(QFont().defaultFamily(),
                                   weight=QFont.Normal)
            self.label_value.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
            self.label_value.setFont(self.text_font)

        # Custom widget
        if self.CUSTOM_WIDGET_CLASS:
            if not issubclass(self.CUSTOM_WIDGET_CLASS, QWidget):
                raise SpyderAPIError(
                    'Any custom status widget must subclass QWidget!')
            self.custom_widget = self.CUSTOM_WIDGET_CLASS(self._parent)

        # Spinner
        if self.show_spinner:
            self.spinner = create_waitspinner(size=14, parent=self)
            self.spinner.hide()

        # Layout setup
        layout = QHBoxLayout(self)
        layout.setSpacing(0)  # Reduce space between icon and label
        if self.show_icon:
            layout.addWidget(self.label_icon)
        if self.show_label:
            layout.addWidget(self.label_value)
        if self.custom_widget:
            layout.addWidget(self.custom_widget)
        if self.show_spinner:
            layout.addWidget(self.spinner)

        if is_dark_interface():
            layout.addSpacing(0)
        else:
            layout.addSpacing(10)

        layout.setContentsMargins(0, 0, 0, 0)
        layout.setAlignment(Qt.AlignVCenter)

        # Setup
        self.update_tooltip()
Пример #12
0
 def _create_prop_widget(self, name, parent, wids, align_ver=True):
     pwid = QWidget(parent)
     vbl = QVBoxLayout(pwid)
     lab = QLabel(name)
     lab.setAlignment(Qt.AlignCenter)
     vbl.addWidget(lab)
     hbl = QHBoxLayout()
     hbl.setAlignment(Qt.AlignCenter)
     vbl.addItem(hbl)
     for wid in wids:
         wid.setParent(pwid)
         hbl.addWidget(wid)
     return pwid
Пример #13
0
    def __init__(self, parent=None, namespace=None, commands=[], message=None,
                 exitfunc=None, profile=False, multithreaded=False):
        SpyderPluginWidget.__init__(self, parent)

        logger.info("Initializing...")
        self.dialog_manager = DialogManager()

        # Shell
        light_background = self.get_option('light_background')
        self.shell = InternalShell(parent, namespace, commands, message,
                                   self.get_option('max_line_count'),
                                   self.get_plugin_font(), exitfunc, profile,
                                   multithreaded,
                                   light_background=light_background)
        self.shell.status.connect(lambda msg: self.show_message.emit(msg, 0))
        self.shell.go_to_error.connect(self.go_to_error)
        self.shell.focus_changed.connect(lambda: self.focus_changed.emit())

        # Redirecting some signals:
        self.shell.redirect_stdio.connect(lambda state:
                                          self.redirect_stdio.emit(state))
        
        # Initialize plugin
        self.initialize_plugin()

        # Find/replace widget
        self.find_widget = FindReplace(self)
        self.find_widget.set_editor(self.shell)
        self.find_widget.hide()
        self.register_widget_shortcuts(self.find_widget)

        # Main layout
        btn_layout = QHBoxLayout()
        btn_layout.setAlignment(Qt.AlignLeft)
        btn_layout.addStretch()
        btn_layout.addWidget(self.options_button, Qt.AlignRight)
        layout = create_plugin_layout(btn_layout)
        layout.addWidget(self.shell)
        layout.addWidget(self.find_widget)
        self.setLayout(layout)
        
        # Parameters
        self.shell.toggle_wrap_mode(self.get_option('wrap'))
            
        # Accepting drops
        self.setAcceptDrops(True)

        # Traceback MessageBox
        self.error_dlg = None
        self.error_traceback = ""
        self.dismiss_error = False
Пример #14
0
class ButtonsWidget(QWidget):
    """Widget with titlebar buttons"""
    def __init__(self, parent):
        super(ButtonsWidget, self).__init__(parent)
        self.setObjectName("buttonsWidget")
        self.setContentsMargins(0, 0, 0, 0)
        sizepolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
        sizepolicy.setHorizontalStretch(0)
        sizepolicy.setVerticalStretch(0)
        sizepolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizepolicy)
        self.setStyleSheet("padding: 0px;")

        self.buttonsLayout = QHBoxLayout(self)
        self.buttonsLayout.setContentsMargins(0, 0, 0, 0)
        self.buttonsLayout.setSpacing(0)
        self.buttonsLayout.setAlignment(Qt.AlignVCenter)
        self.setLayout(self.buttonsLayout)
        if qrainbowstyle.USE_DARWIN_BUTTONS:
            self.btnMinimize = MinimizeDarwinButton(self)
            self.btnMaximize = MaximizeDarwinButton(self)
            self.btnRestore = RestoreDarwinButton(self)
            self.btnClose = CloseDarwinButton(self)
        else:
            self.btnMinimize = MinimizeWindowsButton(self)
            self.btnMaximize = MaximizeWindowsButton(self)
            self.btnRestore = RestoreWindowsButton(self)
            self.btnClose = CloseWindowsButton(self)

        if qrainbowstyle.ALIGN_BUTTONS_LEFT:
            self.buttonsLayout.addWidget(self.btnClose)
            if not qrainbowstyle.USE_DARWIN_BUTTONS:
                self.buttonsLayout.addWidget(self.btnRestore)
            self.buttonsLayout.addWidget(self.btnMinimize)
            self.buttonsLayout.addWidget(self.btnMaximize)
        else:
            self.buttonsLayout.addWidget(self.btnMinimize)
            self.buttonsLayout.addWidget(self.btnMaximize)
            if not qrainbowstyle.USE_DARWIN_BUTTONS:
                self.buttonsLayout.addWidget(self.btnRestore)
            self.buttonsLayout.addWidget(self.btnClose)

        self.btnMinimize.setObjectName("btnMinimize")
        self.btnMaximize.setObjectName("btnMaximize")
        if not qrainbowstyle.USE_DARWIN_BUTTONS:
            self.btnRestore.setObjectName("btnRestore")
        self.btnClose.setObjectName("btnClose")

        if qrainbowstyle.USE_DARWIN_BUTTONS:
            self.buttonsLayout.setSpacing(8)
Пример #15
0
    def _ctrlModeWidget(self):
        self._led_ctrlmode = PyDMLed(
            self, self.dev_pref.substitute(propty='IsRemote-Mon'))
        self._led_ctrlmode.offColor = PyDMLed.Red
        self._led_ctrlmode.onColor = PyDMLed.LightGreen
        self._lb_ctrlmode = PyDMLabel(
            self, self.dev_pref.substitute(propty='Interface-Mon'))

        gbox_ctrlmode = QGroupBox('Control Mode')
        lay_ctrlmode = QHBoxLayout(gbox_ctrlmode)
        lay_ctrlmode.setAlignment(Qt.AlignCenter)
        lay_ctrlmode.addWidget(self._led_ctrlmode)
        lay_ctrlmode.addWidget(self._lb_ctrlmode)
        return gbox_ctrlmode
Пример #16
0
class QtAbout(QDialog):
    def __init__(self):
        super().__init__()

        self.layout = QVBoxLayout()

        # Description
        title_label = QLabel(
            "<b>napari: a multi-dimensional image viewer for python</b>")
        title_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.layout.addWidget(title_label)

        # Add information
        self.infoTextBox = QTextEdit()
        self.infoTextBox.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.infoTextBox.setLineWrapMode(QTextEdit.NoWrap)
        # Add text copy button
        self.infoCopyButton = QtCopyToClipboardButton(self.infoTextBox)
        self.info_layout = QHBoxLayout()
        self.info_layout.addWidget(self.infoTextBox, 1)
        self.info_layout.addWidget(self.infoCopyButton, 0, Qt.AlignTop)
        self.info_layout.setAlignment(Qt.AlignTop)
        self.layout.addLayout(self.info_layout)

        self.infoTextBox.setText(sys_info(as_html=True))
        self.infoTextBox.setMinimumSize(
            self.infoTextBox.document().size().width() + 19,
            self.infoTextBox.document().size().height() + 10,
        )

        self.layout.addWidget(QLabel('<b>citation information:</b>'))
        self.citationTextBox = QTextEdit(citation_text)
        self.citationTextBox.setFixedHeight(64)
        self.citationCopyButton = QtCopyToClipboardButton(self.citationTextBox)
        self.citation_layout = QHBoxLayout()
        self.citation_layout.addWidget(self.citationTextBox, 1)
        self.citation_layout.addWidget(self.citationCopyButton, 0, Qt.AlignTop)
        self.layout.addLayout(self.citation_layout)

        self.setLayout(self.layout)

    @staticmethod
    def showAbout(qt_viewer):
        d = QtAbout()
        d.setObjectName('QtAbout')
        d.setStyleSheet(qt_viewer.styleSheet())
        d.setWindowTitle('About')
        d.setWindowModality(Qt.ApplicationModal)
        d.exec_()
Пример #17
0
    def get_level_show_checkbox(self, level):
        checkbox_widget = QWidget(self.table)
        checkbox_widget.setStyleSheet("QWidget { background-color:none;}")

        checkbox = QCheckBox()
        checkbox.setStyleSheet(
            "QCheckBox::indicator { width: 15px; height: 15px;}")
        checkbox.setChecked(level.enabled)

        checkbox_layout = QHBoxLayout()
        checkbox_layout.setAlignment(Qt.AlignCenter)
        checkbox_layout.setContentsMargins(0, 0, 0, 0)
        checkbox_layout.addWidget(checkbox)
        checkbox_widget.setLayout(checkbox_layout)
        return checkbox_widget
Пример #18
0
    def __init__(self,
                 parent,
                 data,
                 readonly=False,
                 xlabels=None,
                 ylabels=None):
        QWidget.__init__(self, parent)
        self.data = data
        print(type(self.data))
        self.old_data_shape = None

        if len(self.data.shape) == 1:
            self.old_data_shape = self.data.shape
            self.data.shape = (self.data.shape[0], 1)
        elif len(self.data.shape) == 0:
            self.old_data_shape = self.data.shape
            self.data.shape = (1, 1)

        format = SUPPORTED_FORMATS.get(data.dtype.name, '%s')

        self.model = ArrayModel(self.data,
                                format=format,
                                xlabels=xlabels,
                                ylabels=ylabels,
                                readonly=readonly,
                                parent=self)
        self.view = ArrayView(self, self.model, data.dtype, data.shape)

        btn_layout = QHBoxLayout()
        btn_layout.setAlignment(Qt.AlignLeft)
        btn = QPushButton("Format")
        # disable format button for int type
        btn.setEnabled(is_float(data.dtype))
        btn_layout.addWidget(btn)
        btn.clicked.connect(self.change_format)
        btn = QPushButton("Resize")
        btn_layout.addWidget(btn)
        btn.clicked.connect(self.view.resize_to_contents)
        bgcolor = QCheckBox('Background color')
        bgcolor.setChecked(self.model.bgcolor_enabled)
        bgcolor.setEnabled(self.model.bgcolor_enabled)
        bgcolor.stateChanged.connect(self.model.bgcolor)
        btn_layout.addWidget(bgcolor)

        layout = QVBoxLayout()
        layout.addWidget(self.view)
        layout.addLayout(btn_layout)
        self.setLayout(layout)
Пример #19
0
    def __init__(self, appdata: CnaData):
        QWidget.__init__(self)
        self.appdata = appdata
        self.last_selected = None
        self.reaction_counter = 1

        self.add_button = QPushButton("Add new reaction")
        self.add_button.setIcon(QIcon.fromTheme("list-add"))
        policy = QSizePolicy()
        policy.ShrinkFlag = True
        self.add_button.setSizePolicy(policy)

        self.reaction_list = DragableTreeWidget()
        self.reaction_list.setDragEnabled(True)
        self.reaction_list.setHeaderLabels(["Id", "Name", "Flux"])
        self.reaction_list.setSortingEnabled(True)

        for r in self.appdata.project.cobra_py_model.reactions:
            self.add_reaction(r)

        self.reaction_mask = ReactionMask(self)
        self.reaction_mask.hide()

        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        l = QHBoxLayout()
        l.setAlignment(Qt.AlignRight)
        l.addWidget(self.add_button)
        self.splitter = QSplitter()
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.addWidget(self.reaction_list)
        self.splitter.addWidget(self.reaction_mask)
        self.layout.addItem(l)
        self.layout.addWidget(self.splitter)
        self.setLayout(self.layout)

        self.reaction_list.currentItemChanged.connect(self.reaction_selected)
        self.reaction_mask.reactionChanged.connect(
            self.handle_changed_reaction)
        self.reaction_mask.reactionDeleted.connect(
            self.handle_deleted_reaction)
        self.reaction_mask.jumpToMap.connect(self.emit_jump_to_map)
        self.reaction_mask.jumpToMetabolite.connect(
            self.emit_jump_to_metabolite)

        self.add_button.clicked.connect(self.add_new_reaction)
Пример #20
0
    def setup_ui(self):

        secondary_layout = QHBoxLayout()

        # class radio buttons widget
        self.class_selection_layout = QHBoxLayout()  # QGridLayout()

        secondary_layout.addLayout(self.class_selection_layout)
        self.class_selection_layout.setAlignment(Qt.AlignLeft)
        # secondary_layout.setAlignment(self.class_selection_layout, Qt.AlignLeft)

        # edit source code buttons
        self.edit_code_button = QPushButton('edit')
        self.edit_code_button.setProperty('class', 'small_button')
        self.edit_code_button.setMaximumWidth(100)
        self.edit_code_button.clicked.connect(self.edit_code_button_clicked)
        self.override_code_button = QPushButton('override')
        self.override_code_button.setProperty('class', 'small_button')
        self.override_code_button.setMaximumWidth(100)
        self.override_code_button.setEnabled(False)
        self.override_code_button.clicked.connect(
            self.override_code_button_clicked)
        self.reset_code_button = QPushButton('reset')
        self.reset_code_button.setProperty('class', 'small_button')
        self.reset_code_button.setMaximumWidth(206)
        self.reset_code_button.setEnabled(False)
        self.reset_code_button.clicked.connect(self.reset_code_button_clicked)

        edit_buttons_layout = QHBoxLayout()
        # edit_buttons_layout.addWidget(self.highlight_code_button)
        edit_buttons_layout.addWidget(self.edit_code_button)
        edit_buttons_layout.addWidget(self.override_code_button)
        edit_buttons_layout.addWidget(self.reset_code_button)
        # edit_buttons_layout.addWidget(self.highlight_code_button)

        secondary_layout.addLayout(edit_buttons_layout)
        edit_buttons_layout.setAlignment(Qt.AlignRight)

        main_layout = QVBoxLayout()
        main_layout.addLayout(secondary_layout)
        main_layout.addWidget(self.text_edit)
        self.setLayout(main_layout)
Пример #21
0
    def __init__(self,
                 parent,
                 name_filters=[],
                 show_hscrollbar=True,
                 options_button=None,
                 single_click_to_open=False):
        QWidget.__init__(self, parent)

        self.name_filters = name_filters
        self.show_hscrollbar = show_hscrollbar

        self.treewidget = ExplorerTreeWidget(self, self.show_hscrollbar)
        options = {
            'date_column': False,
            'kind_column': True,
            'size_column': False,
            'name_filters': name_filters,
            'show_hidden': False,
            'single_click_to_open': single_click_to_open,
            'file_associations': {},
        }
        self.treewidget.setup(options)
        self.treewidget.setup_view()
        self.treewidget.hide()
        self.treewidget.sig_open_file_requested.connect(
            self.sig_open_file_requested)

        self.emptywidget = ExplorerTreeWidget(self)

        if options_button:
            btn_layout = QHBoxLayout()
            btn_layout.setAlignment(Qt.AlignLeft)
            btn_layout.addStretch()
            btn_layout.addWidget(options_button, Qt.AlignRight)
            layout = create_plugin_layout(btn_layout)
        else:
            layout = QVBoxLayout()
            layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.emptywidget)
        layout.addWidget(self.treewidget)
        self.setLayout(layout)
Пример #22
0
    def _create_groupwidget(self, title, sp_wids, rb_wids, aux_wids=None):
        hbox_sp = QHBoxLayout()
        hbox_sp.setAlignment(Qt.AlignCenter)
        hbox_sp.setContentsMargins(0, 0, 0, 0)
        for wid in sp_wids:
            hbox_sp.addWidget(wid)

        hbox_rb = QHBoxLayout()
        hbox_rb.setAlignment(Qt.AlignCenter)
        hbox_rb.setContentsMargins(0, 0, 0, 0)
        for wid in rb_wids:
            hbox_rb.addWidget(wid)

        box = QGroupBox(title, self) if title else QWidget(self)
        lay = QVBoxLayout(box)
        lay.setAlignment(Qt.AlignCenter)
        if not isinstance(box, QGroupBox):
            lay.setContentsMargins(0, 0, 0, 0)
        lay.addLayout(hbox_sp)
        lay.addLayout(hbox_rb)

        if aux_wids:
            hbox_aux = QHBoxLayout()
            hbox_aux.setAlignment(Qt.AlignCenter)
            hbox_aux.setContentsMargins(0, 0, 0, 0)
            for wid in aux_wids:
                hbox_aux.addWidget(wid)
            lay.addLayout(hbox_aux)
        return box
Пример #23
0
class EntryWidget(QWidget):
    def __init__(self, parent=None):
        super(EntryWidget, self).__init__(parent)
        self.textQVBoxLayout = QVBoxLayout()
        self.allQHBoxLayout = QHBoxLayout()
        self.allQHBoxLayout.setAlignment(Qt.AlignCenter)

        self.titleLabel = QLabel()
        boldFont = QFont()
        boldFont.setBold(True)
        self.titleLabel.setFont(boldFont)
        self.descriptionLabel = QLabel()
        self.textQVBoxLayout.addWidget(self.titleLabel)
        self.textQVBoxLayout.addWidget(self.descriptionLabel)

        self.dateLabel = QLabel()
        self.iconLabel = QLabel()

        self.allQHBoxLayout.addWidget(self.iconLabel, 0)
        self.allQHBoxLayout.addLayout(self.textQVBoxLayout, 1)
        self.allQHBoxLayout.addWidget(self.dateLabel, 0)
        self.setLayout(self.allQHBoxLayout)

    def setTitle(self, text):
        self.titleLabel.setText(text)

    def setDescription(self, text):
        self.descriptionLabel.setText(text)

    def setDate(self, text):
        self.dateLabel.setText(text)

    def setIcon(self, icon, iconsize=32):
        self.iconLabel.setPixmap(icon.pixmap(QSize(iconsize, iconsize)))

    def setStyle(self, style):
        self.dateLabel.setStyleSheet(style)
Пример #24
0
    def __init__(self, parent, data, readonly=False,
                 xlabels=None, ylabels=None):
        QWidget.__init__(self, parent)
        self.data = data
        self.old_data_shape = None
        if len(self.data.shape) == 1:
            self.old_data_shape = self.data.shape
            self.data.shape = (self.data.shape[0], 1)
        elif len(self.data.shape) == 0:
            self.old_data_shape = self.data.shape
            self.data.shape = (1, 1)

        format = SUPPORTED_FORMATS.get(data.dtype.name, '%s')
        self.model = ArrayModel(self.data, format=format, xlabels=xlabels,
                                ylabels=ylabels, readonly=readonly, parent=self)
        self.view = ArrayView(self, self.model, data.dtype, data.shape)
        
        btn_layout = QHBoxLayout()
        btn_layout.setAlignment(Qt.AlignLeft)
        btn = QPushButton(_( "Format"))
        # disable format button for int type
        btn.setEnabled(is_float(data.dtype))
        btn_layout.addWidget(btn)
        btn.clicked.connect(self.change_format)
        btn = QPushButton(_( "Resize"))
        btn_layout.addWidget(btn)
        btn.clicked.connect(self.view.resize_to_contents)
        bgcolor = QCheckBox(_( 'Background color'))
        bgcolor.setChecked(self.model.bgcolor_enabled)
        bgcolor.setEnabled(self.model.bgcolor_enabled)
        bgcolor.stateChanged.connect(self.model.bgcolor)
        btn_layout.addWidget(bgcolor)
        
        layout = QVBoxLayout()
        layout.addWidget(self.view)
        layout.addLayout(btn_layout)        
        self.setLayout(layout)
Пример #25
0
    def __init__(self, appdata):
        QWidget.__init__(self)
        self.appdata = appdata
        self.current = 0
        self.scenario = {}
        self.setFixedHeight(70)
        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.clear_button = QPushButton()
        self.clear_button.setIcon(QIcon.fromTheme("edit-delete"))
        self.clear_button.setToolTip("clear modes")
        self.prev_button = QPushButton("<")
        self.next_button = QPushButton(">")
        self.label = QLabel()

        l1 = QHBoxLayout()
        self.title = QLabel("Mode Navigation")

        l12 = QHBoxLayout()
        l12.setAlignment(Qt.AlignRight)
        l12.addWidget(self.clear_button)
        l1.addWidget(self.title)
        l1.addLayout(l12)

        l2 = QHBoxLayout()
        l2.addWidget(self.prev_button)
        l2.addWidget(self.label)
        l2.addWidget(self.next_button)

        self.layout.addLayout(l1)
        self.layout.addLayout(l2)
        self.setLayout(self.layout)

        self.prev_button.clicked.connect(self.prev)
        self.next_button.clicked.connect(self.next)
        self.clear_button.clicked.connect(self.clear)
Пример #26
0
    def __init__(self):
        super().__init__()

        self.labeledSlider = VLabeledSlider()

        self._qscene = QGraphicsScene()
        self._qscene.setSceneRect(-self._size / 2, -self._size / 2, self._size,
                                  self._size)

        self._qview = BlockDiagramView(scene=self._qscene, parent=self)

        layout = QHBoxLayout()
        layout.addWidget(self.labeledSlider, 0)
        layout.addWidget(self._qview, 1)
        layout.setAlignment(Qt.AlignCenter)
        self.widgetLayout = layout

        groupBox = QGroupBox()
        groupBox.setTitle("Block diagram")
        groupBox.setLayout(layout)

        parentLayout = QVBoxLayout()
        parentLayout.addWidget(groupBox)
        self.setLayout(parentLayout)
Пример #27
0
 def __init__(self, parent, options_button=None):
     QWidget.__init__(self, parent)
     
     self.setWindowTitle("Breakpoints")        
     self.dictwidget = BreakpointTableView(self, 
                            self._load_all_breakpoints())
     if options_button:
         btn_layout = QHBoxLayout()
         btn_layout.setAlignment(Qt.AlignLeft)
         btn_layout.addStretch()
         btn_layout.addWidget(options_button, Qt.AlignRight)
         layout = create_plugin_layout(btn_layout, self.dictwidget)
     else:
         layout = QVBoxLayout()
         layout.addWidget(self.dictwidget)
     self.setLayout(layout)
     self.dictwidget.clear_all_breakpoints.connect(
                                  lambda: self.clear_all_breakpoints.emit())
     self.dictwidget.clear_breakpoint.connect(
                      lambda s1, lino: self.clear_breakpoint.emit(s1, lino))
     self.dictwidget.edit_goto.connect(
                     lambda s1, lino, s2: self.edit_goto.emit(s1, lino, s2))
     self.dictwidget.set_or_edit_conditional_breakpoint.connect(
                     lambda: self.set_or_edit_conditional_breakpoint.emit())
Пример #28
0
    def __init__(self, parent, options_button=None):
        QWidget.__init__(self, parent)

        self.setWindowTitle("Breakpoints")
        self.dictwidget = BreakpointTableView(self,
                                              self._load_all_breakpoints())
        if options_button:
            btn_layout = QHBoxLayout()
            btn_layout.setAlignment(Qt.AlignLeft)
            btn_layout.addStretch()
            btn_layout.addWidget(options_button, Qt.AlignRight)
            layout = create_plugin_layout(btn_layout, self.dictwidget)
        else:
            layout = QVBoxLayout()
            layout.addWidget(self.dictwidget)
        self.setLayout(layout)
        self.dictwidget.clear_all_breakpoints.connect(
            lambda: self.clear_all_breakpoints.emit())
        self.dictwidget.clear_breakpoint.connect(
            lambda s1, lino: self.clear_breakpoint.emit(s1, lino))
        self.dictwidget.edit_goto.connect(
            lambda s1, lino, s2: self.edit_goto.emit(s1, lino, s2))
        self.dictwidget.set_or_edit_conditional_breakpoint.connect(
            lambda: self.set_or_edit_conditional_breakpoint.emit())
Пример #29
0
    def fill_eline_table(self, table_contents):
        self._table_contents = copy.deepcopy(table_contents)

        self._enable_events = False

        self.tbl_elines.clearContents()

        # Clear the list of checkboxes
        for cb in self.cb_sel_list:
            cb.stateChanged.connect(self.cb_eline_state_changed)
        self.cb_sel_list = []

        self.tbl_elines.setRowCount(len(table_contents))
        for nr, row in enumerate(table_contents):
            sel_status = row["sel_status"]
            row_data = [
                None, row["z"], row["eline"], row["energy"], row["peak_int"],
                row["rel_int"], row["cs"]
            ]

            for nc, entry in enumerate(row_data):

                label = self.tbl_labels[nc]

                # Set alternating background colors for the table rows
                #   Make background for editable items a little brighter
                brightness = 240 if label in self.tbl_cols_editable else 220
                if nr % 2:
                    rgb_bckg = (255, brightness, brightness)  # Light-red
                else:
                    rgb_bckg = (brightness, 255, brightness)  # Light-green

                if nc == 0:
                    item = QWidget()
                    cb = CheckBoxNamed(name=f"{nr}")
                    item_hbox = QHBoxLayout(item)
                    item_hbox.addWidget(cb)
                    item_hbox.setAlignment(Qt.AlignCenter)
                    item_hbox.setContentsMargins(0, 0, 0, 0)

                    css1 = get_background_css(rgb_bckg,
                                              widget="QCheckbox",
                                              editable=False)
                    css2 = get_background_css(rgb_bckg,
                                              widget="QWidget",
                                              editable=False)
                    item.setStyleSheet(css2 + css1)

                    cb.setChecked(Qt.Checked if sel_status else Qt.Unchecked)
                    cb.stateChanged.connect(self.cb_eline_state_changed)
                    cb.setStyleSheet("QCheckBox {color: black;}")
                    self.cb_sel_list.append(cb)

                    self.tbl_elines.setCellWidget(nr, nc, item)
                else:

                    s = None
                    # The case when the value (Rel. Int.) is limited from the bottom
                    #   We don't want to print very small numbers here
                    if label in self.tbl_value_min:
                        v = self.tbl_value_min[label]
                        if isinstance(entry,
                                      (float, np.float64)) and (entry < v):
                            s = f"<{v:.2f}"
                    if s is None:
                        if isinstance(entry, (float, np.float64)):
                            s = f"{entry:.2f}" if entry else "-"
                        else:
                            s = f"{entry}" if entry else "-"

                    item = QTableWidgetItem(s)

                    item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)

                    # Set all columns not editable (unless needed)
                    if label not in self.tbl_cols_editable:
                        item.setFlags(item.flags() & ~Qt.ItemIsEditable)

                    brush = QBrush(QColor(*rgb_bckg))
                    item.setBackground(brush)

                    self.tbl_elines.setItem(nr, nc, item)

        self._enable_events = True
        # Update the rest of the widgets
        self._update_widgets_based_on_table_state()
Пример #30
0
class Titlebar(QFrame):
    """Titlebar for frameless windows."""

    minimizeClicked = Signal()
    maximizeClicked = Signal()
    restoreClicked = Signal()
    closeClicked = Signal()

    def __init__(self, parent=None):
        super(Titlebar, self).__init__(parent)
        self.setObjectName("titlebar")
        self.setMouseTracking(True)

        self.menus = []

        self.setAutoFillBackground(True)
        self.setFixedHeight(30)
        self.setContentsMargins(0, 0, 0, 0)
        self.setBackgroundRole(QPalette.Highlight)

        self.layout = QHBoxLayout(self)
        self.layout.setAlignment(Qt.AlignVCenter)
        self.layout.setAlignment(Qt.AlignLeft)
        self.layout.setContentsMargins(8, 0, 0, 0)
        self.layout.setSpacing(0)
        self.setLayout(self.layout)

        self.appLogoLabel = AppLogo(self)
        if qrainbowstyle.APP_ICON_PATH:
            self.appLogoLabel.setPixmap(QPixmap(qrainbowstyle.APP_ICON_PATH))
            self.layout.setContentsMargins(2, 0, 0, 0)
        self.layout.addWidget(self.appLogoLabel)
        if qrainbowstyle.ALIGN_BUTTONS_LEFT:
            self.appLogoLabel.setVisible(False)
            self.layout.setContentsMargins(8, 0, 0, 0)

        self.layout.insertStretch(50)
        self.buttonsWidget = ButtonsWidget(self)
        if qrainbowstyle.ALIGN_BUTTONS_LEFT:
            self.layout.insertWidget(0, self.buttonsWidget)
        else:
            self.layout.addWidget(self.buttonsWidget)

        # auto connect signals
        QMetaObject.connectSlotsByName(self)
        if self.window().parent() is not None:
            self.buttonsWidget.btnRestore.setVisible(False)
            self.buttonsWidget.btnMaximize.setVisible(False)
            self.buttonsWidget.btnMinimize.setVisible(False)

    def setWindowIcon(self, icon: QIcon):
        self.appLogoLabel.setPixmap(icon.pixmap())

    # connecting buttons signals
    @Slot()
    def on_btnClose_clicked(self):
        self.closeClicked.emit()

    @Slot()
    def on_btnRestore_clicked(self):
        self.showRestoreButton(False)
        self.showMaximizeButton(True)
        self.window().showNormal()
        self.restoreClicked.emit()

    @Slot()
    def on_btnMaximize_clicked(self):
        if qrainbowstyle.USE_DARWIN_BUTTONS:
            if self.window().isMaximized():
                self.window().showNormal()
            else:
                self.window().showMaximized()
        else:
            self.showRestoreButton(True)
            self.showMaximizeButton(False)
            self.window().showMaximized()
        self.maximizeClicked.emit()

    @Slot()
    def on_btnMinimize_clicked(self):
        self.window().showMinimized()

    def showLogo(self, value: bool):
        """Show or hide app logo label"""
        self.appLogoLabel.setVisible(value)

    def showRestoreButton(self, value):
        if self.window().parent() is None:
            self.buttonsWidget.btnRestore.setVisible(value)

    def showMaximizeButton(self, value):
        if self.window().parent() is None:
            self.buttonsWidget.btnMaximize.setVisible(value)

    def showMinimizeButton(self, value):
        if self.window().parent() is None:
            self.buttonsWidget.btnMinimize.setVisible(value)

    def addMenu(self, menu: QMenu):
        menuButton = MenuButton(self)
        menuButton.setMenu(menu)
        menuButton.setText(menu.title())
        self.layout.insertWidget(len(self.menus) + 1, menuButton)
        self.menus.append(menuButton)

    def setTitlebarHeight(self, height: int):
        self.setFixedHeight(height)

    def mouseOverTitlebar(self, x, y):
        if self.childAt(QPoint(x, y)):
            return False
        else:
            return QRect(self.appLogoLabel.width(), 0,
                         self.width() - self.appLogoLabel.width(),
                         self.height()).contains(QPoint(x, y))
Пример #31
0
class QtLayerProperties(QFrame):
    def __init__(self, layer):
        super().__init__()

        self.layer = layer
        layer.events.select.connect(lambda v: self.setSelected(True))
        layer.events.deselect.connect(lambda v: self.setSelected(False))
        layer.events.name.connect(self._on_layer_name_change)
        layer.events.blending.connect(self._on_blending_change)
        layer.events.opacity.connect(self._on_opacity_change)
        layer.events.visible.connect(self._on_visible_change)
        layer.events.thumbnail.connect(self._on_thumbnail_change)

        self.setObjectName('layer')

        self.vbox_layout = QVBoxLayout()
        self.top = QFrame()
        self.top_layout = QHBoxLayout()
        self.grid = QFrame()
        self.grid_layout = QGridLayout()
        self.vbox_layout.addWidget(self.top)
        self.vbox_layout.addWidget(self.grid)
        self.vbox_layout.setSpacing(0)
        self.top.setFixedHeight(38)
        self.top_layout.setContentsMargins(0, 0, 0, 0)
        self.grid_layout.setContentsMargins(0, 0, 0, 0)
        self.top_layout.setAlignment(Qt.AlignCenter)
        self.top.setLayout(self.top_layout)
        self.grid.setLayout(self.grid_layout)
        self.setLayout(self.vbox_layout)

        self.name_column = 0
        self.property_column = 1

        cb = QCheckBox(self)
        cb.setObjectName('visibility')
        cb.setToolTip('Layer visibility')
        cb.setChecked(self.layer.visible)
        cb.setProperty('mode', 'visibility')
        cb.stateChanged.connect(lambda state=cb: self.changeVisible(state))
        self.visibleCheckBox = cb
        self.top_layout.addWidget(cb)

        tb = QLabel(self)
        tb.setObjectName('thumbmnail')
        tb.setToolTip('Layer thumbmnail')
        self.thumbnail_label = tb
        self._on_thumbnail_change(None)
        self.top_layout.addWidget(tb)

        textbox = QLineEdit(self)
        textbox.setText(layer.name)
        textbox.home(False)
        textbox.setToolTip('Layer name')
        textbox.setAcceptDrops(False)
        textbox.setEnabled(True)
        textbox.editingFinished.connect(self.changeText)
        self.nameTextBox = textbox
        self.top_layout.addWidget(textbox)

        pb = QPushButton(self)
        pb.setToolTip('Expand properties')
        pb.clicked.connect(self.changeExpanded)
        pb.setObjectName('expand')
        self.expand_button = pb
        self.top_layout.addWidget(pb)

        row = self.grid_layout.rowCount()
        sld = QSlider(Qt.Horizontal, self)
        sld.setFocusPolicy(Qt.NoFocus)
        sld.setMinimum(0)
        sld.setMaximum(100)
        sld.setSingleStep(1)
        sld.setValue(self.layer.opacity * 100)
        sld.valueChanged[int].connect(
            lambda value=sld: self.changeOpacity(value))
        self.opacitySilder = sld
        row = self.grid_layout.rowCount()
        self.grid_layout.addWidget(QLabel('opacity:'), row, self.name_column)
        self.grid_layout.addWidget(sld, row, self.property_column)

        row = self.grid_layout.rowCount()
        blend_comboBox = QComboBox()
        for blend in Blending:
            blend_comboBox.addItem(str(blend))
        index = blend_comboBox.findText(self.layer.blending,
                                        Qt.MatchFixedString)
        blend_comboBox.setCurrentIndex(index)
        blend_comboBox.activated[str].connect(
            lambda text=blend_comboBox: self.changeBlending(text))
        self.blendComboBox = blend_comboBox
        self.grid_layout.addWidget(QLabel('blending:'), row, self.name_column)
        self.grid_layout.addWidget(blend_comboBox, row, self.property_column)

        msg = 'Click to select\nDrag to rearrange\nDouble click to expand'
        self.setToolTip(msg)
        self.setExpanded(False)
        self.setFixedWidth(250)
        self.grid_layout.setColumnMinimumWidth(0, 100)
        self.grid_layout.setColumnMinimumWidth(1, 100)

        self.setSelected(self.layer.selected)

    def setSelected(self, state):
        self.setProperty('selected', state)
        self.nameTextBox.setEnabled(state)
        self.style().unpolish(self)
        self.style().polish(self)

    def changeOpacity(self, value):
        with self.layer.events.blocker(self._on_opacity_change):
            self.layer.opacity = value / 100

    def changeVisible(self, state):
        if state == Qt.Checked:
            self.layer.visible = True
        else:
            self.layer.visible = False

    def changeText(self):
        self.layer.name = self.nameTextBox.text()

    def changeBlending(self, text):
        self.layer.blending = text

    def mouseReleaseEvent(self, event):
        event.ignore()

    def mousePressEvent(self, event):
        event.ignore()

    def mouseMoveEvent(self, event):
        event.ignore()

    def mouseDoubleClickEvent(self, event):
        self.setExpanded(not self.expanded)

    def changeExpanded(self):
        self.setExpanded(not self.expanded)

    def setExpanded(self, bool):
        if bool:
            self.expanded = True
            self.expand_button.setProperty('expanded', True)
            rows = self.grid_layout.rowCount()
            self.setFixedHeight(38 + 30 * rows)
            self.grid.show()
        else:
            self.expanded = False
            self.expand_button.setProperty('expanded', False)
            self.setFixedHeight(60)
            self.grid.hide()
        self.expand_button.style().unpolish(self.expand_button)
        self.expand_button.style().polish(self.expand_button)

    def _on_layer_name_change(self, event):
        with self.layer.events.name.blocker():
            self.nameTextBox.setText(self.layer.name)
            self.nameTextBox.home(False)

    def _on_opacity_change(self, event):
        with self.layer.events.opacity.blocker():
            self.opacitySilder.setValue(self.layer.opacity * 100)

    def _on_blending_change(self, event):
        with self.layer.events.blending.blocker():
            index = self.blendComboBox.findText(self.layer.blending,
                                                Qt.MatchFixedString)
            self.blendComboBox.setCurrentIndex(index)

    def _on_visible_change(self, event):
        with self.layer.events.visible.blocker():
            self.visibleCheckBox.setChecked(self.layer.visible)

    def _on_thumbnail_change(self, event):
        thumbnail = self.layer.thumbnail
        # Note that QImage expects the image width followed by height
        image = QImage(
            thumbnail,
            thumbnail.shape[1],
            thumbnail.shape[0],
            QImage.Format_RGBA8888,
        )
        self.thumbnail_label.setPixmap(QPixmap.fromImage(image))
Пример #32
0
    def _setupUi(self):
        # Layout to enter
        matype_label = QLabel('Choose a magnet: ', self)
        self._matype_cb = QComboBox(self)
        self._matype_items = MASearch.get_pwrsupply_manames()
        self._matype_cb.addItem('Select...')
        self._matype_cb.addItems(self._matype_items)
        self._matype_cb.setEditable(True)
        self._matype_cb.setMaxVisibleItems(10)
        self._matype_cb.currentIndexChanged.connect(
            self._fill_normalizer_layout)
        hlmatype = QHBoxLayout()
        hlmatype.setAlignment(Qt.AlignLeft)
        hlmatype.addWidget(matype_label)
        hlmatype.addWidget(self._matype_cb)

        # Layout to enter normalizer data
        self._lb_current = QLabel('Current [A]: ')
        lb_arrow = QLabel('↔', self, alignment=Qt.AlignCenter)
        lb_arrow.setStyleSheet('min-width:1.2em; max-width:1.2em;')
        self._lb_strength = QLabel('Strength: ')
        self._lb_energy = QLabel('Dipole Energy [GeV]: ')
        self._lb_energy.setVisible(False)
        self._lb_quadfam_kl = QLabel('Family KL [1/m]: ')
        self._lb_quadfam_kl.setVisible(False)

        for name in ['_sb_current', '_sb_strength',
                     '_sb_energy', '_sb_quadfam_kl']:
            setattr(self, name, QDoubleSpinBoxPlus())
            sb = getattr(self, name)
            sb.setObjectName(name)
            sb.setValue(0)
            sb.setMinimum(-100000)
            sb.setMaximum(100000)
            sb.setDecimals(4)
            sb.setStyleSheet("min-width:8em; max-width:8em;")
            sb.editingFinished.connect(self._update_inputs)
            if name in ['_sb_current', '_sb_strength']:
                sb.setEnabled(False)
            else:
                sb.setVisible(False)

        norm_lay = QGridLayout()
        norm_lay.setAlignment(Qt.AlignLeft)
        norm_lay.setHorizontalSpacing(5)
        norm_lay.addItem(
            QSpacerItem(15, 1, QSzPlcy.Fixed, QSzPlcy.Ignored), 1, 0)
        norm_lay.addWidget(self._lb_current, 0, 1)
        norm_lay.addWidget(self._sb_current, 1, 1)
        norm_lay.addWidget(lb_arrow, 0, 2, 2, 1)
        norm_lay.addWidget(self._lb_strength, 0, 3)
        norm_lay.addWidget(self._sb_strength, 1, 3)
        norm_lay.addItem(
            QSpacerItem(15, 1, QSzPlcy.Fixed, QSzPlcy.Ignored), 1, 4)
        norm_lay.addWidget(self._lb_energy, 0, 5)
        norm_lay.addWidget(self._sb_energy, 1, 5)
        norm_lay.addItem(
            QSpacerItem(15, 1, QSzPlcy.Fixed, QSzPlcy.Ignored), 1, 6)
        norm_lay.addWidget(self._lb_quadfam_kl, 0, 7)
        norm_lay.addWidget(self._sb_quadfam_kl, 1, 7)
        self.norm_gb = QGroupBox('', self)
        self.norm_gb.setLayout(norm_lay)

        # General layout
        layout = QVBoxLayout()
        layout.setSpacing(20)
        layout.addWidget(
            QLabel('<h2>Offline Strength/Current Converter</h2>',
                   self, alignment=Qt.AlignCenter))
        layout.addLayout(hlmatype)
        layout.addWidget(self.norm_gb)
        cw = QWidget(self)
        cw.setObjectName('central_widget')
        cw.setStyleSheet("""#central_widget{min-width:42em;}""")
        cw.setLayout(layout)
        self.setCentralWidget(cw)
        self.setFocusPolicy(Qt.StrongFocus)
Пример #33
0
    def __init__(self, parent, data: _Quantity, readonly=False, xlabels=None, ylabels=None, qdata=None):
        QWidget.__init__(self, parent)

        self.parent = parent

        self.qdata = data
        self.data = data

        self.old_data_shape = None

        if len(self.data.m.shape) == 1:
            self.old_data_shape = self.data.m.shape
            self.data.m.shape = (self.data.m.shape[0], 1)

        elif len(self.data.m.shape) == 0:
            self.old_data_shape = self.data.m.shape
            self.data.m.shape = (1, 1)

        format = SUPPORTED_FORMATS.get(data.m.dtype.name, '%s')

        self.model = QuantityArrayModel(self.data,
                                        format=format,
                                        xlabels=xlabels,
                                        ylabels=ylabels,
                                        readonly=readonly,
                                        parent=self)

        self.view = QuantityArrayView(self,
                                      self.model,
                                      data.m.dtype,
                                      data.m.shape)

        btn_layout = QHBoxLayout()
        btn_layout.setAlignment(Qt.AlignLeft)
        btn = QPushButton("Format")

        # disable format button for int type
        btn.setEnabled(is_float(data.m.dtype))
        btn_layout.addWidget(btn)
        btn.clicked.connect(self.change_format)
        btn = QPushButton("Resize")
        btn_layout.addWidget(btn)
        btn.clicked.connect(self.view.resize_to_contents)
        bgcolor = QCheckBox('Background color')
        bgcolor.setChecked(self.model.bgcolor_enabled)
        bgcolor.setEnabled(self.model.bgcolor_enabled)
        bgcolor.stateChanged.connect(self.model.bgcolor)
        btn_layout.addWidget(bgcolor)

        self.unitCombo = QComboBox()
        self.add_units_to_combo()

        i = self.unitCombo.findData(self.data.u)
        self.unitCombo.setCurrentIndex(i)

        self.unitCombo.currentIndexChanged.connect(self.handle_unit_change)

        btn_layout.addWidget(self.unitCombo)

        layout = QVBoxLayout()
        layout.addWidget(self.view)
        layout.addLayout(btn_layout)
        self.setLayout(layout)
Пример #34
0
class MirrorScreen(Display):
    def __init__(self, parent=None, args=None, macros=None):
        super(MirrorScreen, self).__init__(parent=parent, args=args, macros=macros)
        if macros != None:
            self.x_stop = EpicsSignal(macros['XAXIS'] + ".STOP")
            self.y_stop = EpicsSignal(macros['YAXIS'] + ".STOP")
            self.p_stop = EpicsSignal(macros['PITCH'] + ".STOP")

        self.alarm_box_x = QHBoxLayout()
        self.alarm_box_y = QHBoxLayout()
        self.alarm_box_p = QHBoxLayout()
        self.alarm_box_gantry_x = QHBoxLayout()
        self.alarm_box_gantry_y = QHBoxLayout()
        self.ghost = QHBoxLayout()

        self.alarm_x = TyphosAlarmCircle()
        self.alarm_x.channel = "ca://" + macros['XAXIS']
        self.alarm_x.setMaximumHeight(35)
        self.alarm_x.setMaximumWidth(35)

        self.alarm_y = TyphosAlarmCircle()
        self.alarm_y.channel = "ca://" + macros['YAXIS']
        self.alarm_y.setMaximumHeight(35)
        self.alarm_y.setMaximumWidth(35)

        self.alarm_p = TyphosAlarmCircle()
        self.alarm_p.channel = "ca://" + macros['PITCH']
        self.alarm_p.setMaximumHeight(35)
        self.alarm_p.setMaximumWidth(35)

        label_font = QFont()
        label_font.setBold(True) 


        self.x_label = QLabel("x")
        #self.x_label.setFont(label_font)
        self.y_label = QLabel("y")
        #self.y_label.setFont(label_font)
        self.p_label = QLabel("pitch")
        #self.p_label.setFont(label_font)
        self.gantry_x_label = QLabel("gantry x")
        #self.gantry_x_label.setFont(label_font)
        self.gantry_y_label = QLabel("gantry y")
        #self.gantry_y_label.setFont(label_font)

        self.alarm_gantry_x = TyphosAlarmCircle()
        self.alarm_gantry_x.channel = "ca://" + macros['MIRROR'] + ":HOMS:ALREADY_COUPLED_X_RBV"
        self.alarm_gantry_x.setMaximumHeight(35)
        self.alarm_gantry_x.setMaximumWidth(35)

        self.alarm_gantry_y = TyphosAlarmCircle()
        self.alarm_gantry_y.channel = "ca://" + macros['MIRROR'] + ":HOMS:ALREADY_COUPLED_Y_RBV"
        self.alarm_gantry_y.setMaximumHeight(35)
        self.alarm_gantry_y.setMaximumWidth(35)




        
        self.alarm_box_x.addWidget(self.x_label)
        self.alarm_box_x.setAlignment(self.x_label, Qt.AlignCenter)
        self.alarm_box_x.addWidget(self.alarm_x)

        self.alarm_box_y.addWidget(self.y_label)
        self.alarm_box_y.setAlignment(self.y_label, Qt.AlignCenter)
        self.alarm_box_y.addWidget(self.alarm_y)

        self.alarm_box_p.addWidget(self.p_label)
        self.alarm_box_p.setAlignment(self.p_label, Qt.AlignCenter)
        self.alarm_box_p.addWidget(self.alarm_p)

        self.alarm_box_gantry_x.addWidget(self.gantry_x_label)
        self.alarm_box_gantry_x.setAlignment(self.gantry_x_label, Qt.AlignCenter)
        self.alarm_box_gantry_x.addWidget(self.alarm_gantry_x)

        self.alarm_box_gantry_y.addWidget(self.gantry_y_label)
        self.alarm_box_gantry_y.setAlignment(self.gantry_y_label, Qt.AlignCenter)
        self.alarm_box_gantry_y.addWidget(self.alarm_gantry_y)


        self.stop_button = PyDMPushButton(label="Stop")
        self.stop_button.setMaximumHeight(120)
        self.stop_button.setMaximumWidth(120)
        self.stop_button.clicked.connect(self.stop_motors)
        self.stop_button.setStyleSheet("background: rgb(255,0,0)")

        self.advanced_button = TyphosRelatedSuiteButton()
        
        self.advanced_button.happi_names = [macros['MIRROR'].lower() + "_homs"]
        self.advanced_button.setText("Advanced")

        
        self.ui.horizontalLayout_8.addLayout(self.alarm_box_x)
        self.ui.horizontalLayout_8.addLayout(self.alarm_box_y)
        self.ui.horizontalLayout_8.addLayout(self.alarm_box_p)
        self.ui.horizontalLayout_8.addLayout(self.alarm_box_gantry_x)
        self.ui.horizontalLayout_8.addLayout(self.alarm_box_gantry_y)
        #self.ui.horizontalLayout_8.addWidget(self.alarm_x)
        #self.ui.horizontalLayout_8.addWidget(self.alarm_y)
        #self.ui.horizontalLayout_8.addWidget(self.alarm_p)
        #self.ui.horizontalLayout_8.addWidget(self.stop_button)

        #self.ui.verticalLayout_6.setAlignment(Qt.AlignCenter)
        self.ui.horizontalLayout_14.addWidget(self.advanced_button)
        self.ui.horizontalLayout_14.addSpacing(50)
        self.ui.horizontalLayout_14.addWidget(self.stop_button)
        self.ui.horizontalLayout_14.addSpacing(160)

        self.ui.setGeometry(QtCore.QRect(0,0, 360, 385))

    def stop_motors(self):
        self.x_stop.put(1)
        self.y_stop.put(1)
        self.p_stop.put(1)

    def ui_filename(self):
        # Point to our UI file
        return 'mirrorScreen.ui'

    def ui_filepath(self):
        # Return the full path to the UI file
        return path.join(path.dirname(path.realpath(__file__)), self.ui_filename())
Пример #35
0
class PyDMChartingDisplay(Display):
    def __init__(self, parent=None, args=[], macros=None):
        """
        Create all the widgets, including any child dialogs.

        Parameters
        ----------
        parent : QWidget
            The parent widget of the charting display
        args : list
            The command parameters
        macros : str
            Macros to modify the UI parameters at runtime
        """
        super(PyDMChartingDisplay, self).__init__(parent=parent,
                                                  args=args,
                                                  macros=macros)

        self.channel_map = dict()
        self.setWindowTitle("PyDM Charting Tool")

        self.main_layout = QVBoxLayout()
        self.body_layout = QVBoxLayout()

        self.pv_layout = QHBoxLayout()
        self.pv_name_line_edt = QLineEdit()
        self.pv_name_line_edt.setAcceptDrops(True)
        self.pv_name_line_edt.installEventFilter(self)

        self.pv_protocol_cmb = QComboBox()
        self.pv_protocol_cmb.addItems(["ca://", "archive://"])

        self.pv_connect_push_btn = QPushButton("Connect")
        self.pv_connect_push_btn.clicked.connect(self.add_curve)

        self.tab_panel = QTabWidget()
        self.tab_panel.setMaximumWidth(450)
        self.curve_settings_tab = QWidget()
        self.chart_settings_tab = QWidget()

        self.charting_layout = QHBoxLayout()
        self.chart = PyDMTimePlot(plot_by_timestamps=False, plot_display=self)
        self.chart.setPlotTitle("Time Plot")

        self.splitter = QSplitter()

        self.curve_settings_layout = QVBoxLayout()
        self.curve_settings_layout.setAlignment(Qt.AlignTop)
        self.curve_settings_layout.setSizeConstraint(QLayout.SetMinAndMaxSize)
        self.curve_settings_layout.setSpacing(5)

        self.crosshair_settings_layout = QVBoxLayout()
        self.crosshair_settings_layout.setAlignment(Qt.AlignTop)
        self.crosshair_settings_layout.setSpacing(5)

        self.enable_crosshair_chk = QCheckBox("Enable Crosshair")
        self.cross_hair_coord_lbl = QLabel()

        self.curve_settings_inner_frame = QFrame()
        self.curve_settings_inner_frame.setLayout(self.curve_settings_layout)

        self.curve_settings_scroll = QScrollArea()
        self.curve_settings_scroll.setVerticalScrollBarPolicy(
            Qt.ScrollBarAsNeeded)
        self.curve_settings_scroll.setWidget(self.curve_settings_inner_frame)

        self.curves_tab_layout = QHBoxLayout()
        self.curves_tab_layout.addWidget(self.curve_settings_scroll)

        self.enable_crosshair_chk.setChecked(False)
        self.enable_crosshair_chk.clicked.connect(
            self.handle_enable_crosshair_checkbox_clicked)
        self.enable_crosshair_chk.clicked.emit(False)

        self.chart_settings_layout = QVBoxLayout()
        self.chart_settings_layout.setAlignment(Qt.AlignTop)

        self.chart_layout = QVBoxLayout()
        self.chart_panel = QWidget()

        self.chart_control_layout = QHBoxLayout()
        self.chart_control_layout.setAlignment(Qt.AlignHCenter)
        self.chart_control_layout.setSpacing(10)

        self.view_all_btn = QPushButton("View All")
        self.view_all_btn.clicked.connect(self.handle_view_all_button_clicked)
        self.view_all_btn.setEnabled(False)

        self.auto_scale_btn = QPushButton("Auto Scale")
        self.auto_scale_btn.clicked.connect(self.handle_auto_scale_btn_clicked)
        self.auto_scale_btn.setEnabled(False)

        self.reset_chart_btn = QPushButton("Reset")
        self.reset_chart_btn.clicked.connect(
            self.handle_reset_chart_btn_clicked)
        self.reset_chart_btn.setEnabled(False)

        self.resume_chart_text = "Resume"
        self.pause_chart_text = "Pause"
        self.pause_chart_btn = QPushButton(self.pause_chart_text)
        self.pause_chart_btn.clicked.connect(
            self.handle_pause_chart_btn_clicked)

        self.title_settings_layout = QVBoxLayout()
        self.title_settings_layout.setSpacing(10)

        self.title_settings_grpbx = QGroupBox()
        self.title_settings_grpbx.setFixedHeight(150)

        self.import_data_btn = QPushButton("Import Data...")
        self.import_data_btn.clicked.connect(
            self.handle_import_data_btn_clicked)

        self.export_data_btn = QPushButton("Export Data...")
        self.export_data_btn.clicked.connect(
            self.handle_export_data_btn_clicked)

        self.chart_title_lbl = QLabel(text="Chart Title")
        self.chart_title_line_edt = QLineEdit()
        self.chart_title_line_edt.setText(self.chart.getPlotTitle())
        self.chart_title_line_edt.textChanged.connect(
            self.handle_title_text_changed)

        self.chart_change_axis_settings_btn = QPushButton(
            text="Change Axis Settings...")
        self.chart_change_axis_settings_btn.clicked.connect(
            self.handle_change_axis_settings_clicked)

        self.update_datetime_timer = QTimer(self)
        self.update_datetime_timer.timeout.connect(
            self.handle_update_datetime_timer_timeout)

        self.chart_sync_mode_layout = QVBoxLayout()
        self.chart_sync_mode_layout.setSpacing(5)

        self.chart_sync_mode_grpbx = QGroupBox("Data Sampling Mode")
        self.chart_sync_mode_grpbx.setFixedHeight(80)

        self.chart_sync_mode_sync_radio = QRadioButton("Synchronous")
        self.chart_sync_mode_async_radio = QRadioButton("Asynchronous")
        self.chart_sync_mode_async_radio.setChecked(True)

        self.graph_drawing_settings_layout = QVBoxLayout()

        self.chart_redraw_rate_lbl = QLabel("Redraw Rate (Hz)")
        self.chart_redraw_rate_spin = QSpinBox()
        self.chart_redraw_rate_spin.setRange(MIN_REDRAW_RATE_HZ,
                                             MAX_REDRAW_RATE_HZ)
        self.chart_redraw_rate_spin.setValue(DEFAULT_REDRAW_RATE_HZ)
        self.chart_redraw_rate_spin.valueChanged.connect(
            self.handle_redraw_rate_changed)

        self.chart_data_sampling_rate_lbl = QLabel(
            "Asynchronous Data Sampling Rate (Hz)")
        self.chart_data_async_sampling_rate_spin = QSpinBox()
        self.chart_data_async_sampling_rate_spin.setRange(
            MIN_DATA_SAMPLING_RATE_HZ, MAX_DATA_SAMPLING_RATE_HZ)
        self.chart_data_async_sampling_rate_spin.setValue(
            DEFAULT_DATA_SAMPLING_RATE_HZ)
        self.chart_data_async_sampling_rate_spin.valueChanged.connect(
            self.handle_data_sampling_rate_changed)
        self.chart_data_sampling_rate_lbl.hide()
        self.chart_data_async_sampling_rate_spin.hide()

        self.chart_limit_time_span_layout = QHBoxLayout()
        self.chart_limit_time_span_layout.setSpacing(5)

        self.limit_time_plan_text = "Limit Time Span"
        self.chart_limit_time_span_chk = QCheckBox(self.limit_time_plan_text)
        self.chart_limit_time_span_chk.hide()
        self.chart_limit_time_span_lbl = QLabel("Hours : Minutes : Seconds")
        self.chart_limit_time_span_hours_line_edt = QLineEdit()
        self.chart_limit_time_span_minutes_line_edt = QLineEdit()
        self.chart_limit_time_span_seconds_line_edt = QLineEdit()
        self.chart_limit_time_span_activate_btn = QPushButton("Apply")
        self.chart_limit_time_span_activate_btn.setDisabled(True)

        self.chart_ring_buffer_size_lbl = QLabel("Ring Buffer Size")
        self.chart_ring_buffer_size_edt = QLineEdit()
        self.chart_ring_buffer_size_edt.installEventFilter(self)
        self.chart_ring_buffer_size_edt.textChanged.connect(
            self.handle_buffer_size_changed)
        self.chart_ring_buffer_size_edt.setText(str(DEFAULT_BUFFER_SIZE))

        self.show_legend_chk = QCheckBox("Show Legend")
        self.show_legend_chk.setChecked(self.chart.showLegend)
        self.show_legend_chk.clicked.connect(
            self.handle_show_legend_checkbox_clicked)

        self.graph_background_color_layout = QFormLayout()

        self.background_color_lbl = QLabel("Graph Background Color ")
        self.background_color_btn = QPushButton()
        self.background_color_btn.setStyleSheet(
            "background-color: " + self.chart.getBackgroundColor().name())
        self.background_color_btn.setContentsMargins(10, 0, 5, 5)
        self.background_color_btn.setMaximumWidth(20)
        self.background_color_btn.clicked.connect(
            self.handle_background_color_button_clicked)

        self.axis_settings_layout = QVBoxLayout()
        self.axis_settings_layout.setSpacing(5)

        self.show_x_grid_chk = QCheckBox("Show x Grid")
        self.show_x_grid_chk.setChecked(self.chart.showXGrid)
        self.show_x_grid_chk.clicked.connect(
            self.handle_show_x_grid_checkbox_clicked)

        self.show_y_grid_chk = QCheckBox("Show y Grid")
        self.show_y_grid_chk.setChecked(self.chart.showYGrid)
        self.show_y_grid_chk.clicked.connect(
            self.handle_show_y_grid_checkbox_clicked)

        self.axis_color_lbl = QLabel("Axis and Grid Color")
        self.axis_color_lbl.setEnabled(False)

        self.axis_color_btn = QPushButton()
        self.axis_color_btn.setStyleSheet("background-color: " +
                                          DEFAULT_CHART_AXIS_COLOR.name())
        self.axis_color_btn.setContentsMargins(10, 0, 5, 5)
        self.axis_color_btn.setMaximumWidth(20)
        self.axis_color_btn.clicked.connect(
            self.handle_axis_color_button_clicked)
        self.axis_color_btn.setEnabled(False)

        self.grid_opacity_lbl = QLabel("Grid Opacity")
        self.grid_opacity_lbl.setEnabled(False)

        self.grid_opacity_slr = QSlider(Qt.Horizontal)
        self.grid_opacity_slr.setFocusPolicy(Qt.StrongFocus)
        self.grid_opacity_slr.setRange(0, 10)
        self.grid_opacity_slr.setValue(5)
        self.grid_opacity_slr.setTickInterval(1)
        self.grid_opacity_slr.setSingleStep(1)
        self.grid_opacity_slr.setTickPosition(QSlider.TicksBelow)
        self.grid_opacity_slr.valueChanged.connect(
            self.handle_grid_opacity_slider_mouse_release)
        self.grid_opacity_slr.setEnabled(False)

        self.reset_chart_settings_btn = QPushButton("Reset Chart Settings")
        self.reset_chart_settings_btn.clicked.connect(
            self.handle_reset_chart_settings_btn_clicked)

        self.curve_checkbox_panel = QWidget()

        self.graph_drawing_settings_grpbx = QGroupBox()
        self.graph_drawing_settings_grpbx.setFixedHeight(270)

        self.axis_settings_grpbx = QGroupBox()
        self.axis_settings_grpbx.setFixedHeight(180)

        self.app = QApplication.instance()
        self.setup_ui()

        self.curve_settings_disp = None
        self.axis_settings_disp = None
        self.chart_data_export_disp = None
        self.chart_data_import_disp = None
        self.grid_alpha = 5
        self.time_span_limit_hours = None
        self.time_span_limit_minutes = None
        self.time_span_limit_seconds = None
        self.data_sampling_mode = ASYNC_DATA_SAMPLING

    def minimumSizeHint(self):
        """
        The minimum recommended size of the main window.
        """
        return QSize(1490, 800)

    def ui_filepath(self):
        """
        The path to the UI file created by Qt Designer, if applicable.
        """
        # No UI file is being used
        return None

    def ui_filename(self):
        """
        The name the UI file created by Qt Designer, if applicable.
        """
        # No UI file is being used
        return None

    def setup_ui(self):
        """
        Initialize the widgets and layouts.
        """
        self.setLayout(self.main_layout)

        self.pv_layout.addWidget(self.pv_protocol_cmb)
        self.pv_layout.addWidget(self.pv_name_line_edt)
        self.pv_layout.addWidget(self.pv_connect_push_btn)
        QTimer.singleShot(0, self.pv_name_line_edt.setFocus)

        self.curve_settings_tab.setLayout(self.curves_tab_layout)
        self.chart_settings_tab.setLayout(self.chart_settings_layout)
        self.setup_chart_settings_layout()

        self.tab_panel.addTab(self.curve_settings_tab, "Curves")
        self.tab_panel.addTab(self.chart_settings_tab, "Chart")
        self.tab_panel.hide()

        self.crosshair_settings_layout.addWidget(self.enable_crosshair_chk)
        self.crosshair_settings_layout.addWidget(self.cross_hair_coord_lbl)

        self.chart_control_layout.addWidget(self.auto_scale_btn)
        self.chart_control_layout.addWidget(self.view_all_btn)
        self.chart_control_layout.addWidget(self.reset_chart_btn)
        self.chart_control_layout.addWidget(self.pause_chart_btn)
        self.chart_control_layout.addLayout(self.crosshair_settings_layout)
        self.chart_control_layout.addWidget(self.import_data_btn)
        self.chart_control_layout.addWidget(self.export_data_btn)

        self.chart_control_layout.setStretch(4, 15)
        self.chart_control_layout.insertSpacing(5, 350)

        self.chart_layout.addWidget(self.chart)
        self.chart_layout.addLayout(self.chart_control_layout)

        self.chart_panel.setLayout(self.chart_layout)

        self.splitter.addWidget(self.chart_panel)
        self.splitter.addWidget(self.tab_panel)
        self.splitter.setStretchFactor(0, 0)
        self.splitter.setStretchFactor(1, 1)

        self.charting_layout.addWidget(self.splitter)

        self.body_layout.addLayout(self.pv_layout)
        self.body_layout.addLayout(self.charting_layout)
        self.body_layout.addLayout(self.chart_control_layout)
        self.main_layout.addLayout(self.body_layout)

        self.enable_chart_control_buttons(False)

    def setup_chart_settings_layout(self):
        self.chart_sync_mode_sync_radio.toggled.connect(
            partial(self.handle_sync_mode_radio_toggle,
                    self.chart_sync_mode_sync_radio))
        self.chart_sync_mode_async_radio.toggled.connect(
            partial(self.handle_sync_mode_radio_toggle,
                    self.chart_sync_mode_async_radio))

        self.title_settings_layout.addWidget(self.chart_title_lbl)
        self.title_settings_layout.addWidget(self.chart_title_line_edt)
        self.title_settings_layout.addWidget(self.show_legend_chk)
        self.title_settings_layout.addWidget(
            self.chart_change_axis_settings_btn)
        self.title_settings_grpbx.setLayout(self.title_settings_layout)
        self.chart_settings_layout.addWidget(self.title_settings_grpbx)

        self.chart_sync_mode_layout.addWidget(self.chart_sync_mode_sync_radio)
        self.chart_sync_mode_layout.addWidget(self.chart_sync_mode_async_radio)
        self.chart_sync_mode_grpbx.setLayout(self.chart_sync_mode_layout)
        self.chart_settings_layout.addWidget(self.chart_sync_mode_grpbx)

        self.chart_settings_layout.addWidget(self.chart_sync_mode_grpbx)

        self.chart_limit_time_span_layout.addWidget(
            self.chart_limit_time_span_lbl)
        self.chart_limit_time_span_layout.addWidget(
            self.chart_limit_time_span_hours_line_edt)

        self.chart_limit_time_span_layout.addWidget(
            self.chart_limit_time_span_minutes_line_edt)
        self.chart_limit_time_span_layout.addWidget(
            self.chart_limit_time_span_seconds_line_edt)
        self.chart_limit_time_span_layout.addWidget(
            self.chart_limit_time_span_activate_btn)

        self.chart_limit_time_span_lbl.hide()
        self.chart_limit_time_span_hours_line_edt.hide()
        self.chart_limit_time_span_minutes_line_edt.hide()
        self.chart_limit_time_span_seconds_line_edt.hide()
        self.chart_limit_time_span_activate_btn.hide()

        self.chart_limit_time_span_hours_line_edt.textChanged.connect(
            self.handle_time_span_edt_text_changed)
        self.chart_limit_time_span_minutes_line_edt.textChanged.connect(
            self.handle_time_span_edt_text_changed)
        self.chart_limit_time_span_seconds_line_edt.textChanged.connect(
            self.handle_time_span_edt_text_changed)

        self.chart_limit_time_span_chk.clicked.connect(
            self.handle_limit_time_span_checkbox_clicked)
        self.chart_limit_time_span_activate_btn.clicked.connect(
            self.handle_chart_limit_time_span_activate_btn_clicked)
        self.chart_limit_time_span_activate_btn.installEventFilter(self)

        self.graph_background_color_layout.addRow(self.background_color_lbl,
                                                  self.background_color_btn)

        self.graph_drawing_settings_layout.addLayout(
            self.graph_background_color_layout)
        self.graph_drawing_settings_layout.addWidget(
            self.chart_redraw_rate_lbl)
        self.graph_drawing_settings_layout.addWidget(
            self.chart_redraw_rate_spin)
        self.graph_drawing_settings_layout.addWidget(
            self.chart_data_sampling_rate_lbl)
        self.graph_drawing_settings_layout.addWidget(
            self.chart_data_async_sampling_rate_spin)
        self.graph_drawing_settings_layout.addWidget(
            self.chart_limit_time_span_chk)
        self.graph_drawing_settings_layout.addLayout(
            self.chart_limit_time_span_layout)
        self.graph_drawing_settings_layout.addWidget(
            self.chart_ring_buffer_size_lbl)
        self.graph_drawing_settings_layout.addWidget(
            self.chart_ring_buffer_size_edt)
        self.graph_drawing_settings_grpbx.setLayout(
            self.graph_drawing_settings_layout)

        self.axis_settings_layout.addWidget(self.show_x_grid_chk)
        self.axis_settings_layout.addWidget(self.show_y_grid_chk)
        self.axis_settings_layout.addWidget(self.axis_color_lbl)
        self.axis_settings_layout.addWidget(self.axis_color_btn)
        self.axis_settings_layout.addWidget(self.grid_opacity_lbl)
        self.axis_settings_layout.addWidget(self.grid_opacity_slr)
        self.axis_settings_grpbx.setLayout(self.axis_settings_layout)

        self.chart_settings_layout.addWidget(self.graph_drawing_settings_grpbx)
        self.chart_settings_layout.addWidget(self.axis_settings_grpbx)
        self.chart_settings_layout.addWidget(self.reset_chart_settings_btn)

        self.chart_sync_mode_async_radio.toggled.emit(True)
        self.update_datetime_timer.start(1000)

    def eventFilter(self, obj, event):
        """
        Handle key and mouse events for any applicable widget.

        Parameters
        ----------
        obj : QWidget
            The current widget that accepts the event
        event : QEvent
            The key or mouse event to handle

        Returns
        -------
            True if the event was handled successfully; False otherwise
        """
        if obj == self.pv_name_line_edt and event.type() == QEvent.KeyPress:
            if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return:
                self.add_curve()
                return True
        elif obj == self.chart_limit_time_span_activate_btn and event.type(
        ) == QEvent.KeyPress:
            if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return:
                self.handle_chart_limit_time_span_activate_btn_clicked()
                return True
        elif obj == self.chart_ring_buffer_size_edt:
            if event.type() == QEvent.KeyPress and (event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return) or \
                    event.type() == QEvent.FocusOut:
                try:
                    buffer_size = int(self.chart_ring_buffer_size_edt.text())
                    if buffer_size < MINIMUM_BUFFER_SIZE:
                        self.chart_ring_buffer_size_edt.setText(
                            str(MINIMUM_BUFFER_SIZE))
                except ValueError:
                    display_message_box(QMessageBox.Critical, "Invalid Values",
                                        "Only integer values are accepted.")
                return True
        return super(PyDMChartingDisplay, self).eventFilter(obj, event)

    def add_curve(self):
        """
        Add a new curve to the chart.
        """
        pv_name = self._get_full_pv_name(self.pv_name_line_edt.text())
        color = random_color()
        for k, v in self.channel_map.items():
            if color == v.color:
                color = random_color()

        self.add_y_channel(pv_name=pv_name, curve_name=pv_name, color=color)

    def handle_enable_crosshair_checkbox_clicked(self, is_checked):
        self.chart.enableCrosshair(is_checked)
        self.cross_hair_coord_lbl.setVisible(is_checked)

    def add_y_channel(self,
                      pv_name,
                      curve_name,
                      color,
                      line_style=Qt.SolidLine,
                      line_width=2,
                      symbol=None,
                      symbol_size=None):
        if pv_name in self.channel_map:
            logger.error("'{0}' has already been added.".format(pv_name))
            return

        curve = self.chart.addYChannel(y_channel=pv_name,
                                       name=curve_name,
                                       color=color,
                                       lineStyle=line_style,
                                       lineWidth=line_width,
                                       symbol=symbol,
                                       symbolSize=symbol_size)
        self.channel_map[pv_name] = curve
        self.generate_pv_controls(pv_name, color)

        self.enable_chart_control_buttons()
        self.app.establish_widget_connections(self)

    def generate_pv_controls(self, pv_name, curve_color):
        """
        Generate a set of widgets to manage the appearance of a curve. The set of widgets includes:
            1. A checkbox which shows the curve on the chart if checked, and hide the curve if not checked
            2. Two buttons -- Modify... and Remove. Modify... will bring up the Curve Settings dialog. Remove will
               delete the curve from the chart
        This set of widgets will be hidden initially, until the first curve is plotted.

        Parameters
        ----------
        pv_name: str
            The name of the PV the current curve is being plotted for

        curve_color : QColor
            The color of the curve to paint for the checkbox label to help the user track the curve to the checkbox
        """
        checkbox = QCheckBox()
        checkbox.setObjectName(pv_name)

        palette = checkbox.palette()
        palette.setColor(QPalette.Active, QPalette.WindowText, curve_color)
        checkbox.setPalette(palette)

        display_name = pv_name.split("://")[1]
        if len(display_name) > MAX_DISPLAY_PV_NAME_LENGTH:
            # Only display max allowed number of characters of the PV Name
            display_name = display_name[:int(MAX_DISPLAY_PV_NAME_LENGTH / 2) - 1] + "..." + \
                           display_name[-int(MAX_DISPLAY_PV_NAME_LENGTH / 2) + 2:]

        checkbox.setText(display_name)

        data_text = QLabel()
        data_text.setObjectName(pv_name)
        data_text.setPalette(palette)

        checkbox.setChecked(True)
        checkbox.clicked.connect(
            partial(self.handle_curve_chkbox_toggled, checkbox))

        curve_btn_layout = QHBoxLayout()

        modify_curve_btn = QPushButton("Modify...")
        modify_curve_btn.setObjectName(pv_name)
        modify_curve_btn.setMaximumWidth(100)
        modify_curve_btn.clicked.connect(
            partial(self.display_curve_settings_dialog, pv_name))

        focus_curve_btn = QPushButton("Focus")
        focus_curve_btn.setObjectName(pv_name)
        focus_curve_btn.setMaximumWidth(100)
        focus_curve_btn.clicked.connect(partial(self.focus_curve, pv_name))

        annotate_curve_btn = QPushButton("Annotate...")
        annotate_curve_btn.setObjectName(pv_name)
        annotate_curve_btn.setMaximumWidth(100)
        annotate_curve_btn.clicked.connect(
            partial(self.annotate_curve, pv_name))

        remove_curve_btn = QPushButton("Remove")
        remove_curve_btn.setObjectName(pv_name)
        remove_curve_btn.setMaximumWidth(100)
        remove_curve_btn.clicked.connect(partial(self.remove_curve, pv_name))

        curve_btn_layout.addWidget(modify_curve_btn)
        curve_btn_layout.addWidget(focus_curve_btn)
        curve_btn_layout.addWidget(annotate_curve_btn)
        curve_btn_layout.addWidget(remove_curve_btn)

        individual_curve_layout = QVBoxLayout()
        individual_curve_layout.addWidget(checkbox)
        individual_curve_layout.addWidget(data_text)
        individual_curve_layout.addLayout(curve_btn_layout)

        size_policy = QSizePolicy()
        size_policy.setVerticalPolicy(QSizePolicy.Fixed)
        individual_curve_grpbx = QGroupBox()
        individual_curve_grpbx.setSizePolicy(size_policy)

        individual_curve_grpbx.setObjectName(pv_name)
        individual_curve_grpbx.setLayout(individual_curve_layout)

        self.curve_settings_layout.addWidget(individual_curve_grpbx)
        self.tab_panel.show()

    def handle_curve_chkbox_toggled(self, checkbox):
        """
        Handle a checkbox's checked and unchecked events.

        If a checkbox is checked, find the curve from the channel map. If found, re-draw the curve with its previous
        appearance settings.

        If a checkbox is unchecked, remove the curve from the chart, but keep the cached data in the channel map.

        Parameters
        ----------
        checkbox : QCheckBox
            The current checkbox being toggled
        """
        pv_name = self._get_full_pv_name(checkbox.text())

        if checkbox.isChecked():
            curve = self.channel_map.get(pv_name, None)
            if curve:
                self.chart.addLegendItem(curve, pv_name,
                                         self.show_legend_chk.isChecked())
                curve.show()
        else:
            curve = self.chart.findCurve(pv_name)
            if curve:
                curve.hide()
                self.chart.removeLegendItem(pv_name)

    def display_curve_settings_dialog(self, pv_name):
        """
        Bring up the Curve Settings dialog to modify the appearance of a curve.

        Parameters
        ----------
        pv_name : str
            The name of the PV the curve is being plotted for

        """
        self.curve_settings_disp = CurveSettingsDisplay(self, pv_name)
        self.curve_settings_disp.show()

    def focus_curve(self, pv_name):
        curve = self.chart.findCurve(pv_name)
        if curve:
            self.chart.plotItem.setYRange(curve.minY, curve.maxY, padding=0)

    def annotate_curve(self, pv_name):
        curve = self.chart.findCurve(pv_name)
        if curve:
            annot = TextItem(
                html=
                '<div style="text-align: center"><span style="color: #FFF;">This is the'
                '</span><br><span style="color: #FF0; font-size: 16pt;">PEAK</span></div>',
                anchor=(-0.3, 0.5),
                border='w',
                fill=(0, 0, 255, 100))
            annot = TextItem("test", anchor=(-0.3, 0.5))
            self.chart.annotateCurve(curve, annot)

    def remove_curve(self, pv_name):
        """
        Remove a curve from the chart permanently. This will also clear the channel map cache from retaining the
        removed curve's appearance settings.

        Parameters
        ----------
        pv_name : str
            The name of the PV the curve is being plotted for
        """
        curve = self.chart.findCurve(pv_name)
        if curve:
            self.chart.removeYChannel(curve)
            del self.channel_map[pv_name]
            self.chart.removeLegendItem(pv_name)

            widgets = self.findChildren(
                (QCheckBox, QLabel, QPushButton, QGroupBox), pv_name)
            for w in widgets:
                w.deleteLater()

        if len(self.chart.getCurves()) < 1:
            self.enable_chart_control_buttons(False)
            self.show_legend_chk.setChecked(False)

    def handle_title_text_changed(self, new_text):
        self.chart.setPlotTitle(new_text)

    def handle_change_axis_settings_clicked(self):
        self.axis_settings_disp = AxisSettingsDisplay(self)
        self.axis_settings_disp.show()

    def handle_limit_time_span_checkbox_clicked(self, is_checked):
        self.chart_limit_time_span_lbl.setVisible(is_checked)
        self.chart_limit_time_span_hours_line_edt.setVisible(is_checked)
        self.chart_limit_time_span_minutes_line_edt.setVisible(is_checked)
        self.chart_limit_time_span_seconds_line_edt.setVisible(is_checked)
        self.chart_limit_time_span_activate_btn.setVisible(is_checked)

        self.chart_ring_buffer_size_lbl.setDisabled(is_checked)
        self.chart_ring_buffer_size_edt.setDisabled(is_checked)

        if not is_checked:
            self.chart_limit_time_span_chk.setText(self.limit_time_plan_text)

    def handle_time_span_edt_text_changed(self, new_text):
        try:
            self.time_span_limit_hours = int(
                self.chart_limit_time_span_hours_line_edt.text())
            self.time_span_limit_minutes = int(
                self.chart_limit_time_span_minutes_line_edt.text())
            self.time_span_limit_seconds = int(
                self.chart_limit_time_span_seconds_line_edt.text())
        except ValueError as e:
            self.time_span_limit_hours = None
            self.time_span_limit_minutes = None
            self.time_span_limit_seconds = None

        if self.time_span_limit_hours is not None and self.time_span_limit_minutes is not None and \
                self.time_span_limit_seconds is not None:
            self.chart_limit_time_span_activate_btn.setEnabled(True)
        else:
            self.chart_limit_time_span_activate_btn.setEnabled(False)

    def handle_chart_limit_time_span_activate_btn_clicked(self):
        if self.time_span_limit_hours is None or self.time_span_limit_minutes is None or \
                self.time_span_limit_seconds is None:
            display_message_box(
                QMessageBox.Critical, "Invalid Values",
                "Hours, minutes, and seconds expect only integer values.")
        else:
            timeout_milliseconds = (self.time_span_limit_hours * 3600 +
                                    self.time_span_limit_minutes * 60 +
                                    self.time_span_limit_seconds) * 1000
            self.chart.setTimeSpan(timeout_milliseconds / 1000.0)
            self.chart_ring_buffer_size_edt.setText(
                str(self.chart.getBufferSize()))

    def handle_buffer_size_changed(self, new_buffer_size):
        try:
            if new_buffer_size and int(new_buffer_size) > MINIMUM_BUFFER_SIZE:
                self.chart.setBufferSize(new_buffer_size)
        except ValueError:
            display_message_box(QMessageBox.Critical, "Invalid Values",
                                "Only integer values are accepted.")

    def handle_redraw_rate_changed(self, new_redraw_rate):
        self.chart.maxRedrawRate = new_redraw_rate

    def handle_data_sampling_rate_changed(self, new_data_sampling_rate):
        # The chart expects the value in milliseconds
        sampling_rate_seconds = 1 / new_data_sampling_rate
        self.chart.setUpdateInterval(sampling_rate_seconds)

    def handle_background_color_button_clicked(self):
        selected_color = QColorDialog.getColor()
        self.chart.setBackgroundColor(selected_color)
        self.background_color_btn.setStyleSheet("background-color: " +
                                                selected_color.name())

    def handle_axis_color_button_clicked(self):
        selected_color = QColorDialog.getColor()
        self.chart.setAxisColor(selected_color)
        self.axis_color_btn.setStyleSheet("background-color: " +
                                          selected_color.name())

    def handle_grid_opacity_slider_mouse_release(self):
        self.grid_alpha = float(self.grid_opacity_slr.value()) / 10.0
        self.chart.setShowXGrid(self.show_x_grid_chk.isChecked(),
                                self.grid_alpha)
        self.chart.setShowYGrid(self.show_y_grid_chk.isChecked(),
                                self.grid_alpha)

    def handle_show_x_grid_checkbox_clicked(self, is_checked):
        self.chart.setShowXGrid(is_checked, self.grid_alpha)

        self.axis_color_lbl.setEnabled(is_checked
                                       or self.show_y_grid_chk.isChecked())
        self.axis_color_btn.setEnabled(is_checked
                                       or self.show_y_grid_chk.isChecked())
        self.grid_opacity_lbl.setEnabled(is_checked
                                         or self.show_y_grid_chk.isChecked())
        self.grid_opacity_slr.setEnabled(is_checked
                                         or self.show_y_grid_chk.isChecked())

    def handle_show_y_grid_checkbox_clicked(self, is_checked):
        self.chart.setShowYGrid(is_checked, self.grid_alpha)

        self.axis_color_lbl.setEnabled(is_checked
                                       or self.show_x_grid_chk.isChecked())
        self.axis_color_btn.setEnabled(is_checked
                                       or self.show_x_grid_chk.isChecked())
        self.grid_opacity_lbl.setEnabled(is_checked
                                         or self.show_x_grid_chk.isChecked())
        self.grid_opacity_slr.setEnabled(is_checked
                                         or self.show_x_grid_chk.isChecked())

    def handle_show_legend_checkbox_clicked(self, is_checked):
        self.chart.setShowLegend(is_checked)

    def handle_export_data_btn_clicked(self):
        self.chart_data_export_disp = ChartDataExportDisplay(self)
        self.chart_data_export_disp.show()

    def handle_import_data_btn_clicked(self):
        open_file_info = QFileDialog.getOpenFileName(self,
                                                     caption="Save File",
                                                     filter="*." +
                                                     IMPORT_FILE_FORMAT)
        open_file_name = open_file_info[0]
        if open_file_name:
            importer = SettingsImporter(self)
            importer.import_settings(open_file_name)

    def handle_sync_mode_radio_toggle(self, radio_btn):
        if radio_btn.isChecked():
            if radio_btn.text() == "Synchronous":
                self.data_sampling_mode = SYNC_DATA_SAMPLING

                self.chart_data_sampling_rate_lbl.hide()
                self.chart_data_async_sampling_rate_spin.hide()

                self.chart.resetTimeSpan()
                self.chart_limit_time_span_chk.setChecked(False)
                self.chart_limit_time_span_chk.clicked.emit(False)
                self.chart_limit_time_span_chk.hide()
                self.graph_drawing_settings_grpbx.setFixedHeight(180)

                self.chart.setUpdatesAsynchronously(False)
            elif radio_btn.text() == "Asynchronous":
                self.data_sampling_mode = ASYNC_DATA_SAMPLING

                self.chart_data_sampling_rate_lbl.show()
                self.chart_data_async_sampling_rate_spin.show()
                self.chart_limit_time_span_chk.show()
                self.graph_drawing_settings_grpbx.setFixedHeight(270)

                self.chart.setUpdatesAsynchronously(True)
        self.app.establish_widget_connections(self)

    def handle_auto_scale_btn_clicked(self):
        self.chart.resetAutoRangeX()
        self.chart.resetAutoRangeY()

    def handle_view_all_button_clicked(self):
        self.chart.getViewBox().autoRange()

    def handle_pause_chart_btn_clicked(self):
        if self.chart.pausePlotting():
            self.pause_chart_btn.setText(self.pause_chart_text)
        else:
            self.pause_chart_btn.setText(self.resume_chart_text)

    def handle_reset_chart_btn_clicked(self):
        self.chart.getViewBox().setXRange(DEFAULT_X_MIN, 0)
        self.chart.resetAutoRangeY()

    @Slot()
    def handle_reset_chart_settings_btn_clicked(self):
        self.chart_ring_buffer_size_edt.setText(str(DEFAULT_BUFFER_SIZE))

        self.chart_redraw_rate_spin.setValue(DEFAULT_REDRAW_RATE_HZ)
        self.chart_data_async_sampling_rate_spin.setValue(
            DEFAULT_DATA_SAMPLING_RATE_HZ)
        self.chart_data_sampling_rate_lbl.hide()
        self.chart_data_async_sampling_rate_spin.hide()

        self.chart_sync_mode_async_radio.setChecked(True)
        self.chart_sync_mode_async_radio.toggled.emit(True)

        self.chart_limit_time_span_chk.setChecked(False)
        self.chart_limit_time_span_chk.setText(self.limit_time_plan_text)
        self.chart_limit_time_span_chk.clicked.emit(False)

        self.chart.setUpdatesAsynchronously(True)
        self.chart.resetTimeSpan()
        self.chart.resetUpdateInterval()
        self.chart.setBufferSize(DEFAULT_BUFFER_SIZE)

        self.chart.setBackgroundColor(DEFAULT_CHART_BACKGROUND_COLOR)
        self.background_color_btn.setStyleSheet(
            "background-color: " + DEFAULT_CHART_BACKGROUND_COLOR.name())

        self.chart.setAxisColor(DEFAULT_CHART_AXIS_COLOR)
        self.axis_color_btn.setStyleSheet("background-color: " +
                                          DEFAULT_CHART_AXIS_COLOR.name())

        self.grid_opacity_slr.setValue(5)

        self.show_x_grid_chk.setChecked(False)
        self.show_x_grid_chk.clicked.emit(False)

        self.show_y_grid_chk.setChecked(False)
        self.show_y_grid_chk.clicked.emit(False)

        self.show_legend_chk.setChecked(False)

        self.chart.setShowXGrid(False)
        self.chart.setShowYGrid(False)
        self.chart.setShowLegend(False)

    def enable_chart_control_buttons(self, enabled=True):
        self.auto_scale_btn.setEnabled(enabled)
        self.view_all_btn.setEnabled(enabled)
        self.reset_chart_btn.setEnabled(enabled)
        self.pause_chart_btn.setText(self.pause_chart_text)
        self.pause_chart_btn.setEnabled(enabled)
        self.export_data_btn.setEnabled(enabled)

    def _get_full_pv_name(self, pv_name):
        """
        Append the protocol to the PV Name.

        Parameters
        ----------
        pv_name : str
            The name of the PV the curve is being plotted for
        """
        if pv_name and "://" not in pv_name:
            pv_name = ''.join([self.pv_protocol_cmb.currentText(), pv_name])
        return pv_name

    def handle_update_datetime_timer_timeout(self):
        current_label = self.chart.getBottomAxisLabel()
        new_label = "Current Time: " + PyDMChartingDisplay.get_current_datetime(
        )

        if X_AXIS_LABEL_SEPARATOR in current_label:
            current_label = current_label[current_label.
                                          find(X_AXIS_LABEL_SEPARATOR) +
                                          len(X_AXIS_LABEL_SEPARATOR):]
            new_label += X_AXIS_LABEL_SEPARATOR + current_label

        self.chart.setLabel("bottom", text=new_label)

    def update_curve_data(self, curve):
        """
        Determine if the PV is active. If not, disable the related PV controls. If the PV is active, update the PV
        controls' states.

        Parameters
        ----------
        curve : PlotItem
           A PlotItem, i.e. a plot, to draw on the chart.
        """
        pv_name = curve.name()
        max_x = self.chart.getViewBox().viewRange()[1][0]
        max_y = self.chart.getViewBox().viewRange()[1][1]
        current_y = curve.data_buffer[1, -1]

        widgets = self.findChildren((QCheckBox, QLabel, QPushButton), pv_name)
        for w in widgets:
            if np.isnan(current_y):
                if isinstance(w, QCheckBox):
                    w.setChecked(False)
            else:
                if isinstance(w, QCheckBox) and not w.isEnabled():
                    w.setChecked(True)
                if isinstance(w, QLabel):
                    w.clear()
                    w.setText(
                        "(yMin = {0:.3f}, yMax = {1:.3f}) y = {2:.3f}".format(
                            max_x, max_y, current_y))
                    w.show()
            w.setEnabled(not np.isnan(current_y))

            if isinstance(w, QPushButton) and w.text() == "Remove":
                # Enable the Remove button to make removing inactive PVs possible anytime
                w.setEnabled(True)

    def show_mouse_coordinates(self, x, y):
        self.cross_hair_coord_lbl.clear()
        self.cross_hair_coord_lbl.setText("x = {0:.3f}, y = {1:.3f}".format(
            x, y))

    @staticmethod
    def get_current_datetime():
        current_date = datetime.datetime.now().strftime("%b %d, %Y")
        current_time = datetime.datetime.now().strftime("%H:%M:%S")
        current_datetime = current_time + ' (' + current_date + ')'

        return current_datetime

    @property
    def gridAlpha(self):
        return self.grid_alpha