Source code for labscript_utils.qtwidgets.enumoutput

#####################################################################
#                                                                   #
# enumcontrol.py                                                    #
#                                                                   #
# Copyright 2019, Monash University and contributors                #
#                                                                   #
# This file is part of the labscript suite (see                     #
# http://labscriptsuite.org) and is licensed under the Simplified   #
# BSD License. See the license.txt file in the root of the project  #
# for the full license.                                             #
#                                                                   #
#####################################################################
import sys

from qtutils.qt.QtCore import *
from qtutils.qt.QtGui import *
from qtutils.qt.QtWidgets import *


[docs] class EnumOutput(QWidget):
[docs] def __init__(self, hardware_name, connection_name='-', display_name=None, horizontal_alignment=False, parent=None): QWidget.__init__(self,parent) self._connection_name = connection_name self._hardware_name = hardware_name label_text = (self._hardware_name + '\n' + self._connection_name) if display_name is None else display_name self._label = QLabel(label_text) self._label.setAlignment(Qt.AlignCenter) self._label.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Minimum) self._combobox = QComboBox() self._combobox.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum) self._value_changed_function = None self.setSizePolicy(QSizePolicy.MinimumExpanding,QSizePolicy.Minimum) # Lock/Unlock action self._lock_action = QAction("Lock",self._combobox) self._lock_action.triggered.connect(lambda:self._menu_triggered(self._lock_action)) # Create widgets and layouts if horizontal_alignment: self._layout = QHBoxLayout(self) self._layout.addWidget(self._label) self._layout.addWidget(self._combobox) self._layout.setContentsMargins(0,0,0,0) else: self._layout = QGridLayout(self) self._layout.setVerticalSpacing(3) self._layout.setHorizontalSpacing(0) self._layout.setContentsMargins(3,3,3,3) self._label.setSizePolicy(QSizePolicy.MinimumExpanding,QSizePolicy.Minimum) h_widget = QWidget() h_layout = QHBoxLayout(h_widget) h_layout.setContentsMargins(0,0,0,0) h_layout.addWidget(self._combobox) self._layout.addWidget(self._label,0,0) self._layout.addWidget(h_widget,1,0) self._layout.addItem(QSpacerItem(0,0,QSizePolicy.Minimum,QSizePolicy.MinimumExpanding),2,0) # Install the event filter that will allow us to catch right click mouse release events so we can popup a menu even when the button is disabled self.installEventFilter(self) # The Analog Out object that is in charge of this button self._EO = None
# Setting and getting methods for the object in charge of this button
[docs] def set_EO(self,EO,notify_old_EO=True,notify_new_EO=True): # If we are setting a new EO, remove this widget from the old one (if it isn't None) and add it to the new one (if it isn't None) if EO != self._EO: if self._EO is not None and notify_old_EO: self._EO.remove_widget(self,False) if EO is not None and notify_new_EO: EO.add_widget(self) # Store a reference to the digital out object self._EO = EO
[docs] def get_EO(self): return self._EO
[docs] def set_combobox_model(self,model): self._combobox.setModel(model)
[docs] def connect_value_change(self,func): self._value_changed_function = func self._combobox.currentTextChanged.connect(self._value_changed_function)
[docs] def disconnect_value_change(self): self._combobox.currentTextChanged.disconnect(self._value_changed_function)
@property def selected_option(self): return str(self._combobox.currentText()) @selected_option.setter def selected_option(self,option): if option != self.selected_option: #item = self._combobox.model().findItems(option) model_index = self._combobox.findText(option) if model_index != -1: #model_index = self._combobox.model().indexFromItem(item[0]).row() self._combobox.setCurrentIndex(model_index) @property def selected_index(self): return self._combobox.currentData(Qt.UserRole) @selected_index.setter def selected_index(self,index): if index != self.selected_index: model_index = self._combobox.findData(index,Qt.UserRole) if model_index != -1: self._combobox.setCurrentIndex(model_index) else: raise RuntimeError('Index {index} not found!'.format(index=index))
[docs] def block_combobox_signals(self): return self._combobox.blockSignals(True)
[docs] def unblock_combobox_signals(self): return self._combobox.blockSignals(False)
# The event filter that pops up a context menu on a right click, even when the button is disabled
[docs] def eventFilter(self, obj, event): if event.type() == QEvent.MouseButtonRelease and event.button() == Qt.RightButton: menu = QMenu(self) menu.addAction("Lock" if self._combobox.isEnabled() else "Unlock") menu.triggered.connect(self._menu_triggered) menu.popup(self.mapToGlobal(event.pos())) # pass scrollwheel events of disabled buttons through to the parent # code adapted from: http://www.qtforum.org/article/28540/disabled-widgets-and-wheel-events.html elif obj and not obj.isEnabled() and event.type() == QEvent.Wheel and QT_ENV != PYQT5: newEvent = QWheelEvent(obj.mapToParent(event.pos()), event.globalPos(), event.delta(), event.buttons(), event.modifiers(), event.orientation()) QApplication.instance().postEvent(obj.parent(), newEvent) return True return QPushButton.eventFilter(self, obj, event)
# This method is called whenever an entry in the context menu is clicked def _menu_triggered(self,action): if action.text() == "Lock": self.lock() elif action.text() == "Unlock": self.unlock() # This method locks (disables) the widget, and if the widget has a parent EO object, notifies it of the lock
[docs] def lock(self,notify_eo=True): self._combobox.setEnabled(False) self._lock_action.setText("Unlock") if self._EO is not None and notify_eo: self._EO.lock()
# This method unlocks (enables) the widget, and if the widget has a parent EO object, notifies it of the unlock
[docs] def unlock(self,notify_eo=True): self._combobox.setEnabled(True) self._lock_action.setText("Lock") if self._EO is not None and notify_eo: self._EO.unlock()
# A simple test! if __name__ == '__main__': qapplication = QApplication(sys.argv) window = QWidget() layout = QVBoxLayout(window) test_options = {'option 1':{'index':0,'tooltip':"Option 1 Description"}, 'option 2':{'index':1,'tooltip':"Option 2 Description"}, 'option 3':2} test_model = QStandardItemModel() for key,val in test_options.items(): item = QStandardItem(key) if type(val) != dict: item.setData(val,Qt.UserRole) else: item.setData(val['index'],Qt.UserRole) item.setData(val['tooltip'],Qt.ToolTipRole) test_model.appendRow(item) combobox = EnumOutput('Enumerate',display_name='Test Name', horizontal_alignment=True) layout.addWidget(combobox) combobox.set_combobox_model(test_model) window.show() sys.exit(qapplication.exec_())