class LeapFlow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.controller = Controller() self.listener = LeapListener(self) self.controller.add_listener(self.listener) self.mode = "gallery" self.scroll = False self.direction = "" self.direction_x = 0 self.scroll_velocity = 0 self.current_index = 0 # List containing images for the gallery self.list_view = QListWidget() self.list_view.setFlow(0) self.list_view.setHorizontalScrollMode(1) self.list_view.setMouseTracking(True) self.list_view.itemClicked.connect(self.show_image) # Setting the style of the ListView, background, item selected, etc self.list_view.setStyleSheet( """ QListWidget::item:hover {background: transparent;} QListWidget::item:disabled:hover {background: transparent;} QListWidget::item:hover:!active {background: transparent;} QListWidget::item:selected:active {background: transparent;} QListWidget::item:selected:!active {background: transparent;} QListWidget::item:selected:disabled {background: transparent;} QListWidget::item:selected:!disabled {background: transparent;} QListWidget {background: #2C3539} """ ) # Image viewer self.scene = QGraphicsScene() self.viewer = QGraphicsView(self.scene) self.stackedWidget = QStackedWidget() self.stackedWidget.addWidget(self.list_view) self.stackedWidget.addWidget(self.viewer) self.setCentralWidget(self.stackedWidget) self.resize(500, 400) self.showMaximized() scan = ScanLibrary("/home/chris/Example") threads.append(scan) self.connect(scan, SIGNAL(scan.signal), self.add_images_to_list) scan.start() self.connect(self, SIGNAL("scrollChanged(bool)"), self.scroll_view) def setScroll(self, scroll): """Emit signal to scroll the view""" if self.scroll != scroll: self.scroll = scroll self.emit(SIGNAL("scrollChanged(bool)"), scroll) def scroll_view(self): """Scroll the view based on scroll velocity and direction""" x = self.direction_x * self.scroll_velocity / 100 bar_x = self.list_view.horizontalScrollBar().value() self.list_view.horizontalScrollBar().setValue(bar_x + x) def add_images_to_list(self): """To add a widget to the listview you must add a QListWidgetItem and replace with your widget""" for image in library: item = QListWidgetItem() pixmap = QPixmap.fromImage(QImage(library[image])) label = QLabel() label.setPixmap(pixmap.scaled(600, 400)) item.setSizeHint(label.sizeHint()) item.setData(0, library[image]) self.list_view.addItem(item) self.list_view.setItemWidget(item, label) def show_image(self, item): """"Display the selected image""" self.current_index = self.list_view.indexFromItem(item).row() self.scene.addPixmap((QPixmap.fromImage(QImage(item.text()))).scaled(self.viewer.size())) self.stackedWidget.setCurrentIndex(1) self.mode = "viewer" def previous_image(self): """Load previous image""" if self.current_index - 1 >= 0: self.current_index -= 1 self.load_image() def next_image(self): """Load next image""" if self.current_index + 1 <= len(library.keys()) - 1: self.current_index += 1 self.load_image() def load_image(self): """Load the image in self.current_index""" self.scene.addPixmap(QPixmap.fromImage(QImage(library[library.keys()[self.current_index]])))
class OWMoleculeVisualizer(OWWidget): settingsList = ["colorFragmets", "showFragments"] contextHandlers = { "": DomainContextHandler("", [ ContextField("selected_title_indices"), ContextField("moleculeTitleAttributeList", (DomainContextHandler.List + DomainContextHandler.SelectedRequired + DomainContextHandler.IncludeMetaAttributes), selected="selectedMoleculeTitleAttrs"), ContextField( "smiles_var", DomainContextHandler.Required + DomainContextHandler.IncludeMetaAttributes) ], maxAttributesToPickle=1000) } def __init__(self, parent=None, signalManager=None, title="Molecule visualizer"): super(OWMoleculeVisualizer, self).__init__(parent, signalManager, title) self.colorFragments = 1 self.showFragments = 0 self.selectedFragment = "" self.moleculeSmiles = [] self.fragmentSmiles = [] self.defFragmentSmiles = [] self.smiles_var = 0 self.moleculeTitleAttr = 0 self.moleculeTitleAttributeList = [] self.selectedMoleculeTitleAttrs = [] self.fragmentSmilesAttr = 0 self.imageSize = 200 self.numColumns = 4 self.commitOnChange = 0 ## GUI box = OWGUI.widgetBox(self.controlArea, "Info", addSpace=True) self.infoLabel = OWGUI.label(box, self, "Chemicals:") box = OWGUI.radioButtonsInBox(self.controlArea, self, "showFragments", ["Show molecules", "Show fragments"], "Show", callback=self.updateitems) self.showFragmentsRadioButton = box.buttons[-1] self.markFragmentsCheckBox = OWGUI.checkBox(box, self, "colorFragments", "Mark fragments", callback=self._update) box.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)) OWGUI.separator(self.controlArea) self.moleculeSmilesCombo = OWGUI.comboBox(self.controlArea, self, "smiles_var", "Molecule SMILES Attribute", callback=self.updateitems) self.moleculeSmilesCombo.box.setSizePolicy( QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)) self.smiles_var_model = VariableListModel(parent=self) self.moleculeSmilesCombo.setModel(self.smiles_var_model) OWGUI.separator(self.controlArea) box = OWGUI.widgetBox(self.controlArea, "Molecule Title Attributes", addSpace=True) self.title_var_view = QListView( selectionMode=QListView.ExtendedSelection) self.title_var_model = VariableListModel(parent=self) self.title_var_view.setModel(self.title_var_model) self.title_var_view.selectionModel().selectionChanged.connect( self._title_selection_changed) box.layout().addWidget(self.title_var_view) OWGUI.separator(self.controlArea) self.fragmentSmilesCombo = OWGUI.comboBox( self.controlArea, self, "fragmentSmilesAttr", "Fragment SMILES Attribute", callback=self.updateFragmentsListBox) self.fragmentSmilesCombo.setModel(VariableListModel(parent=self)) self.fragmentSmilesCombo.box.setSizePolicy( QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)) OWGUI.separator(self.controlArea) box = OWGUI.spin(self.controlArea, self, "imageSize", 50, 500, 10, box="Image Size", callback=self._image_size_changed) box.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)) OWGUI.separator(self.controlArea) box = OWGUI.widgetBox(self.controlArea, "Selection", addSpace=True) OWGUI.checkBox(box, self, "commitOnChange", "Commit on change") self.selectMarkedMoleculesButton = OWGUI.button( box, self, "Select &matched molecules", self.select_marked) OWGUI.button(box, self, "&Commit", callback=self.commit, default=True) OWGUI.separator(self.controlArea) OWGUI.rubber(self.controlArea) spliter = QSplitter(Qt.Vertical) self.scrollArea = ScrollArea(spliter) self.grid = GridWidget() self.grid.selectionChanged.connect(self._on_selection_changed) self.scrollArea.setWidget(self.grid) self.scrollArea.setWidgetResizable(True) self.mainArea.layout().addWidget(spliter) if pybel: self.listBox = QListWidget(spliter) else: self.listBox = QListWidget(None) self.listBox.setHidden(True) self.listBox.itemClicked.connect(self.fragmentSelection) self.fragmentSmilesCombo.box.setDisabled(not pybel) self.data = None self.data_subset = [] self.fragment_data = None self.resize(800, 600) self.listBox.setMaximumHeight(150) self.fragmentSmilesCombo.setDisabled(True) self.selectMarkedMoleculesButton.setDisabled(True) self.markFragmentsCheckBox.setDisabled(True) self.showFragmentsRadioButton.setDisabled(True) self.loadSettings() if not pybel: self.showFragments = 0 self.warning( 10, "Pybel module not installed. To view molecule fragments\n" "please install openbabel python extension.") self.__loop = None def setMoleculeTable(self, data): self.closeContext() self.clear() self.data = data if data is not None: all_vars = data.domain.variables + data.domain.get_metas().values() text_vars = filter( lambda v: isinstance(v, (Orange.feature.Discrete, Orange. feature.String)), all_vars) var_scored = score_smiles_variables(data, text_vars) self.smiles_var_model[:] = [var for var, _ in var_scored] self.smiles_var = max(range(len(var_scored)), key=lambda i: var_scored[i][1]) self.title_var_model[:] = all_vars self.setFragmentSmilesCombo() self.updateFragmentsListBox() if self.data_subset: try: self.data_subset = self.data_subset.select( self.data.domain) except Exception: self.data_subset = [] self.openContext("", data) else: self.defFragmentSmiles = [] if not self.fragmentSmilesAttr: self.listBox.clear() self.openContext("", data) self.send("Selected Molecules", None) def setMoleculeSubset(self, data): self.data_subset = data try: self.data_subset = self.data_subset.select(self.data.domain) except Exception: self.data_subset = [] def setFragmentTable(self, data): self.fragment_data = data if data is not None: self.setFragmentSmilesCombo() self.updateFragmentsListBox() self.selectedFragment = "" else: self.setFragmentSmilesCombo() self.updateFragmentsListBox() self.fragmentSmilesCombo.setEnabled(data is not None) def handleNewSignals(self): self.updateitems() def clear(self): self.smiles_var_model[:] = [] self.title_var_model[:] = [] self.fragmentSmilesCombo.clear() self.grid.clear() self._widgets = [] self._items = [] if self.__loop is not None: self.__loop.close() self.__loop = None def cleargrid(self): self.grid.clear() self._widgets = [] def _update_titles(self): if self.data is None: return title_vars = [ self.title_var_model[ind.row()] for ind in self.title_var_view.selectedIndexes() ] for item, widget in zip(self._items, self._widgets): inst = self.data[item.index] text = " / ".join(map(str, (inst[var] for var in title_vars))) widget.label.setText(text) def setFragmentSmilesCombo(self): if self.fragment_data: candidates = score_smiles_variables(self.fragment_data) else: candidates = [] self.fragmentSmilesCombo.model()[:] = [v for v, _ in candidates] if self.fragmentSmilesAttr > len(candidates): self.fragmentSmilesAttr = 0 def updateFragmentsListBox(self): if pybel is None: return fragvars = self.fragmentSmilesCombo.model() if 0 <= self.fragmentSmilesAttr < len(fragvars): fvar = fragvars[self.fragmentSmilesAttr] else: fvar = None if fvar: frags = [ str(e[fvar]) for e in self.fragment_data if not e[fvar].is_special() ] self.fragmentSmiles = [""] + frags else: self.fragmentSmiles = [""] + self.defFragmentSmiles self.listBox.clear() self.listBox.addItems(self.fragmentSmiles) self.showFragmentsRadioButton.setDisabled( len(self.fragmentSmiles) == 1) self.markFragmentsCheckBox.setDisabled(len(self.fragmentSmiles) == 1) self.selectMarkedMoleculesButton.setDisabled(True) def fragmentSelection(self, item): if pybel is None: return index = self.listBox.indexFromItem(item).row() if index == -1: index = 0 self.selectedFragment = self.fragmentSmiles[index] self.selectMarkedMoleculesButton.setEnabled(bool( self.selectedFragment)) self.markFragmentsCheckBox.setEnabled(bool(self.selectedFragment)) if not self.showFragments and self.colorFragments: self._update() def _title_text(self, index): title_vars = [ self.title_var_model[ind.row()] for ind in self.title_var_view.selectedIndexes() ] inst = self.data[index] return " / ".join(map(str, (inst[var] for var in title_vars))) def _items_from_var(self, var): if self.data is None: return None values = [(i, str(inst[var])) for i, inst in enumerate(self.data) if not inst[var].is_special()] return [ Item(i, smiles, *self._parse_smiles(smiles)) for i, smiles in values ] def _parse_smiles(self, smiles): try: return (OK, molecule_from_smiles(smiles)) except Exception: return (ParseError, None) def updateitems(self): if self.showFragments and self.fragmentSmiles: values = [(None, frag) for frag in self.fragmentSmiles[1:]] items = [ Item(i, smiles, *self._parse_smiles(smiles)) for i, smiles in values ] else: smilesvar = self.smiles_var_model[self.smiles_var] items = self._items_from_var(smilesvar) self._items = items self.setupgrid() def setupgrid(self): self.cleargrid() layout = self.grid widgets = [] for item in self._items: thumb = ThumbnailWidget(self.grid) thumb.setImageSize(self.imageSize, self.imageSize) if item.index is not None: text = self._title_text(item.index) else: text = "" thumb.label.setText(text) widgets.append(thumb) layout.appendWidget(thumb) self._widgets = widgets self.infoLabel.setText("Chemicals %i" % len(self._items)) self._update() def __update_items(self, items, widgets, pattern=None): for i, item, widget in zip(range(len(items)), items, widgets): if item.status != ParseError: if pattern is not None: emb = substructure_embedding(item.molecule, pattern) emb = reduce(list.__iadd__, emb, []) svg = molecule_to_svg_with_substructure(item.molecule, emb) else: svg = molecule_to_svg(item.molecule) else: svg = "" widget.setData(svg) widget.setEnabled(True) yield i * 100.0 / len(items) def _update(self): if self.showFragments and self.fragmentSmiles: loop = self.__update_items(self._items, self._widgets) elif self.colorFragments and self.selectedFragment: pattern = pybel.Smarts(self.selectedFragment) loop = self.__update_items(self._items, self._widgets, pattern) else: loop = self.__update_items(self._items, self._widgets) self.__schedule(loop) def __schedule(self, coroutine): if self.__loop is not None: self.progressBarFinished() self.__loop.close() self.__loop = None self.__loop = coroutine self.progressBarInit() QTimer.singleShot(0, self.__loop_update) @Slot() def __loop_update(self): if self.__loop is None: return try: progress = next(self.__loop) except StopIteration: self.__loop = None self.progressBarFinished() else: self.progressBarSet(progress) QTimer.singleShot(0, self.__loop_update) def _title_selection_changed(self): self._update_titles() def _image_size_changed(self): for widget in self._widgets: widget.setImageSize(self.imageSize, self.imageSize) self.grid.layout().invalidate() def select_marked(self): if not pybel: return if not self.showFragments: pattern = pybel.Smarts(self.selectedFragment) for item, widget in zip(self._items, self._widgets): if item.status != ParseError: emb = substructure_embedding(item.molecule, pattern) widget.setSelected(bool(emb)) else: widget.setSelected(False) if self.commitOnChange: self.commit() def _on_selection_changed(self): if self.commitOnChange: self.commit() def commit(self): if self.showFragments: svar = self.smiles_var_model[self.smiles_var] items = self._items_from_var(svar) frags = [ item for item, w in zip(self._items, self._widgets) if w.selected ] patterns = [pybel.Smarts(item.smiles) for item in frags] def test(molecule, patterns): return any( bool(substructure_embedding(molecule, patt)) for patt in patterns) matched = filter( lambda item: item.status != ParseError and test( item.molecule, patterns), items) instances = [self.data[item.index] for item in matched] if instances: table = Orange.data.Table(instances) self.send("Selected Molecules", table) else: self.send("Selected Molecules", None) else: items = [ item for item, w in zip(self._items, self._widgets) if w.selected ] instances = [self.data[item.index] for item in items] if instances: table = Orange.data.Table(instances) self.send("Selected Molecules", table) else: self.send("Selected Molecules", None) def onDeleteWidget(self): OWWidget.onDeleteWidget(self) if self.__loop is not None: self.__loop.close() self.__loop = None
class SeriesPreview(QDialog): def __init__(self, parent=None): super(SeriesPreview, self).__init__(parent) self.data = None self.workingSet = None self.list = QListWidget() self.cancel = QPushButton('Close') self.apply = QPushButton('Update') self.layout = QGridLayout() self.layout.addWidget(self.list, 0, 0, 1, 2) self.layout.addWidget(self.apply, 1, 0) self.layout.addWidget(self.cancel, 1, 1) self.setLayout(self.layout) self.initComponents() self.initActions() def initComponents(self): self.setWindowFlags(Qt.Tool) self.setWindowTitle("Time series") self.setStyleSheet('''QPushButton { color: #333; border: 1px solid #555; border-radius: 11px; padding: 2px; background: qradialgradient(cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4, radius: 1.35, stop: 0 #fff, stop: 1 #888); min-width: 80px; } QPushButton:hover { color: #fff; background: qradialgradient(cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4, radius: 1.35, stop: 0 #fff, stop: 1 #bbb);} QPushButton:pressed { background: qradialgradient(cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1, radius: 1.35, stop: 0 #fff, stop: 1 #ddd);} QPushButton:checked { background: qradialgradient(cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1, radius: 1.35, stop: 0 #fff, stop: 1 #ddd);} QListView::focus { border: 2px solid black; border-radius: 6px; } QScrollBar:vertical { width: 20px; border: 1px solid grey; border-radius: 6px; background-color: transparent; margin: 28px 0 28px 0; } QScrollBar::add-line:vertical { background: transparent; height: 32px; subcontrol-position: bottom; subcontrol-origin: margin; } QScrollBar::sub-line:vertical { background: transparent; height: 32px; subcontrol-position: top; subcontrol-origin: margin; } QScrollBar::up-arrow:vertical { width: 20px; height: 32px; background: transparent; image: url(../res/icons/arrow_up.png); } QScrollBar::up-arrow:hover { bottom: 2px; } QScrollBar::down-arrow:vertical { width: 20px; height: 32px; background: transparent; image: url(../res/icons/arrow_down.png); } QScrollBar::down-arrow:hover { top: 2px; } QScrollBar::handle:vertical { border-radius: 6px; background: url(../res/icons/handle.png) 0% center no-repeat; background-color: white; min-height: 32px; } QScrollBar::handle:hover { background: url(../res/icons/handle_hover.png) 0% center no-repeat; background-color: white; border: 1px solid gray; }''') self.list.setAlternatingRowColors(True) self.list.setStyleSheet('''QListView::item:selected:active { background: qlineargradient(x1: 1, y1: 0, x2: 0, y2: 3, stop: 0 #cbdaf1, stop: 1 #bfcde4); } QListView::item { border: 1px solid #d9d9d9; border-top-color: transparent; border-bottom-color: transparent; } QListView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1); border: 1px solid #bfcde4; }''') self.list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.list.setContextMenuPolicy(Qt.ActionsContextMenu) def initActions(self): self.apply.clicked.connect(self.applyChanges) self.cancel.clicked.connect(self.close) self.list.itemDoubleClicked.connect(self.removeFromList) self.list.addAction(QAction('&Remove selected', self, triggered=self.removeItems)) #--- actions ---# def updateData(self, data): self.data = data self.workingSet = data[0][:] self.updateList() def updateList(self): self.list.clear() for item in self.workingSet: item = QListWidgetItem(str(item)) item.setTextAlignment(Qt.AlignCenter) self.list.addItem(item) def applyChanges(self): self.data = (self.workingSet, self.data[1]) def removeFromList(self, item): self.workingSet.remove(float(item.text())) self.list.takeItem(self.list.indexFromItem(item).row()) def removeItems(self): for item in self.list.selectedItems(): self.workingSet.remove(float(item.text())) self.list.takeItem(self.list.indexFromItem(item).row())
class LeapFlow (QMainWindow): def __init__ (self): QMainWindow.__init__ (self) self.controller = Controller () self.listener = LeapListener (self) self.controller.add_listener (self.listener) self.mode = "gallery" self.scroll = False self.direction = "" self.direction_x = 0 self.scroll_velocity = 0 self.current_index = 0 # List containing images for the gallery self.list_view = QListWidget () self.list_view.setFlow (0) self.list_view.setHorizontalScrollMode (1) self.list_view.setMouseTracking (True) self.list_view.itemClicked.connect (self.show_image) # Setting the style of the ListView, background, item selected, etc self.list_view.setStyleSheet (""" QListWidget::item:hover {background: transparent;} QListWidget::item:disabled:hover {background: transparent;} QListWidget::item:hover:!active {background: transparent;} QListWidget::item:selected:active {background: transparent;} QListWidget::item:selected:!active {background: transparent;} QListWidget::item:selected:disabled {background: transparent;} QListWidget::item:selected:!disabled {background: transparent;} QListWidget {background: #2C3539} """) # Image viewer self.scene = QGraphicsScene () self.viewer = QGraphicsView (self.scene) self.stackedWidget = QStackedWidget () self.stackedWidget.addWidget (self.list_view) self.stackedWidget.addWidget (self.viewer) self.setCentralWidget (self.stackedWidget) self.resize (500, 400) self.showMaximized () scan = ScanLibrary ("/home/chris/Example") threads.append (scan) self.connect (scan, SIGNAL (scan.signal), self.add_images_to_list) scan.start () self.connect (self, SIGNAL ("scrollChanged(bool)"), self.scroll_view) def setScroll (self, scroll): """Emit signal to scroll the view""" if (self.scroll != scroll): self.scroll = scroll self.emit (SIGNAL("scrollChanged(bool)"), scroll) def scroll_view (self): """Scroll the view based on scroll velocity and direction""" x = self.direction_x * self.scroll_velocity / 100 bar_x = self.list_view.horizontalScrollBar ().value () self.list_view.horizontalScrollBar ().setValue (bar_x + x) def add_images_to_list (self): """To add a widget to the listview you must add a QListWidgetItem and replace with your widget""" for image in library: item = QListWidgetItem () pixmap = QPixmap.fromImage (QImage (library[image])) label = QLabel () label.setPixmap (pixmap.scaled (600, 400)) item.setSizeHint (label.sizeHint ()) item.setData (0, library[image]) self.list_view.addItem (item) self.list_view.setItemWidget (item, label) def show_image (self, item): """"Display the selected image""" self.current_index = self.list_view.indexFromItem (item).row () self.scene.addPixmap ((QPixmap.fromImage (QImage (item.text()))).scaled (self.viewer.size())) self.stackedWidget.setCurrentIndex (1) self.mode = "viewer" def previous_image (self): """Load previous image""" if self.current_index - 1 >= 0: self.current_index -= 1 self.load_image () def next_image (self): """Load next image""" if self.current_index + 1 <= len(library.keys ()) - 1: self.current_index += 1 self.load_image () def load_image (self): """Load the image in self.current_index""" self.scene.addPixmap (QPixmap.fromImage (QImage (library[library.keys()[self.current_index]])))
class ListParameterWidget(GenericParameterWidget): """Widget class for List parameter.""" def __init__(self, parameter, parent=None): """Constructor .. versionadded:: 2.2 :param parameter: A ListParameter object. :type parameter: ListParameter """ super(ListParameterWidget, self).__init__(parameter, parent) self._input = QListWidget() self._input.setSelectionMode(QAbstractItemView.MultiSelection) if self._parameter.maximum_item_count != \ self._parameter.minimum_item_count: tool_tip = 'Select between %d and %d items' % ( self._parameter.minimum_item_count, self._parameter.maximum_item_count) else: tool_tip = 'Select exactly %d items' % ( self._parameter.maximum_item_count) self._input.setToolTip(tool_tip) for opt in self._parameter.options_list: item = QListWidgetItem() item.setFlags(item.flags() | Qt.ItemIsEditable) item.setText(str(opt)) self._input.addItem(item) if opt in self._parameter.value: item.setSelected(True) self.inner_input_layout.addWidget(self._input) # override self._input_layout arrangement to make the label at the top # reset the layout self.input_layout.setParent(None) self.help_layout.setParent(None) self.label.setParent(None) self.inner_input_layout.setParent(None) self.input_layout = QVBoxLayout() self.input_layout.setSpacing(0) # put element into layout self.input_layout.addWidget(self.label) self.input_layout.addLayout(self.inner_input_layout) self.main_layout.addLayout(self.input_layout) self.main_layout.addLayout(self.help_layout) def raise_invalid_type_exception(self): message = 'Expecting element type of %s' % ( self._parameter.element_type.__name__) err = ValueError(message) return err def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A ListParameter from the current state of widget """ selected_value = [] for opt in self._input.selectedItems(): index = self._input.indexFromItem(opt) selected_value.append(self._parameter.options_list[index.row()]) try: self._parameter.value = selected_value except ValueError: err = self.raise_invalid_type_exception() raise err return self._parameter
class FileArgs(QtHelper.EnhancedQDialog, Logger.ClassLogger): """ File arguments dialog """ def __init__(self, dataArgs, parent=None): """ Dialog to fill arguments for the file probe @param dataArgs: @type dataArgs: @param parent: @type parent: """ super(FileArgs, self).__init__(parent) self.dataArgs = dataArgs self.createDialog() self.createConnections() self.loadDefaultData() def createDialog(self): """ Create qt dialog """ mainLayout = QHBoxLayout() dataLayout = QVBoxLayout() self.labelHelp = QLabel("Path of the file to retrieve:") self.lineEdit = QLineEdit() self.listBox = QListWidget() dataLayout.addWidget(self.labelHelp) dataLayout.addWidget(self.lineEdit) dataLayout.addWidget(self.listBox) buttonLayout = QVBoxLayout() self.addButton = QPushButton("Add", self) self.delButton = QPushButton("Remove", self) self.delButton.setEnabled(False) self.editButton = QPushButton("Edit", self) self.editButton.setEnabled(False) self.clearButton = QPushButton("Clear", self) self.okButton = QPushButton("Ok", self) self.cancelButton = QPushButton("Cancel", self) buttonLayout.addWidget(self.addButton) buttonLayout.addWidget(self.delButton) buttonLayout.addWidget(self.editButton) buttonLayout.addWidget(self.clearButton) buttonLayout.addWidget(self.okButton) buttonLayout.addWidget(self.cancelButton) mainLayout.addLayout(dataLayout) mainLayout.addLayout(buttonLayout) self.setLayout(mainLayout) self.setWindowTitle("File Probe > Arguments") def createConnections(self): """ Create qt connections """ self.okButton.clicked.connect(self.accept) self.cancelButton.clicked.connect(self.reject) self.addButton.clicked.connect(self.addItem) self.delButton.clicked.connect(self.delItem) self.editButton.clicked.connect(self.editItem) self.clearButton.clicked.connect(self.clearList) self.listBox.itemClicked.connect(self.onItemSelected) def clearList(self): """ Clear the list """ self.listBox.clear() def onItemSelected(self, itm): """ Called when an item is selected """ self.delButton.setEnabled(True) self.editButton.setEnabled(True) def editItem(self): """ Edit the selected item """ self.delButton.setEnabled(False) self.editButton.setEnabled(False) # retrieve value to put it in the line edit and then remove item model = self.listBox.model() for selectedItem in self.listBox.selectedItems(): qIndex = self.listBox.indexFromItem(selectedItem) if sys.version_info > (3, ): self.lineEdit.setText(model.data(qIndex)) else: self.lineEdit.setText(model.data(qIndex).toString()) model.removeRow(qIndex.row()) def delItem(self): """ Delete the selected item """ self.delButton.setEnabled(False) self.editButton.setEnabled(False) # remove item model = self.listBox.model() for selectedItem in self.listBox.selectedItems(): qIndex = self.listBox.indexFromItem(selectedItem) model.removeRow(qIndex.row()) def addItem(self): """ Add item """ txt = self.lineEdit.text() if txt != '': self.listBox.insertItem(0, txt) self.lineEdit.setText('') def loadDefaultData(self): """ Load the default data """ try: if len(self.dataArgs) == 0: return dat = eval(self.dataArgs) if 'files' in dat: list_files = dat['files'] self.listBox.insertItems(0, list_files) except Exception as e: self.error(e) def getArgs(self): """ Returns arguments Examples: {'files': [ '/etc/init.d/ntpd', '/root/wmi-1.3.14-2.el5.art.x86_64.rpm' ] } """ listFiles = [] model = self.listBox.model() # iterate all items in a QListWidget for index in xrange(self.listBox.count()): itm = self.listBox.item(index) qIndex = self.listBox.indexFromItem(itm) if sys.version_info > (3, ): listFiles.append(model.data(qIndex)) else: listFiles.append(str(model.data(qIndex).toString())) ret = {'files': listFiles} if len(listFiles) == 0: ret = '' return str(ret)
class InputListParameterWidget(GenericParameterWidget): """Widget class for List parameter.""" def __init__(self, parameter, parent=None): """Constructor .. versionadded:: 2.2 :param parameter: A ListParameter object. :type parameter: InputListParameter """ super(InputListParameterWidget, self).__init__(parameter, parent) # value cache for self._parameter.value # copy the list so the original is unaffected self._value_cache = list(self._parameter.value) self._input = QListWidget() self._input.setSelectionMode(QAbstractItemView.SingleSelection) if self._parameter.maximum_item_count != \ self._parameter.minimum_item_count: tool_tip = 'Select between %d and %d items' % ( self._parameter.minimum_item_count, self._parameter.maximum_item_count) else: tool_tip = 'Select exactly %d items' % ( self._parameter.maximum_item_count) self._input.setToolTip(tool_tip) # arrange widget self._insert_item_input = QLineEdit() vbox_layout = QVBoxLayout() hbox_layout = QHBoxLayout() self._input_add_button = QPushButton('Add') self._input_remove_button = QPushButton('Remove') # arrange line edit, add button, remove button in horizontal layout hbox_layout.addWidget(self._insert_item_input) hbox_layout.addWidget(self._input_add_button) hbox_layout.addWidget(self._input_remove_button) # arrange vertical layout vbox_layout.addLayout(hbox_layout) vbox_layout.addWidget(self._input) self._inner_input_layout.addLayout(vbox_layout) # override self._input_layout arrangement to make the label at the top # reset the layout self._input_layout.setParent(None) self._help_layout.setParent(None) self._label.setParent(None) self._inner_input_layout.setParent(None) self._input_layout = QVBoxLayout() self._input_layout.setSpacing(0) # put element into layout self._input_layout.addWidget(self._label) self._input_layout.addLayout(self._inner_input_layout) self._main_layout.addLayout(self._input_layout) self._main_layout.addLayout(self._help_layout) # connect handler # noinspection PyUnresolvedReferences self._input_add_button.clicked.connect(self.on_add_button_click) # noinspection PyUnresolvedReferences self._input_remove_button.clicked.connect(self.on_remove_button_click) # noinspection PyUnresolvedReferences self._insert_item_input.returnPressed.connect( self._input_add_button.click) # noinspection PyUnresolvedReferences self._input.itemChanged.connect(self.on_row_changed) self.refresh_list() # init row add error handler self._add_row_error_handler = None @property def add_row_error_handler(self): """return error handler if user mistakenly add row of unexpected type :return: a function handler :rtype: () -> None """ return self._add_row_error_handler @add_row_error_handler.setter def add_row_error_handler(self, value): """Set error handler to handle user mistakenly add row of unexpected type """ self._add_row_error_handler = value def refresh_list(self): self._input.clear() if not self._parameter.ordering == InputListParameter.NotOrdered: self._value_cache.sort() if self._parameter.ordering == InputListParameter.DescendingOrder: self._value_cache.reverse() for opt in self._value_cache: item = QListWidgetItem() item.setText(str(opt)) item.setFlags(item.flags() | Qt.ItemIsEditable) self._input.addItem(item) def on_add_button_click(self): try: value = self._parameter.element_type( self._insert_item_input.text()) self._value_cache.append(value) self.refresh_list() except ValueError: err = self.raise_invalid_type_exception() if self.add_row_error_handler is not None: self.add_row_error_handler(err) else: raise err def on_remove_button_click(self): for opt in self._input.selectedItems(): index = self._input.indexFromItem(opt) del self._value_cache[index.row()] self.refresh_list() def on_row_changed(self, item): try: index = self._input.indexFromItem(item).row() prev_value = self._value_cache[index] self._value_cache[index] = self._parameter.element_type( item.text()) self.refresh_list() except ValueError: item.setText(str(prev_value)) self.raise_invalid_type_exception() def raise_invalid_type_exception(self): message = 'Expecting element type of %s' % ( self._parameter.element_type.__name__) err = ValueError(message) return err def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A ListParameter from the current state of widget """ try: self._parameter.value = self._value_cache except ValueError: err = self.raise_invalid_type_exception() raise err return self._parameter
class ListParameterWidget(GenericParameterWidget): """Widget class for List parameter.""" def __init__(self, parameter, parent=None): """Constructor .. versionadded:: 2.2 :param parameter: A ListParameter object. :type parameter: ListParameter """ super(ListParameterWidget, self).__init__(parameter, parent) self._input = QListWidget() self._input.setSelectionMode(QAbstractItemView.MultiSelection) if self._parameter.maximum_item_count != \ self._parameter.minimum_item_count: tool_tip = 'Select between %d and %d items' % ( self._parameter.minimum_item_count, self._parameter.maximum_item_count) else: tool_tip = 'Select exactly %d items' % ( self._parameter.maximum_item_count) self._input.setToolTip(tool_tip) for opt in self._parameter.options_list: item = QListWidgetItem() item.setFlags(item.flags() | Qt.ItemIsEditable) item.setText(str(opt)) self._input.addItem(item) if opt in self._parameter.value: item.setSelected(True) self._inner_input_layout.addWidget(self._input) # override self._input_layout arrangement to make the label at the top # reset the layout self._input_layout.setParent(None) self._help_layout.setParent(None) self._label.setParent(None) self._inner_input_layout.setParent(None) self._input_layout = QVBoxLayout() self._input_layout.setSpacing(0) # put element into layout self._input_layout.addWidget(self._label) self._input_layout.addLayout(self._inner_input_layout) self._main_layout.addLayout(self._input_layout) self._main_layout.addLayout(self._help_layout) def raise_invalid_type_exception(self): message = 'Expecting element type of %s' % ( self._parameter.element_type.__name__) err = ValueError(message) return err def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A ListParameter from the current state of widget """ selected_value = [] for opt in self._input.selectedItems(): index = self._input.indexFromItem(opt) selected_value.append(self._parameter.options_list[index.row()]) try: self._parameter.value = selected_value except ValueError: err = self.raise_invalid_type_exception() raise err return self._parameter
class OWMoleculeVisualizer(OWWidget): settingsList = ["colorFragmets", "showFragments"] contextHandlers = { "": DomainContextHandler( "", [ContextField("selected_title_indices"), ContextField("moleculeTitleAttributeList", (DomainContextHandler.List + DomainContextHandler.SelectedRequired + DomainContextHandler.IncludeMetaAttributes), selected="selectedMoleculeTitleAttrs"), ContextField("smiles_var", DomainContextHandler.Required + DomainContextHandler.IncludeMetaAttributes)], maxAttributesToPickle=1000) } def __init__(self, parent=None, signalManager=None, title="Molecule visualizer"): super(OWMoleculeVisualizer, self).__init__(parent, signalManager, title) self.colorFragments = 1 self.showFragments = 0 self.selectedFragment = "" self.moleculeSmiles = [] self.fragmentSmiles = [] self.defFragmentSmiles = [] self.smiles_var = 0 self.moleculeTitleAttr = 0 self.moleculeTitleAttributeList = [] self.selectedMoleculeTitleAttrs = [] self.fragmentSmilesAttr = 0 self.imageSize = 200 self.numColumns = 4 self.commitOnChange = 0 ## GUI box = OWGUI.widgetBox(self.controlArea, "Info", addSpace=True) self.infoLabel = OWGUI.label(box, self, "Chemicals:") box = OWGUI.radioButtonsInBox( self.controlArea, self, "showFragments", ["Show molecules", "Show fragments"], "Show", callback=self.updateitems ) self.showFragmentsRadioButton = box.buttons[-1] self.markFragmentsCheckBox = OWGUI.checkBox( box, self, "colorFragments", "Mark fragments", callback=self._update ) box.setSizePolicy( QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)) OWGUI.separator(self.controlArea) self.moleculeSmilesCombo = OWGUI.comboBox( self.controlArea, self, "smiles_var", "Molecule SMILES Attribute", callback=self.updateitems ) self.moleculeSmilesCombo.box.setSizePolicy( QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum) ) self.smiles_var_model = VariableListModel(parent=self) self.moleculeSmilesCombo.setModel(self.smiles_var_model) OWGUI.separator(self.controlArea) box = OWGUI.widgetBox(self.controlArea, "Molecule Title Attributes", addSpace=True) self.title_var_view = QListView( selectionMode=QListView.ExtendedSelection ) self.title_var_model = VariableListModel(parent=self) self.title_var_view.setModel(self.title_var_model) self.title_var_view.selectionModel().selectionChanged.connect( self._title_selection_changed ) box.layout().addWidget(self.title_var_view) OWGUI.separator(self.controlArea) self.fragmentSmilesCombo = OWGUI.comboBox( self.controlArea, self, "fragmentSmilesAttr", "Fragment SMILES Attribute", callback=self.updateFragmentsListBox ) self.fragmentSmilesCombo.setModel(VariableListModel(parent=self)) self.fragmentSmilesCombo.box.setSizePolicy( QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum) ) OWGUI.separator(self.controlArea) box = OWGUI.spin(self.controlArea, self, "imageSize", 50, 500, 10, box="Image Size", callback=self._image_size_changed) box.setSizePolicy( QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)) OWGUI.separator(self.controlArea) box = OWGUI.widgetBox(self.controlArea, "Selection", addSpace=True) OWGUI.checkBox(box, self, "commitOnChange", "Commit on change") self.selectMarkedMoleculesButton = OWGUI.button( box, self, "Select &matched molecules", self.select_marked ) OWGUI.button(box, self, "&Commit", callback=self.commit, default=True) OWGUI.separator(self.controlArea) OWGUI.rubber(self.controlArea) spliter = QSplitter(Qt.Vertical) self.scrollArea = ScrollArea(spliter) self.grid = GridWidget() self.grid.selectionChanged.connect(self._on_selection_changed) self.scrollArea.setWidget(self.grid) self.scrollArea.setWidgetResizable(True) self.mainArea.layout().addWidget(spliter) if pybel: self.listBox = QListWidget(spliter) else: self.listBox = QListWidget(None) self.listBox.setHidden(True) self.listBox.itemClicked.connect(self.fragmentSelection) self.fragmentSmilesCombo.box.setDisabled(not pybel) self.data = None self.data_subset = [] self.fragment_data = None self.resize(800, 600) self.listBox.setMaximumHeight(150) self.fragmentSmilesCombo.setDisabled(True) self.selectMarkedMoleculesButton.setDisabled(True) self.markFragmentsCheckBox.setDisabled(True) self.showFragmentsRadioButton.setDisabled(True) self.loadSettings() if not pybel: self.showFragments = 0 self.warning(10, "Pybel module not installed. To view molecule fragments\n" "please install openbabel python extension.") self.__loop = None def setMoleculeTable(self, data): self.closeContext() self.clear() self.data = data if data is not None: all_vars = data.domain.variables + data.domain.get_metas().values() text_vars = filter( lambda v: isinstance(v, (Orange.feature.Discrete, Orange.feature.String)), all_vars) var_scored = score_smiles_variables(data, text_vars) self.smiles_var_model[:] = [var for var, _ in var_scored] self.smiles_var = max(range(len(var_scored)), key=lambda i: var_scored[i][1]) self.title_var_model[:] = all_vars self.setFragmentSmilesCombo() self.updateFragmentsListBox() if self.data_subset: try: self.data_subset = self.data_subset.select(self.data.domain) except Exception: self.data_subset = [] self.openContext("", data) else: self.defFragmentSmiles = [] if not self.fragmentSmilesAttr: self.listBox.clear() self.openContext("", data) self.send("Selected Molecules", None) def setMoleculeSubset(self, data): self.data_subset = data try: self.data_subset = self.data_subset.select(self.data.domain) except Exception: self.data_subset = [] def setFragmentTable(self, data): self.fragment_data = data if data is not None: self.setFragmentSmilesCombo() self.updateFragmentsListBox() self.selectedFragment = "" else: self.setFragmentSmilesCombo() self.updateFragmentsListBox() self.fragmentSmilesCombo.setEnabled(data is not None) def handleNewSignals(self): self.updateitems() def clear(self): self.smiles_var_model[:] = [] self.title_var_model[:] = [] self.fragmentSmilesCombo.clear() self.grid.clear() self._widgets = [] self._items = [] if self.__loop is not None: self.__loop.close() self.__loop = None def cleargrid(self): self.grid.clear() self._widgets = [] def _update_titles(self): if self.data is None: return title_vars = [self.title_var_model[ind.row()] for ind in self.title_var_view.selectedIndexes()] for item, widget in zip(self._items, self._widgets): inst = self.data[item.index] text = " / ".join(map(str, (inst[var] for var in title_vars))) widget.label.setText(text) def setFragmentSmilesCombo(self): if self.fragment_data: candidates = score_smiles_variables(self.fragment_data) else: candidates = [] self.fragmentSmilesCombo.model()[:] = [v for v, _ in candidates] if self.fragmentSmilesAttr > len(candidates): self.fragmentSmilesAttr = 0 def updateFragmentsListBox(self): if pybel is None: return fragvars = self.fragmentSmilesCombo.model() if 0 <= self.fragmentSmilesAttr < len(fragvars): fvar = fragvars[self.fragmentSmilesAttr] else: fvar = None if fvar: frags = [str(e[fvar]) for e in self.fragment_data if not e[fvar].is_special()] self.fragmentSmiles = [""] + frags else: self.fragmentSmiles = [""] + self.defFragmentSmiles self.listBox.clear() self.listBox.addItems(self.fragmentSmiles) self.showFragmentsRadioButton.setDisabled(len(self.fragmentSmiles) == 1) self.markFragmentsCheckBox.setDisabled(len(self.fragmentSmiles) == 1) self.selectMarkedMoleculesButton.setDisabled(True) def fragmentSelection(self, item): if pybel is None: return index = self.listBox.indexFromItem(item).row() if index == -1: index = 0 self.selectedFragment = self.fragmentSmiles[index] self.selectMarkedMoleculesButton.setEnabled(bool(self.selectedFragment)) self.markFragmentsCheckBox.setEnabled(bool(self.selectedFragment)) if not self.showFragments and self.colorFragments: self._update() def _title_text(self, index): title_vars = [self.title_var_model[ind.row()] for ind in self.title_var_view.selectedIndexes()] inst = self.data[index] return " / ".join(map(str, (inst[var] for var in title_vars))) def _items_from_var(self, var): if self.data is None: return None values = [(i, str(inst[var])) for i, inst in enumerate(self.data) if not inst[var].is_special()] return [Item(i, smiles, *self._parse_smiles(smiles)) for i, smiles in values] def _parse_smiles(self, smiles): try: return (OK, molecule_from_smiles(smiles)) except Exception: return (ParseError, None) def updateitems(self): if self.showFragments and self.fragmentSmiles: values = [(None, frag) for frag in self.fragmentSmiles[1:]] items = [Item(i, smiles, *self._parse_smiles(smiles)) for i, smiles in values] else: smilesvar = self.smiles_var_model[self.smiles_var] items = self._items_from_var(smilesvar) self._items = items self.setupgrid() def setupgrid(self): self.cleargrid() layout = self.grid widgets = [] for item in self._items: thumb = ThumbnailWidget(self.grid) thumb.setImageSize(self.imageSize, self.imageSize) if item.index is not None: text = self._title_text(item.index) else: text = "" thumb.label.setText(text) widgets.append(thumb) layout.appendWidget(thumb) self._widgets = widgets self.infoLabel.setText("Chemicals %i" % len(self._items)) self._update() def __update_items(self, items, widgets, pattern=None): for i, item, widget in zip(range(len(items)), items, widgets): if item.status != ParseError: if pattern is not None: emb = substructure_embedding(item.molecule, pattern) emb = reduce(list.__iadd__, emb, []) svg = molecule_to_svg_with_substructure(item.molecule, emb) else: svg = molecule_to_svg(item.molecule) else: svg = "" widget.setData(svg) widget.setEnabled(True) yield i * 100.0 / len(items) def _update(self): if self.showFragments and self.fragmentSmiles: loop = self.__update_items(self._items, self._widgets) elif self.colorFragments and self.selectedFragment: pattern = pybel.Smarts(self.selectedFragment) loop = self.__update_items(self._items, self._widgets, pattern) else: loop = self.__update_items(self._items, self._widgets) self.__schedule(loop) def __schedule(self, coroutine): if self.__loop is not None: self.progressBarFinished() self.__loop.close() self.__loop = None self.__loop = coroutine self.progressBarInit() QTimer.singleShot(0, self.__loop_update) @Slot() def __loop_update(self): if self.__loop is None: return try: progress = next(self.__loop) except StopIteration: self.__loop = None self.progressBarFinished() else: self.progressBarSet(progress) QTimer.singleShot(0, self.__loop_update) def _title_selection_changed(self): self._update_titles() def _image_size_changed(self): for widget in self._widgets: widget.setImageSize(self.imageSize, self.imageSize) self.grid.layout().invalidate() def select_marked(self): if not pybel: return if not self.showFragments: pattern = pybel.Smarts(self.selectedFragment) for item, widget in zip(self._items, self._widgets): if item.status != ParseError: emb = substructure_embedding(item.molecule, pattern) widget.setSelected(bool(emb)) else: widget.setSelected(False) if self.commitOnChange: self.commit() def _on_selection_changed(self): if self.commitOnChange: self.commit() def commit(self): if self.showFragments: svar = self.smiles_var_model[self.smiles_var] items = self._items_from_var(svar) frags = [item for item, w in zip(self._items, self._widgets) if w.selected] patterns = [pybel.Smarts(item.smiles) for item in frags] def test(molecule, patterns): return any(bool(substructure_embedding(molecule, patt)) for patt in patterns) matched = filter( lambda item: item.status != ParseError and test(item.molecule, patterns), items ) instances = [self.data[item.index] for item in matched] if instances: table = Orange.data.Table(instances) self.send("Selected Molecules", table) else: self.send("Selected Molecules", None) else: items = [item for item, w in zip(self._items, self._widgets) if w.selected] instances = [self.data[item.index] for item in items] if instances: table = Orange.data.Table(instances) self.send("Selected Molecules", table) else: self.send("Selected Molecules", None) def onDeleteWidget(self): OWWidget.onDeleteWidget(self) if self.__loop is not None: self.__loop.close() self.__loop = None