Source code for pydm.widgets.enum_combo_box

import logging
import six
from qtpy.QtWidgets import QComboBox
from qtpy.QtCore import Slot, Qt
from .base import PyDMWritableWidget
from .. import data_plugins

logger = logging.getLogger(__name__)


[docs]class PyDMEnumComboBox(QComboBox, PyDMWritableWidget): """ A QComboBox with support for Channels and more from PyDM Parameters ---------- parent : QWidget The parent widget for the Label init_channel : str, optional The channel to be used by the widget. Signals ------- send_value_signal : int, float, str, bool or np.ndarray Emitted when the user changes the value. activated : int, str Emitted when the user chooses an item in the combobox. currentIndexChanged : int, str Emitted when the index is changed in the combobox. highlighted : int, str Emitted when an item in the combobox popup list is highlighted by the user. """ def __init__(self, parent=None, init_channel=None): QComboBox.__init__(self, parent) PyDMWritableWidget.__init__(self, init_channel=init_channel) self._has_enums = False self.activated[int].connect(self.internal_combo_box_activated_int) self.setContextMenuPolicy(Qt.DefaultContextMenu) self.contextMenuEvent = self.open_context_menu # Because of the way PyQt5 UI parser enumerates combobox items (first adding an item with an empty title # and then resetting that title to the actual text), we can't distinguish it from the regular title change. # This flag helps tracking title change followed immediately after adding a new item. self._new_item_added = False
[docs] def wheelEvent(self, e): # To ignore mouse wheel events e.ignore() return
[docs] def addItem(self, text, userData=None): """ Adds an item to the combobox. The item is appended to the list of existing items. Parameters ---------- text : str Title of the item userData : QVariant Arbitrary user data that is stored in the Qt.UserRole """ super(PyDMEnumComboBox, self).addItem(text, userData) self._new_item_added = True
[docs] def setItemText(self, index, text): """ Sets the text for the item on the given index in the combobox. Parameters ---------- index : int Position in the dropdown list text : str Title for the item """ super(PyDMEnumComboBox, self).setItemText(index, text) if self._new_item_added: self._new_item_added = False # Recalculate the enums super(PyDMEnumComboBox, self).enum_strings_changed(tuple(self.itemText(i) for i in range(self.count()))) self._has_enums = True self.check_enable_state()
# Internal methods
[docs] def set_items(self, enums): """ Internal method to fill the ComboBox items based on a list of strings. Parameters ---------- enums : tuple The new list of values """ if not enums: logger.error( "Invalid enum value '{0}'. The value is expected to be a valid list of string values.".format(enums) ) return self.clear() for e_str in enums: if e_str is None: logger.error("Invalid enum type '{0}'. The expected type is 'string'.".format(type(e_str))) return try: self.addItem(e_str) except TypeError as error: logger.error( "Invalid enum type '{0}'. The expected type is 'string'. Exception: {1}".format(type(e_str), error) ) self._has_enums = True self.check_enable_state()
[docs] def check_enable_state(self): """ Checks whether or not the widget should be disable. This method also disables the widget and add a Tool Tip with the reason why it is disabled. """ status = self._write_access and self._connected and self._has_enums tooltip = "" if not self._connected: tooltip += "PV is disconnected." if self.channel: tooltip += "\n" tooltip += self.get_address() elif not self._write_access: if data_plugins.is_read_only(): tooltip += "Running PyDM on Read-Only mode." else: tooltip += "Access denied by Channel Access Security." elif not self._has_enums: tooltip += "Enums not available." self.setToolTip(tooltip) self.setEnabled(status)
[docs] def enum_strings_changed(self, new_enum_strings): """ Callback invoked when the Channel has new enum values. This callback also triggers a value_changed call so the new enum values to be broadcasted Parameters ---------- new_enum_strings : tuple The new list of values """ super(PyDMEnumComboBox, self).enum_strings_changed(new_enum_strings) self.set_items(new_enum_strings)
[docs] def value_changed(self, new_val): """ Callback invoked when the Channel value is changed. Sets the value of new_value accordingly at the ComboBox. Parameters ---------- new_value : str, int, float, bool or np.ndarray The new value from the channel. The type depends on the channel. """ if new_val is not None: super(PyDMEnumComboBox, self).value_changed(new_val) # Integers are straight forward if isinstance(new_val, int): idx = new_val # String values are valid as well, but we need to look up the index elif isinstance(new_val, six.text_type): idx = self.findText(new_val) # findText return -1 when we can not find the text inside the # QComboBox if idx == -1: logger.error("Can not change value to %r. " "Not an option in PyDMComboBox", new_val) return # Handle bool, float, and ndarray else: logger.error("Invalid type for PyDMComboBox %s", type(new_val)) return # Set the index self.setCurrentIndex(idx)
[docs] @Slot(int) def internal_combo_box_activated_int(self, index): """ PyQT Slot for when the user chooses an item in the combobox. This slot triggers the ```send_value_signal```. Parameters ---------- index : int """ self.send_value_signal.emit(index)