def __init__(self, var, parent=None, **kwargs): PyListModel.__init__(self, [], parent, **kwargs) self.wrap(var.values) self.colorPalette = OWColorPalette.ColorPaletteHSV(len(self)) self.connect(self, SIGNAL("columnsInserted(QModelIndex, int, int)"), self.updateColors) self.connect(self, SIGNAL("columnsRemoved(QModelIndex, int, int)"), self.updateColors)
def _setup_gui_values(self): self.values_edit = QListView() self.values_edit.setEditTriggers(QTreeView.CurrentChanged) self.values_model = PyListModel(flags=Qt.ItemIsSelectable | \ Qt.ItemIsEnabled | Qt.ItemIsEditable) self.values_edit.setModel(self.values_model) self.values_model.dataChanged.connect(self.on_values_changed) self.main_form.addRow("Values", self.values_edit)
def __init__(self, parent=None, signalManager=None, name="R Script"): OWWidget.__init__(self, parent, signalManager, name) self.inputs = [("in_data", ExampleTable, self.setData), ("in_distance", orange.SymMatrix, self.setDistance)] self.outputs = [("out_data", ExampleTable), ("out_distance", orange.SymMatrix), ("out_learner", orange.Learner), ("out_classifier", orange.Classifier)] self.in_data, self.in_distance = None, None self.scriptLibraryList = [RScript("New script", "x <- c(1,2,5)\ny <- c(2,1 6)\nplot(x,y)\n")] self.selectedScriptIndex = 0 self.lastDir = os.path.expanduser("~/script.R") self.loadSettings() self.defaultFont = QFont("Monaco") if sys.platform == "darwin" else QFont("Courier") self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) self.scriptEdit = RScriptEditor() self.splitter.addWidget(self.scriptEdit) self.console = RPy2Console({}, self) self.splitter.addWidget(self.console) self.splitter.setSizes([2,1]) self.libraryModel = PyListModel([], self, Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable) self.libraryModel.wrap(self.scriptLibraryList) self.infoBox = OWGUI.widgetLabel(OWGUI.widgetBox(self.controlArea, "Info", addSpace=True), "") self.infoBox.setText("<p>Execute R script</p>Input variables<li><ul>in_data</ul><ul>in_distance</ul></li>Output variables:<li><ul>out_data</ul></p/>") box = OWGUI.widgetBox(self.controlArea, "Library", addSpace=True) self.libraryWidget = LibraryWidget() self.libraryView = self.libraryWidget.view box.layout().addWidget(self.libraryWidget) self.libraryWidget.view.setItemDelegate(ScriptItemDelegate(self)) self.libraryWidget.setScriptModel(self.libraryModel) self.libraryWidget.setDocumentEditor(self.scriptEdit) box = OWGUI.widgetBox(self.controlArea, "Run") OWGUI.button(box, self, "Execute", callback=self.runScript, tooltip="Execute the script") OWGUI.rubber(self.controlArea) self.connect(self.libraryWidget.addScriptAction, SIGNAL("triggered()"), self.onAddNewScript) self.connect(self.libraryWidget.updateScriptAction, SIGNAL("triggered()"), self.onUpdateScript) self.connect(self.libraryWidget.removeScriptAction, SIGNAL("triggered()"), self.onRemoveScript) self.connect(self.libraryWidget.addScriptFromFile, SIGNAL("triggered()"), self.onAddScriptFromFile) self.connect(self.libraryWidget.saveScriptToFile, SIGNAL("triggered()"), self.onSaveScriptToFile) self.connect(self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onScriptSelection) self._cachedDocuments = {} self.resize(800, 600) QTimer.singleShot(30, self.initGrDevice)
def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'Python Script') self.inputs = [ ("in_data", Orange.data.Table, self.setExampleTable, Default), ("in_distance", Orange.misc.SymMatrix, self.setDistanceMatrix, Default), ("in_learner", Orange.core.Learner, self.setLearner, Default), ("in_classifier", Orange.core.Classifier, self.setClassifier, Default), ("in_object", object, self.setObject) ] self.outputs = [("out_data", Orange.data.Table), ("out_distance", Orange.misc.SymMatrix), ("out_learner", Orange.core.Learner), ("out_classifier", Orange.core.Classifier, Dynamic), ("out_object", object, Dynamic)] self.in_data = None self.in_distance = None self.in_learner = None self.in_classifier = None self.in_object = None self.auto_execute = False self.libraryListSource = [ Script("Hello world", "print 'Hello world'\n") ] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') OWGUI.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + "<li>".join(t[0] for t in self.outputs) + "</ul></p>") self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import a script from a file", self) save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) OWGUI.checkBox(self.runBox, self, "auto_execute", "Auto execute", tooltip=("Run the script automatically whenever " "the inputs to the widget change.")) self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'Python script') self.splitter.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitter.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.splitter.setSizes([2, 1]) if self.splitterState is not None: self.splitter.restoreState(QByteArray(self.splitterState)) self.splitter.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600)
class OWPythonScript(OWWidget): settingsList = [ "libraryListSource", "currentScriptIndex", "splitterState", "auto_execute" ] def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'Python Script') self.inputs = [ ("in_data", Orange.data.Table, self.setExampleTable, Default), ("in_distance", Orange.misc.SymMatrix, self.setDistanceMatrix, Default), ("in_learner", Orange.core.Learner, self.setLearner, Default), ("in_classifier", Orange.core.Classifier, self.setClassifier, Default), ("in_object", object, self.setObject) ] self.outputs = [("out_data", Orange.data.Table), ("out_distance", Orange.misc.SymMatrix), ("out_learner", Orange.core.Learner), ("out_classifier", Orange.core.Classifier, Dynamic), ("out_object", object, Dynamic)] self.in_data = None self.in_distance = None self.in_learner = None self.in_classifier = None self.in_object = None self.auto_execute = False self.libraryListSource = [ Script("Hello world", "print 'Hello world'\n") ] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') OWGUI.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + "<li>".join(t[0] for t in self.outputs) + "</ul></p>") self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import a script from a file", self) save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) OWGUI.checkBox(self.runBox, self, "auto_execute", "Auto execute", tooltip=("Run the script automatically whenever " "the inputs to the widget change.")) self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'Python script') self.splitter.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitter.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.splitter.setSizes([2, 1]) if self.splitterState is not None: self.splitter.restoreState(QByteArray(self.splitterState)) self.splitter.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600) def setExampleTable(self, et): self.in_data = et def setDistanceMatrix(self, dm): self.in_distance = dm def setLearner(self, learner): self.in_learner = learner def setClassifier(self, classifier): self.in_classifier = classifier def setObject(self, obj): self.in_object = obj def handleNewSignals(self): if self.auto_execute: self.execute() def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): select_row(self.libraryView, index) def onAddScript(self, *args): self.libraryList.append(Script("New script", "", 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): filename = QFileDialog.getOpenFileName( self, 'Open Python Script', os.path.expanduser("~/"), 'Python files (*.py)\nAll files(*.*)') filename = unicode(filename) if filename: name = os.path.basename(filename) self.libraryList.append( Script(name, open(filename, "rb").read(), 0, filename)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] select_row(self.libraryView, max(index - 1, 0)) def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script=0): if type(script) != Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = QTextDocument(self) doc.setDocumentLayout(QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) doc.modificationChanged[bool].connect(self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = unicode(self.text.toPlainText()) self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def onSpliterMoved(self, pos, ind): self.splitterState = str(self.splitter.saveState()) def saveScript(self): index = self.selectedScriptIndex() filename = os.path.expanduser("~/") if index is not None: script = self.libraryList[index] filename = script.sourceFileName or filename filename = QFileDialog.getSaveFileName( self, 'Save Python Script', filename, 'Python files (*.py)\nAll files(*.*)') self.codeFile = unicode(filename) if self.codeFile: fn = "" head, tail = os.path.splitext(self.codeFile) if not tail: fn = head + ".py" else: fn = self.codeFile f = open(fn, 'w') f.write(self.text.toPlainText()) f.close() def execute(self): self._script = str(self.text.toPlainText()) self.console.write("\nRunning script:\n") self.console.push("exec(_script)") self.console.new_prompt(sys.ps1) for out in self.outputs: signal = out[0] self.send(signal, getattr(self, signal, None))
class DiscreteVariableEditor(VariableEditor): """An editor widget for editing a discrete variable. Extends the :class:`VariableEditor` to enable editing of variables values. """ def setup_gui(self): layout = QVBoxLayout() self.setLayout(layout) self.main_form = QFormLayout() self.main_form.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) layout.addLayout(self.main_form) self._setup_gui_name() self._setup_gui_values() self._setup_gui_labels() def _setup_gui_values(self): self.values_edit = QListView() self.values_edit.setEditTriggers(QListView.DoubleClicked | \ QListView.EditKeyPressed) self.values_model = PyListModel(flags=Qt.ItemIsSelectable | \ Qt.ItemIsEnabled | Qt.ItemIsEditable) self.values_edit.setModel(self.values_model) self.values_model.dataChanged.connect(self.on_values_changed) self.main_form.addRow("Values", self.values_edit) def set_data(self, var): """Set the variable to edit """ VariableEditor.set_data(self, var) self.values_model.wrap([]) if var is not None: for v in var.values: self.values_model.append(v) def get_data(self): """Retrieve the modified variable """ name = str(self.name_edit.text()) labels = self.labels_model.get_dict() values = map(str, self.values_model) if not self.is_same(): var = type(self.var)(name, values=values) var.attributes.update(labels) self.var = var else: var = self.var return var def is_same(self): """Is the current model state the same as the input. """ values = map(str, self.values_model) return VariableEditor.is_same(self) and self.var.values == values def clear(self): """Clear the model state. """ VariableEditor.clear(self) self.values_model.wrap([]) @QtCore.Slot() def on_values_changed(self): self.maybe_commit()
def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'MultiData Python Script') self.inputs = [("in_data", ExampleTable, self.setExampleTable, Default + Multiple), ("in_distance", orange.SymMatrix, self.setDistanceMatrix), ("in_network", Orange.network.Graph, self.setNetwork), ("in_learners", orange.Learner, self.setLearner, Default + Multiple), ("in_classifiers", orange.Classifier, self.setClassifier, Default + Multiple), ("in_misc", object, self.setMisc, Default + Multiple)] self.outputs = [("out_data", ExampleTable), ("out_distance", orange.SymMatrix), ("out_network", Orange.network.Graph), ("out_learner", orange.Learner), ("out_classifier", orange.Classifier, Dynamic), ("out_test_results", Orange.evaluation.testing.ExperimentResults), ("out_misc", object)] self.in_data = [] self.in_data_dict = {} # TODO: switch to weakref? self.in_learners = [] self.in_learner_dict = {} self.in_classifiers = [] self.in_classifier_dict = {} self.in_misc = [] self.in_misc_dict = {} self.in_network = None self.in_distance = None self.codeFile = '' self.libraryListSource = [Script("Hello world", "print 'Hello world'\n")] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') label = OWGUI.label(self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + \ "<li>".join(t[0] for t in self.outputs) + "</ul></p>") self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) # self.libraryList.append(Script("Hello world", "print 'Hello world'\n")) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView() self.libraryView.setEditTriggers(QListView.DoubleClicked | QListView.EditKeyPressed) self.libraryView.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.connect(self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.pyqtConfigure(toolTip="Add a new script to the library") self.connect(action, SIGNAL("triggered()"), self.onAddScript) new_empty = QAction("Add a new empty script", action) new_from_file = QAction("Add a new script from a file", action) self.connect(new_empty, SIGNAL("triggered()"), self.onAddScript) self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) menu = QMenu(w) menu.addAction(new_empty) menu.addAction(new_from_file) # action.setMenu(menu) button = w.addAction(action) self.removeAction = action = QAction("-", self) action.pyqtConfigure(toolTip="Remove script from library") self.connect(action, SIGNAL("triggered()"), self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.pyqtConfigure(toolTip="Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) self.connect(action, SIGNAL("triggered()"), self.commitChangesToLibrary) b = w.addAction(action) # b.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) action = QAction("More", self) action.pyqtConfigure(toolTip="More actions") #, icon=self.style().standardIcon(QStyle.SP_ToolBarHorizontalExtensionButton)) self.openScriptFromFileAction = new_from_file = QAction("Import a script from a file", self) self.saveScriptToFile = save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) self.connect(save_to_file, SIGNAL("triggered()"), self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) b = w.addAction(action) b.setPopupMode(QToolButton.InstantPopup) ## TODO: set the space for the indicator w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) # OWGUI.button(self.controlBox, self, "Open...", callback=self.openScript) # OWGUI.button(self.controlBox, self, "Save...", callback=self.saveScript) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'MultiData Python script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.connect(self.text, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.pyqtConfigure(toolTip="Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) self.connect(action, SIGNAL("triggered()"), self.saveScript) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) self.openScript(self.codeFile) try: self.libraryView.selectionModel().select(self.libraryList.index(self.currentScriptIndex), QItemSelectionModel.ClearAndSelect) except Exception: pass self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.connect(self.splitCanvas, SIGNAL("splitterMoved(int, int)"), lambda pos, ind: setattr(self, "splitterState", str(self.splitCanvas.saveState()))) self.controlArea.layout().addStretch(1) self.resize(800,600)
class OWMultiDataPythonScript(OWWidget): settingsList = ["codeFile", "libraryListSource", "currentScriptIndex", "splitterState"] def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'MultiData Python Script') self.inputs = [("in_data", ExampleTable, self.setExampleTable, Default + Multiple), ("in_distance", orange.SymMatrix, self.setDistanceMatrix), ("in_network", Orange.network.Graph, self.setNetwork), ("in_learners", orange.Learner, self.setLearner, Default + Multiple), ("in_classifiers", orange.Classifier, self.setClassifier, Default + Multiple), ("in_misc", object, self.setMisc, Default + Multiple)] self.outputs = [("out_data", ExampleTable), ("out_distance", orange.SymMatrix), ("out_network", Orange.network.Graph), ("out_learner", orange.Learner), ("out_classifier", orange.Classifier, Dynamic), ("out_test_results", Orange.evaluation.testing.ExperimentResults), ("out_misc", object)] self.in_data = [] self.in_data_dict = {} # TODO: switch to weakref? self.in_learners = [] self.in_learner_dict = {} self.in_classifiers = [] self.in_classifier_dict = {} self.in_misc = [] self.in_misc_dict = {} self.in_network = None self.in_distance = None self.codeFile = '' self.libraryListSource = [Script("Hello world", "print 'Hello world'\n")] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') label = OWGUI.label(self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + \ "<li>".join(t[0] for t in self.outputs) + "</ul></p>") self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) # self.libraryList.append(Script("Hello world", "print 'Hello world'\n")) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView() self.libraryView.setEditTriggers(QListView.DoubleClicked | QListView.EditKeyPressed) self.libraryView.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.connect(self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.pyqtConfigure(toolTip="Add a new script to the library") self.connect(action, SIGNAL("triggered()"), self.onAddScript) new_empty = QAction("Add a new empty script", action) new_from_file = QAction("Add a new script from a file", action) self.connect(new_empty, SIGNAL("triggered()"), self.onAddScript) self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) menu = QMenu(w) menu.addAction(new_empty) menu.addAction(new_from_file) # action.setMenu(menu) button = w.addAction(action) self.removeAction = action = QAction("-", self) action.pyqtConfigure(toolTip="Remove script from library") self.connect(action, SIGNAL("triggered()"), self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.pyqtConfigure(toolTip="Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) self.connect(action, SIGNAL("triggered()"), self.commitChangesToLibrary) b = w.addAction(action) # b.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) action = QAction("More", self) action.pyqtConfigure(toolTip="More actions") #, icon=self.style().standardIcon(QStyle.SP_ToolBarHorizontalExtensionButton)) self.openScriptFromFileAction = new_from_file = QAction("Import a script from a file", self) self.saveScriptToFile = save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) self.connect(save_to_file, SIGNAL("triggered()"), self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) b = w.addAction(action) b.setPopupMode(QToolButton.InstantPopup) ## TODO: set the space for the indicator w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) # OWGUI.button(self.controlBox, self, "Open...", callback=self.openScript) # OWGUI.button(self.controlBox, self, "Save...", callback=self.saveScript) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'MultiData Python script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.connect(self.text, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.pyqtConfigure(toolTip="Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) self.connect(action, SIGNAL("triggered()"), self.saveScript) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) self.openScript(self.codeFile) try: self.libraryView.selectionModel().select(self.libraryList.index(self.currentScriptIndex), QItemSelectionModel.ClearAndSelect) except Exception: pass self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.connect(self.splitCanvas, SIGNAL("splitterMoved(int, int)"), lambda pos, ind: setattr(self, "splitterState", str(self.splitCanvas.saveState()))) self.controlArea.layout().addStretch(1) self.resize(800,600) def setDistanceMatrix(self, dm): self.in_distance = dm def setNetwork(self, net): self.in_network = net def setExampleTable(self, table, widget_tuple): # dictionary of id(input) to exampletable, if data is not None # if existing entry turns to None, remove. if table is None: self.in_data_dict.pop(widget_tuple, None) else: self.in_data_dict[widget_tuple] = table self.in_data = self.in_data_dict.values() def setLearner(self, learner, widget_tuple): # dictionary of id(input) to exampletable, if data is not None # if existing entry turns to None, remove. if learner is None: self.in_learner_dict.pop(widget_tuple, None) else: self.in_learner_dict[widget_tuple] = learner self.in_learners = self.in_learner_dict.values() def setClassifier(self, classifier, widget_tuple): # dictionary of id(input) to exampletable, if data is not None # if existing entry turns to None, remove. if classifier is None: self.in_classifier_dict.pop(widget_tuple, None) else: self.in_classifier_dict[widget_tuple] = classifier self.in_classifiers = self.in_classifier_dict.values() def setMisc(self, misc, widget_tuple): # dictionary of id(input) to exampletable, if data is not None # if existing entry turns to None, remove. if misc is None: self.in_misc_dict.pop(widget_tuple, None) else: self.in_misc_dict[widget_tuple] = misc self.in_misc = self.in_misc_dict.values() def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): selection = self.libraryView.selectionModel() selection.select(self.libraryList.index(index), QItemSelectionModel.ClearAndSelect) def onAddScript(self, *args): self.libraryList.append(Script("New script", "", 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): file = QFileDialog.getOpenFileName(self, 'Open Python Script', self.codeFile, 'Python files (*.py)\nAll files(*.*)') file = unicode(file) if file: name = os.path.basename(file) self.libraryList.append(Script(name, open(file, "rb").read(), 0, file)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] self.libraryView.selectionModel().select(self.libraryList.index(max(index - 1, 0)), QItemSelectionModel.ClearAndSelect) def onSaveScriptToFile(self, *args): index = self.selectedScriptIndex() if index is not None: self.saveScript() def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] if current >= len(self.libraryList): self.addNewScriptAction.trigger() return self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script=0): if type(script) != Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = QTextDocument(self) doc.setDocumentLayout(QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) self.connect(doc, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = self.text.toPlainText() self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def updateSelecetdScriptState(self): index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] self.libraryList[index] = Script(script.name, self.text.toPlainText(), 0) def openScript(self, filename=None): if filename == None: filename = unicode(QFileDialog.getOpenFileName(self, 'Open Python Script', self.codeFile, 'Python files (*.py)\nAll files(*.*)')) self.codeFile = filename else: self.codeFile = filename if self.codeFile == "": return self.error(0) try: f = open(self.codeFile, 'r') except (IOError, OSError), ex: self.text.setPlainText("") return self.text.setPlainText(f.read()) f.close()
class OWPythonScript(OWWidget): settingsList = [ "codeFile", "libraryListSource", "currentScriptIndex", "splitterState" ] def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'Python Script') self.inputs = [ ("in_data", ExampleTable, self.setExampleTable), ("in_distance", orange.SymMatrix, self.setDistanceMatrix), ("in_network", Orange.network.Graph, self.setNetwork), ("in_learner", orange.Learner, self.setLearner), ("in_classifier", orange.Classifier, self.setClassifier) ] self.outputs = [("out_data", ExampleTable), ("out_distance", orange.SymMatrix), ("out_network", Orange.network.Graph), ("out_learner", orange.Learner), ("out_classifier", orange.Classifier, Dynamic)] self.in_data = None self.in_network = None self.in_distance = None self.in_learner = None self.in_classifier = None self.codeFile = '' self.libraryListSource = [ Script("Hello world", "print 'Hello world'\n") ] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') label = OWGUI.label(self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + \ "<li>".join(t[0] for t in self.outputs) + "</ul></p>") self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) # self.libraryList.append(Script("Hello world", "print 'Hello world'\n")) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView() self.libraryView.pyqtConfigure(editTriggers=QListView.DoubleClicked | QListView.SelectedClicked) self.libraryView.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.connect( self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.pyqtConfigure(toolTip="Add a new script to the library") self.connect(action, SIGNAL("triggered()"), self.onAddScript) new_empty = QAction("Add a new empty script", action) new_from_file = QAction("Add a new script from a file", action) self.connect(new_empty, SIGNAL("triggered()"), self.onAddScript) self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) menu = QMenu(w) menu.addAction(new_empty) menu.addAction(new_from_file) # action.setMenu(menu) button = w.addAction(action) self.removeAction = action = QAction("-", self) action.pyqtConfigure(toolTip="Remove script from library") self.connect(action, SIGNAL("triggered()"), self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.pyqtConfigure(toolTip="Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) self.connect(action, SIGNAL("triggered()"), self.commitChangesToLibrary) b = w.addAction(action) # b.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) action = QAction("More", self) action.pyqtConfigure( toolTip="More actions" ) #, icon=self.style().standardIcon(QStyle.SP_ToolBarHorizontalExtensionButton)) self.openScriptFromFileAction = new_from_file = QAction( "Import a script from a file", self) self.saveScriptToFile = save_to_file = QAction( "Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) self.connect(save_to_file, SIGNAL("triggered()"), self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) b = w.addAction(action) b.setPopupMode(QToolButton.InstantPopup) ## TODO: set the space for the indicator w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) # OWGUI.button(self.controlBox, self, "Open...", callback=self.openScript) # OWGUI.button(self.controlBox, self, "Save...", callback=self.saveScript) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'Python script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.connect(self.text, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.pyqtConfigure(toolTip="Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) self.connect(action, SIGNAL("triggered()"), self.saveScript) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) self.openScript(self.codeFile) try: self.libraryView.selectionModel().select( self.libraryList.index(self.currentScriptIndex), QItemSelectionModel.ClearAndSelect) except Exception: pass self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.connect( self.splitCanvas, SIGNAL("splitterMoved(int, int)"), lambda pos, ind: setattr(self, "splitterState", str(self.splitCanvas.saveState()))) self.controlArea.layout().addStretch(1) self.resize(800, 600) def setExampleTable(self, et): self.in_data = et def setDistanceMatrix(self, dm): self.in_distance = dm def setNetwork(self, net): self.in_network = net def setLearner(self, learner): self.in_learner = learner def setClassifier(self, classifier): self.in_classifier = classifier def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): selection = self.libraryView.selectionModel() selection.select(self.libraryList.index(index), QItemSelectionModel.ClearAndSelect) def onAddScript(self, *args): self.libraryList.append(Script("New script", "", 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): file = QFileDialog.getOpenFileName( self, 'Open Python Script', self.codeFile, 'Python files (*.py)\nAll files(*.*)') if file: file = str(file) name = os.path.basename(file) self.libraryList.append( Script(name, open(file, "rb").read(), 0, file)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] self.libraryView.selectionModel().select( self.libraryList.index(max(index - 1, 0)), QItemSelectionModel.ClearAndSelect) def onSaveScriptToFile(self, *args): index = self.selectedScriptIndex() if index is not None: self.saveScript() def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] if current >= len(self.libraryList): self.addNewScriptAction.trigger() return self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script=0): if type(script) != Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = QTextDocument(self) doc.setDocumentLayout(QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) self.connect(doc, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = self.text.toPlainText() self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def updateSelecetdScriptState(self): index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] self.libraryList[index] = Script(script.name, self.text.toPlainText(), 0) def openScript(self, filename=None): if filename == None: self.codeFile = str( QFileDialog.getOpenFileName( self, 'Open Python Script', self.codeFile, 'Python files (*.py)\nAll files(*.*)')) else: self.codeFile = filename if self.codeFile == "": return self.error(0) try: f = open(self.codeFile, 'r') except (IOError, OSError), ex: self.text.setPlainText("") return self.text.setPlainText(f.read()) f.close()
def __init__(self, var, parent=None, **kwargs): PyListModel.__init__(self, [], parent, **kwargs) self.wrap(var.values) self.colorPalette = OWColorPalette.ColorPaletteHSV(len(self))
def data(self, index, role=Qt.DisplayRole): if role == Qt.DecorationRole: i = index.row() return QVariant(self.itemQIcon(i)) else: return PyListModel.data(self, index, role)
class DiscreteVariableEditor(VariableEditor): """An editor widget for editing a discrete variable. Extends the :class:`VariableEditor` to enable editing of variables values. """ def setup_gui(self): layout = QVBoxLayout() self.setLayout(layout) self.main_form = QFormLayout() self.main_form.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) layout.addLayout(self.main_form) self._setup_gui_name() self._setup_gui_values() self._setup_gui_labels() def _setup_gui_values(self): self.values_edit = QListView() self.values_edit.setEditTriggers(QTreeView.CurrentChanged) self.values_model = PyListModel(flags=Qt.ItemIsSelectable | \ Qt.ItemIsEnabled | Qt.ItemIsEditable) self.values_edit.setModel(self.values_model) self.values_model.dataChanged.connect(self.on_values_changed) self.main_form.addRow("Values", self.values_edit) def set_data(self, var): """Set the variable to edit """ VariableEditor.set_data(self, var) self.values_model.wrap([]) if var is not None: for v in var.values: self.values_model.append(v) def get_data(self): """Retrieve the modified variable """ name = str(self.name_edit.text()) labels = self.labels_model.get_dict() values = map(str, self.values_model) if not self.is_same(): var = type(self.var)(name, values=values) var.attributes.update(labels) self.var = var else: var = self.var return var def is_same(self): """Is the current model state the same as the input. """ values = map(str, self.values_model) return VariableEditor.is_same(self) and self.var.values == values def clear(self): """Clear the model state. """ VariableEditor.clear(self) self.values_model.wrap([]) @QtCore.Slot() def on_values_changed(self): self.maybe_commit()
def __init__(self, parent=None, signalManager=None, name="Preprocess"): OWWidget.__init__(self, parent, signalManager, name) self.inputs = [("Example Table", ExampleTable, self.setData) ] #, ("Learner", orange.Learner, self.setLearner)] self.outputs = [("Preprocess", orngWrap.PreprocessedLearner), ("Preprocessed Example Table", ExampleTable) ] #, ("Preprocessor", orange.Preprocessor)] self.autoCommit = False self.changedFlag = False # self.allSchemas = [PreprocessorSchema("Default" , [Preprocessor_discretize(method=orange.EntropyDiscretization()), Preprocessor_dropMissing()])] self.allSchemas = [("Default", [ Preprocessor_discretizeEntropy( method=orange.EntropyDiscretization()), Preprocessor_dropMissing() ], 0)] self.lastSelectedSchemaIndex = 0 self.preprocessorsList = PyListModel([], self) box = OWGUI.widgetBox(self.controlArea, "Preprocessors", addSpace=True) box.layout().setSpacing(1) self.setStyleSheet("QListView::item { margin: 1px;}") self.preprocessorsListView = QListView() self.preprocessorsListSelectionModel = ListSingleSelectionModel( self.preprocessorsList, self) self.preprocessorsListView.setItemDelegate( PreprocessorItemDelegate(self)) self.preprocessorsListView.setModel(self.preprocessorsList) self.preprocessorsListView.setSelectionModel( self.preprocessorsListSelectionModel) self.preprocessorsListView.setSelectionMode(QListView.SingleSelection) self.connect(self.preprocessorsListSelectionModel, SIGNAL("selectedIndexChanged(QModelIndex)"), self.onPreprocessorSelection) self.connect(self.preprocessorsList, SIGNAL("dataChanged(QModelIndex, QModelIndex)"), lambda arg1, arg2: self.commitIf) box.layout().addWidget(self.preprocessorsListView) self.addPreprocessorAction = QAction("+", self) self.addPreprocessorAction.pyqtConfigure( toolTip="Add a new preprocessor to the list") self.removePreprocessorAction = QAction("-", self) self.removePreprocessorAction.pyqtConfigure( toolTip="Remove selected preprocessor from the list") self.removePreprocessorAction.setEnabled(False) self.connect( self.preprocessorsListSelectionModel, SIGNAL("selectedIndexChanged(QModelIndex)"), lambda index: self. removePreprocessorAction.setEnabled(index.isValid())) actionsWidget = ModelActionsWidget( [self.addPreprocessorAction, self.removePreprocessorAction]) actionsWidget.layout().setSpacing(1) actionsWidget.layout().addStretch(10) box.layout().addWidget(actionsWidget) self.connect(self.addPreprocessorAction, SIGNAL("triggered()"), self.onAddPreprocessor) self.connect(self.removePreprocessorAction, SIGNAL("triggered()"), self.onRemovePreprocessor) box = OWGUI.widgetBox(self.controlArea, "Saved Schemas", addSpace=True) self.schemaFilterEdit = OWGUIEx.LineEditFilter(self) box.layout().addWidget(self.schemaFilterEdit) self.schemaList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled) self.schemaListProxy = PySortFilterProxyModel(filter_fmt="{0.name}", parent=self) self.schemaListProxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.schemaListProxy.setSourceModel(self.schemaList) self.schemaListView = QListView() self.schemaListView.setItemDelegate(PreprocessorSchemaDelegate(self)) # self.schemaListView.setModel(self.schemaList) self.schemaListView.setModel(self.schemaListProxy) self.connect(self.schemaFilterEdit, SIGNAL("textEdited(QString)"), self.schemaListProxy.setFilterRegExp) box.layout().addWidget(self.schemaListView) self.schemaListSelectionModel = ListSingleSelectionModel( self.schemaListProxy, self) self.schemaListView.setSelectionMode(QListView.SingleSelection) self.schemaListView.setSelectionModel(self.schemaListSelectionModel) self.connect(self.schemaListSelectionModel, SIGNAL("selectedIndexChanged(QModelIndex)"), self.onSchemaSelection) self.addSchemaAction = QAction("+", self) self.addSchemaAction.pyqtConfigure( toolTip="Add a new preprocessor schema") self.updateSchemaAction = QAction("Update", self) self.updateSchemaAction.pyqtConfigure( toolTip="Save changes made in the current schema") self.removeSchemaAction = QAction("-", self) self.removeSchemaAction.pyqtConfigure(toolTip="Remove selected schema") self.updateSchemaAction.setEnabled(False) self.removeSchemaAction.setEnabled(False) actionsWidget = ModelActionsWidget([]) actionsWidget.addAction(self.addSchemaAction) actionsWidget.addAction(self.updateSchemaAction).setSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) actionsWidget.addAction(self.removeSchemaAction) actionsWidget.layout().setSpacing(1) box.layout().addWidget(actionsWidget) self.connect(self.addSchemaAction, SIGNAL("triggered()"), self.onAddSchema) self.connect(self.updateSchemaAction, SIGNAL("triggered()"), self.onUpdateSchema) self.connect(self.removeSchemaAction, SIGNAL("triggered()"), self.onRemoveSchema) self.addPreprocessorsMenuActions = actions = [] for name, pp, kwargs in self.preprocessors: action = QAction(name, self) self.connect(action, SIGNAL("triggered()"), lambda pp=pp, kwargs=kwargs: self.addPreprocessor( pp(**kwargs))) actions.append(action) box = OWGUI.widgetBox(self.controlArea, "Output") cb = OWGUI.checkBox(box, self, "autoCommit", "Commit on any change", callback=self.commitIf) b = OWGUI.button(box, self, "Commit", callback=self.commit) OWGUI.setStopper(self, b, cb, "changedFlag", callback=self.commitIf) self.mainAreaStack = QStackedLayout() self.stackedEditorsCache = {} OWGUI.widgetBox(self.mainArea, orientation=self.mainAreaStack) self.data = None self.learner = None self.loadSettings() self.activateLoadedSettings()
class OWPreprocess(OWWidget): contextHandlers = {"": PerfectDomainContextHandler("", [""])} settingsList = ["allSchemas", "lastSelectedSchemaIndex"] # Default preprocessors preprocessors = [("Discretize", Preprocessor_discretizeEntropy, {}), ("Continuize", Preprocessor_continuize, {}), ("Impute", Preprocessor_impute, {}), ("Feature selection", Preprocessor_featureSelection, {}), ("Sample", Preprocessor_sample, {})] # Editor widgets for preprocessors EDITORS = { Preprocessor_discretize: DiscretizeEditor, Preprocessor_discretizeEntropy: DiscretizeEditor, Preprocessor_removeContinuous: DiscretizeEditor, Preprocessor_continuize: ContinuizeEditor, Preprocessor_removeDiscrete: ContinuizeEditor, Preprocessor_impute: ImputeEditor, Preprocessor_imputeByLearner: ImputeEditor, Preprocessor_dropMissing: ImputeEditor, Preprocessor_featureSelection: FeatureSelectEditor, Preprocessor_sample: SampleEditor, type(None): QWidget } def __init__(self, parent=None, signalManager=None, name="Preprocess"): OWWidget.__init__(self, parent, signalManager, name) self.inputs = [("Example Table", ExampleTable, self.setData) ] #, ("Learner", orange.Learner, self.setLearner)] self.outputs = [("Preprocess", orngWrap.PreprocessedLearner), ("Preprocessed Example Table", ExampleTable) ] #, ("Preprocessor", orange.Preprocessor)] self.autoCommit = False self.changedFlag = False # self.allSchemas = [PreprocessorSchema("Default" , [Preprocessor_discretize(method=orange.EntropyDiscretization()), Preprocessor_dropMissing()])] self.allSchemas = [("Default", [ Preprocessor_discretizeEntropy( method=orange.EntropyDiscretization()), Preprocessor_dropMissing() ], 0)] self.lastSelectedSchemaIndex = 0 self.preprocessorsList = PyListModel([], self) box = OWGUI.widgetBox(self.controlArea, "Preprocessors", addSpace=True) box.layout().setSpacing(1) self.setStyleSheet("QListView::item { margin: 1px;}") self.preprocessorsListView = QListView() self.preprocessorsListSelectionModel = ListSingleSelectionModel( self.preprocessorsList, self) self.preprocessorsListView.setItemDelegate( PreprocessorItemDelegate(self)) self.preprocessorsListView.setModel(self.preprocessorsList) self.preprocessorsListView.setSelectionModel( self.preprocessorsListSelectionModel) self.preprocessorsListView.setSelectionMode(QListView.SingleSelection) self.connect(self.preprocessorsListSelectionModel, SIGNAL("selectedIndexChanged(QModelIndex)"), self.onPreprocessorSelection) self.connect(self.preprocessorsList, SIGNAL("dataChanged(QModelIndex, QModelIndex)"), lambda arg1, arg2: self.commitIf) box.layout().addWidget(self.preprocessorsListView) self.addPreprocessorAction = QAction("+", self) self.addPreprocessorAction.pyqtConfigure( toolTip="Add a new preprocessor to the list") self.removePreprocessorAction = QAction("-", self) self.removePreprocessorAction.pyqtConfigure( toolTip="Remove selected preprocessor from the list") self.removePreprocessorAction.setEnabled(False) self.connect( self.preprocessorsListSelectionModel, SIGNAL("selectedIndexChanged(QModelIndex)"), lambda index: self. removePreprocessorAction.setEnabled(index.isValid())) actionsWidget = ModelActionsWidget( [self.addPreprocessorAction, self.removePreprocessorAction]) actionsWidget.layout().setSpacing(1) actionsWidget.layout().addStretch(10) box.layout().addWidget(actionsWidget) self.connect(self.addPreprocessorAction, SIGNAL("triggered()"), self.onAddPreprocessor) self.connect(self.removePreprocessorAction, SIGNAL("triggered()"), self.onRemovePreprocessor) box = OWGUI.widgetBox(self.controlArea, "Saved Schemas", addSpace=True) self.schemaFilterEdit = OWGUIEx.LineEditFilter(self) box.layout().addWidget(self.schemaFilterEdit) self.schemaList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled) self.schemaListProxy = PySortFilterProxyModel(filter_fmt="{0.name}", parent=self) self.schemaListProxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.schemaListProxy.setSourceModel(self.schemaList) self.schemaListView = QListView() self.schemaListView.setItemDelegate(PreprocessorSchemaDelegate(self)) # self.schemaListView.setModel(self.schemaList) self.schemaListView.setModel(self.schemaListProxy) self.connect(self.schemaFilterEdit, SIGNAL("textEdited(QString)"), self.schemaListProxy.setFilterRegExp) box.layout().addWidget(self.schemaListView) self.schemaListSelectionModel = ListSingleSelectionModel( self.schemaListProxy, self) self.schemaListView.setSelectionMode(QListView.SingleSelection) self.schemaListView.setSelectionModel(self.schemaListSelectionModel) self.connect(self.schemaListSelectionModel, SIGNAL("selectedIndexChanged(QModelIndex)"), self.onSchemaSelection) self.addSchemaAction = QAction("+", self) self.addSchemaAction.pyqtConfigure( toolTip="Add a new preprocessor schema") self.updateSchemaAction = QAction("Update", self) self.updateSchemaAction.pyqtConfigure( toolTip="Save changes made in the current schema") self.removeSchemaAction = QAction("-", self) self.removeSchemaAction.pyqtConfigure(toolTip="Remove selected schema") self.updateSchemaAction.setEnabled(False) self.removeSchemaAction.setEnabled(False) actionsWidget = ModelActionsWidget([]) actionsWidget.addAction(self.addSchemaAction) actionsWidget.addAction(self.updateSchemaAction).setSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) actionsWidget.addAction(self.removeSchemaAction) actionsWidget.layout().setSpacing(1) box.layout().addWidget(actionsWidget) self.connect(self.addSchemaAction, SIGNAL("triggered()"), self.onAddSchema) self.connect(self.updateSchemaAction, SIGNAL("triggered()"), self.onUpdateSchema) self.connect(self.removeSchemaAction, SIGNAL("triggered()"), self.onRemoveSchema) self.addPreprocessorsMenuActions = actions = [] for name, pp, kwargs in self.preprocessors: action = QAction(name, self) self.connect(action, SIGNAL("triggered()"), lambda pp=pp, kwargs=kwargs: self.addPreprocessor( pp(**kwargs))) actions.append(action) box = OWGUI.widgetBox(self.controlArea, "Output") cb = OWGUI.checkBox(box, self, "autoCommit", "Commit on any change", callback=self.commitIf) b = OWGUI.button(box, self, "Commit", callback=self.commit) OWGUI.setStopper(self, b, cb, "changedFlag", callback=self.commitIf) self.mainAreaStack = QStackedLayout() self.stackedEditorsCache = {} OWGUI.widgetBox(self.mainArea, orientation=self.mainAreaStack) self.data = None self.learner = None self.loadSettings() self.activateLoadedSettings() def activateLoadedSettings(self): try: self.allSchemas = [ PreprocessorSchemaDelegate.asSchema(obj) for obj in self.allSchemas ] for s in self.allSchemas: s.modified = False self.schemaList.wrap(self.allSchemas) self.schemaListSelectionModel.select( self.schemaList.index( min(self.lastSelectedSchemaIndex, len(self.schemaList) - 1)), QItemSelectionModel.ClearAndSelect) self.commit() except Exception as ex: print(repr(ex)) def setData(self, data=None): self.data = data # self.commit() def setLearner(self, learner=None): self.learner = learner # self.commit() def handleNewSignals(self): self.commit() def selectedSchemaIndex(self): rows = self.schemaListSelectionModel.selectedRows() rows = [self.schemaListProxy.mapToSource(row) for row in rows] if rows: return rows[0] else: return QModelIndex() def addPreprocessor(self, prep): self.preprocessorsList.append(prep) self.preprocessorsListSelectionModel.select( self.preprocessorsList.index(len(self.preprocessorsList) - 1), QItemSelectionModel.ClearAndSelect) self.commitIf() self.setSchemaModified(True) def onAddPreprocessor(self): action = QMenu.exec_(self.addPreprocessorsMenuActions, QCursor.pos()) def onRemovePreprocessor(self): index = self.preprocessorsListSelectionModel.selectedRow() if index.isValid(): row = index.row() del self.preprocessorsList[row] newrow = min(max(row - 1, 0), len(self.preprocessorsList) - 1) if newrow > -1: self.preprocessorsListSelectionModel.select( self.preprocessorsList.index(newrow), QItemSelectionModel.ClearAndSelect) self.commitIf() self.setSchemaModified(True) def onPreprocessorSelection(self, index): if index.isValid(): pp = self.preprocessorsList[index.row()] self.currentSelectedIndex = index.row() self.showEditWidget(pp) else: self.showEditWidget(None) def onSchemaSelection(self, index): self.updateSchemaAction.setEnabled(index.isValid()) self.removeSchemaAction.setEnabled(index.isValid()) if index.isValid(): self.lastSelectedSchemaIndex = index.row() self.setActiveSchema(index.data().toPyObject()) def onAddSchema(self): schema = list(self.preprocessorsList) self.schemaList.append( PreprocessorSchema( "New schema", schema, self.preprocessorsListSelectionModel.selectedRow().row())) index = self.schemaList.index(len(self.schemaList) - 1) index = self.schemaListProxy.mapFromSource(index) self.schemaListSelectionModel.setCurrentIndex( index, QItemSelectionModel.ClearAndSelect) self.schemaListView.edit(index) def onUpdateSchema(self): # index = self.schemaListSelectionModel.selectedRow() index = self.selectedSchemaIndex() if index.isValid(): row = index.row() schema = self.schemaList[row] self.schemaList[row] = PreprocessorSchema( schema.name, list(self.preprocessorsList), self.preprocessorsListSelectionModel.selectedRow().row()) def onRemoveSchema(self): # index = self.schemaListSelectionModel.selectedRow() index = self.selectedSchemaIndex() if index.isValid(): row = index.row() del self.schemaList[row] newrow = min(max(row - 1, 0), len(self.schemaList) - 1) if newrow > -1: self.schemaListSelectionModel.select( self.schemaListProxy.mapFromSource( self.schemaList.index(newrow)), QItemSelectionModel.ClearAndSelect) def setActiveSchema(self, schema): if schema.modified and hasattr(schema, "_tmp_preprocessors"): self.preprocessorsList[:] = list(schema._tmp_preprocessors) else: self.preprocessorsList[:] = list(schema.preprocessors) self.preprocessorsListSelectionModel.select( schema.selectedPreprocessor, QItemSelectionModel.ClearAndSelect) self.commitIf() def showEditWidget(self, pp): w = self.stackedEditorsCache.get(type(pp), None) if w is None: w = self.EDITORS[type(pp)](self.mainArea) self.stackedEditorsCache[type(pp)] = w self.connect(w, SIGNAL("dataChanged"), self.setEditedPreprocessor) self.mainAreaStack.addWidget(w) self.mainAreaStack.setCurrentWidget(w) w.data = pp w.show() def setEditedPreprocessor(self, pp): self.preprocessorsList[ self.preprocessorsListSelectionModel.selectedRow().row()] = pp self.setSchemaModified(True) self.commitIf() # self.onUpdateSchema() def setSchemaModified(self, state): # index = self.schemaListSelectionModel.selectedRow() index = self.selectedSchemaIndex() if index.isValid(): row = index.row() self.schemaList[row].modified = True self.schemaList[row]._tmp_preprocessors = list( self.preprocessorsList) self.schemaList.emitDataChanged([row]) def commitIf(self): if self.autoCommit: self.commit() else: self.changedFlag = True def commit(self): wrap = orngWrap.PreprocessedLearner(list(self.preprocessorsList)) if self.data is not None: data = wrap.processData(self.data) self.send("Preprocessed Example Table", data) self.send("Preprocess", wrap) # self.send("Preprocessor", Preprocessor_preprocessorList(list(self.preprocessorsList))) self.changedFlag = False
def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'Python Script') self.inputs = [("in_data", Orange.data.Table, self.setExampleTable, Default), ("in_distance", Orange.misc.SymMatrix, self.setDistanceMatrix, Default), ("in_learner", Orange.core.Learner, self.setLearner, Default), ("in_classifier", Orange.core.Classifier, self.setClassifier, Default), ("in_object", object, self.setObject)] self.outputs = [("out_data", Orange.data.Table), ("out_distance", Orange.misc.SymMatrix), ("out_learner", Orange.core.Learner), ("out_classifier", Orange.core.Classifier, Dynamic), ("out_object", object, Dynamic)] self.in_data = None self.in_distance = None self.in_learner = None self.in_classifier = None self.in_object = None self.auto_execute = False self.libraryListSource = [Script("Hello world", "print 'Hello world'\n")] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') OWGUI.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + "<li>".join(t[0] for t in self.outputs) + "</ul></p>" ) self.libraryList = PyListModel( [], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable ) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) ) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged ) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import a script from a file", self) save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) OWGUI.checkBox(self.runBox, self, "auto_execute", "Auto execute", tooltip=("Run the script automatically whenever " "the inputs to the widget change.")) self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'Python script') self.splitter.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitter.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.splitter.setSizes([2, 1]) if self.splitterState is not None: self.splitter.restoreState(QByteArray(self.splitterState)) self.splitter.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600)
class OWPythonScript(OWWidget): settingsList = ["libraryListSource", "currentScriptIndex", "splitterState", "auto_execute"] def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'Python Script') self.inputs = [("in_data", Orange.data.Table, self.setExampleTable, Default), ("in_distance", Orange.misc.SymMatrix, self.setDistanceMatrix, Default), ("in_learner", Orange.core.Learner, self.setLearner, Default), ("in_classifier", Orange.core.Classifier, self.setClassifier, Default), ("in_object", object, self.setObject)] self.outputs = [("out_data", Orange.data.Table), ("out_distance", Orange.misc.SymMatrix), ("out_learner", Orange.core.Learner), ("out_classifier", Orange.core.Classifier, Dynamic), ("out_object", object, Dynamic)] self.in_data = None self.in_distance = None self.in_learner = None self.in_classifier = None self.in_object = None self.auto_execute = False self.libraryListSource = [Script("Hello world", "print 'Hello world'\n")] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') OWGUI.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + "<li>".join(t[0] for t in self.outputs) + "</ul></p>" ) self.libraryList = PyListModel( [], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable ) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) ) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged ) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import a script from a file", self) save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) OWGUI.checkBox(self.runBox, self, "auto_execute", "Auto execute", tooltip=("Run the script automatically whenever " "the inputs to the widget change.")) self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'Python script') self.splitter.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitter.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.splitter.setSizes([2, 1]) if self.splitterState is not None: self.splitter.restoreState(QByteArray(self.splitterState)) self.splitter.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600) def setExampleTable(self, et): self.in_data = et def setDistanceMatrix(self, dm): self.in_distance = dm def setLearner(self, learner): self.in_learner = learner def setClassifier(self, classifier): self.in_classifier = classifier def setObject(self, obj): self.in_object = obj def handleNewSignals(self): if self.auto_execute: self.execute() def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): select_row(self.libraryView, index) def onAddScript(self, *args): self.libraryList.append(Script("New script", "", 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): filename = QFileDialog.getOpenFileName( self, 'Open Python Script', os.path.expanduser("~/"), 'Python files (*.py)\nAll files(*.*)' ) filename = unicode(filename) if filename: name = os.path.basename(filename) self.libraryList.append(Script(name, open(filename, "rb").read(), 0, filename)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] select_row(self.libraryView, max(index - 1, 0)) def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script=0): if type(script) != Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = QTextDocument(self) doc.setDocumentLayout(QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) doc.modificationChanged[bool].connect(self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = unicode(self.text.toPlainText()) self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def onSpliterMoved(self, pos, ind): self.splitterState = str(self.splitter.saveState()) def saveScript(self): index = self.selectedScriptIndex() filename = os.path.expanduser("~/") if index is not None: script = self.libraryList[index] filename = script.sourceFileName or filename filename = QFileDialog.getSaveFileName( self, 'Save Python Script', filename, 'Python files (*.py)\nAll files(*.*)' ) self.codeFile = unicode(filename) if self.codeFile: fn = "" head, tail = os.path.splitext(self.codeFile) if not tail: fn = head + ".py" else: fn = self.codeFile f = open(fn, 'w') f.write(self.text.toPlainText()) f.close() def execute(self): self._script = str(self.text.toPlainText()) self.console.write("\nRunning script:\n") self.console.push("exec(_script)") self.console.new_prompt(sys.ps1) for out in self.outputs: signal = out[0] self.send(signal, getattr(self, signal, None))
def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'Python Script') self.inputs = [ ("in_data", ExampleTable, self.setExampleTable), ("in_distance", orange.SymMatrix, self.setDistanceMatrix), ("in_network", Orange.network.Graph, self.setNetwork), ("in_learner", orange.Learner, self.setLearner), ("in_classifier", orange.Classifier, self.setClassifier) ] self.outputs = [("out_data", ExampleTable), ("out_distance", orange.SymMatrix), ("out_network", Orange.network.Graph), ("out_learner", orange.Learner), ("out_classifier", orange.Classifier, Dynamic)] self.in_data = None self.in_network = None self.in_distance = None self.in_learner = None self.in_classifier = None self.codeFile = '' self.libraryListSource = [ Script("Hello world", "print 'Hello world'\n") ] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') label = OWGUI.label(self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + \ "<li>".join(t[0] for t in self.outputs) + "</ul></p>") self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) # self.libraryList.append(Script("Hello world", "print 'Hello world'\n")) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView() self.libraryView.pyqtConfigure(editTriggers=QListView.DoubleClicked | QListView.SelectedClicked) self.libraryView.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.connect( self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.pyqtConfigure(toolTip="Add a new script to the library") self.connect(action, SIGNAL("triggered()"), self.onAddScript) new_empty = QAction("Add a new empty script", action) new_from_file = QAction("Add a new script from a file", action) self.connect(new_empty, SIGNAL("triggered()"), self.onAddScript) self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) menu = QMenu(w) menu.addAction(new_empty) menu.addAction(new_from_file) # action.setMenu(menu) button = w.addAction(action) self.removeAction = action = QAction("-", self) action.pyqtConfigure(toolTip="Remove script from library") self.connect(action, SIGNAL("triggered()"), self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.pyqtConfigure(toolTip="Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) self.connect(action, SIGNAL("triggered()"), self.commitChangesToLibrary) b = w.addAction(action) # b.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) action = QAction("More", self) action.pyqtConfigure( toolTip="More actions" ) #, icon=self.style().standardIcon(QStyle.SP_ToolBarHorizontalExtensionButton)) self.openScriptFromFileAction = new_from_file = QAction( "Import a script from a file", self) self.saveScriptToFile = save_to_file = QAction( "Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) self.connect(save_to_file, SIGNAL("triggered()"), self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) b = w.addAction(action) b.setPopupMode(QToolButton.InstantPopup) ## TODO: set the space for the indicator w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) # OWGUI.button(self.controlBox, self, "Open...", callback=self.openScript) # OWGUI.button(self.controlBox, self, "Save...", callback=self.saveScript) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'Python script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.connect(self.text, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.pyqtConfigure(toolTip="Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) self.connect(action, SIGNAL("triggered()"), self.saveScript) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) self.openScript(self.codeFile) try: self.libraryView.selectionModel().select( self.libraryList.index(self.currentScriptIndex), QItemSelectionModel.ClearAndSelect) except Exception: pass self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.connect( self.splitCanvas, SIGNAL("splitterMoved(int, int)"), lambda pos, ind: setattr(self, "splitterState", str(self.splitCanvas.saveState()))) self.controlArea.layout().addStretch(1) self.resize(800, 600)
class OWRScript(OWWidget): settingsList = ["scriptLibraryList", "selectedScriptIndex", "lastDir"] def __init__(self, parent=None, signalManager=None, name="R Script"): OWWidget.__init__(self, parent, signalManager, name) self.inputs = [("in_data", ExampleTable, self.setData), ("in_distance", orange.SymMatrix, self.setDistance)] self.outputs = [("out_data", ExampleTable), ("out_distance", orange.SymMatrix), ("out_learner", orange.Learner), ("out_classifier", orange.Classifier)] self.in_data, self.in_distance = None, None self.scriptLibraryList = [RScript("New script", "x <- c(1,2,5)\ny <- c(2,1 6)\nplot(x,y)\n")] self.selectedScriptIndex = 0 self.selectedGrDev = "PNG" self.lastDir = os.path.expanduser("~/script.R") self.loadSettings() self.defaultFont = QFont("Monaco") if sys.platform == "darwin" else QFont("Courier") self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) self.scriptEdit = RScriptEditor() self.splitter.addWidget(self.scriptEdit) self.console = RPy2Console({}, self) self.splitter.addWidget(self.console) self.splitter.setSizes([2,1]) self.libraryModel = PyListModel([], self, Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable) self.libraryModel.wrap(self.scriptLibraryList) self.infoBox = OWGUI.widgetLabel(OWGUI.widgetBox(self.controlArea, "Info", addSpace=True), "") self.infoBox.setText("<p>Execute R script</p>Input variables<li><ul>in_data</ul><ul>in_distance</ul></li>Output variables:<li><ul>out_data</ul></p/>") box = OWGUI.widgetBox(self.controlArea, "Library", addSpace=True) self.libraryWidget = LibraryWidget() self.libraryView = self.libraryWidget.view box.layout().addWidget(self.libraryWidget) self.libraryWidget.view.setItemDelegate(ScriptItemDelegate(self)) self.libraryWidget.setScriptModel(self.libraryModel) self.libraryWidget.setDocumentEditor(self.scriptEdit) box = OWGUI.widgetBox(self.controlArea, "Run") OWGUI.button(box, self, "Execute", callback=self.runScript, tooltip="Execute the script") OWGUI.rubber(self.controlArea) self.connect(self.libraryWidget.addScriptAction, SIGNAL("triggered()"), self.onAddNewScript) self.connect(self.libraryWidget.updateScriptAction, SIGNAL("triggered()"), self.onUpdateScript) self.connect(self.libraryWidget.removeScriptAction, SIGNAL("triggered()"), self.onRemoveScript) self.connect(self.libraryWidget.addScriptFromFile, SIGNAL("triggered()"), self.onAddScriptFromFile) self.connect(self.libraryWidget.saveScriptToFile, SIGNAL("triggered()"), self.onSaveScriptToFile) self.connect(self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onScriptSelection) self._cachedDocuments = {} self.grView = QLabel() self.resize(800, 600) QTimer.singleShot(30, self.initGrDevice) def initGrDevice(self): import tempfile self.grDevFile = tempfile.NamedTemporaryFile("rwb", prefix="orange-rscript-grDev", suffix=".png", delete=False) self.grDevFile.close() robjects.r('png("%s", width=512, height=512)' % self.grDevFile.name) self.fileWatcher = QFileSystemWatcher(self) self.fileWatcher.addPath(self.grDevFile.name) self.connect(self.fileWatcher, SIGNAL("fileChanged(QString)"), self.updateGraphicsView) def updateGraphicsView(self, filename): self.grView.setPixmap(QPixmap(filename)) self.grView.show() if self.grDevFile.name not in list(self.fileWatcher.files()): # The file can be removed and recreated by R, in which case we need to re-add it self.fileWatcher.addPath(self.grDevFile.name) def selectScript(self, index): index = self.libraryModel.index(index) self.libraryView.selectionModel().select(index, QItemSelectionModel.ClearAndSelect) def selectedScript(self): rows = self.libraryView.selectionModel().selectedRows() rows = [index.row() for index in rows] if rows: return rows[0] else: return None def onAddNewScript(self): self.libraryModel.append(RScript("New Script", "")) self.selectScript(len(self.libraryModel) - 1) def onRemoveScript(self): row = self.selectedScript() if row is not None: del self.libraryModel[row] def onUpdateScript(self): row = self.selectedScript() if row is not None: self.libraryModel[row].script = str(self.scriptEdit.toPlainText()) self.scriptEdit.document().setModified(False) self.libraryModel.emitDataChanged([row]) def onAddScriptFromFile(self): filename = str(QFileDialog.getOpenFileName(self, "Open script", self.lastDir)) if filename: script = open(filename, "rb").read() self.lastDir, name = os.path.split(filename) self.libraryModel.append(RScript(name, script, sourceFileName=filename)) self.selectScript(len(self.libraryModel) - 1) def onSaveScriptToFile(self): row = self.selectedScript() if row is not None: script = self.libraryModel[row] filename = str(QFileDialog.getSaveFileName(self, "Save Script As", script.sourceFileName or self.lastDir)) if filename: self.lastDir, name = os.path.split(filename) script.sourceFileName = filename script.flags = 0 open(filename, "wb").write(script.script) def onScriptSelection(self, *args): row = self.selectedScript() if row is not None: self.scriptEdit.setDocument(self.documentForScript(row)) def documentForScript(self, script=0): if type(script) != RScript: script = self.libraryModel[script] if script not in self._cachedDocuments: doc = QTextDocument(self) doc.setDocumentLayout(QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = RSyntaxHighlighter(doc) self.connect(doc, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def onModificationChanged(self, changed): row = self.selectedScript() if row is not None: self.libraryModel[row].flags = RScript.Modified if changed else 0 self.libraryModel.emitDataChanged([row]) def setData(self, data): self.in_data = data self.console.setLocals(self.getLocals()) def setDistance(self, matrix): self.in_distance = matrix self.console.setLocals(self.getLocals()) def getLocals(self): return {"in_data": self.in_data, "in_distance": self.in_distance, } def runScript(self): self.console.push('png("%s", width=512, height=512)\n' % self.grDevFile.name) self.console.push(str(self.scriptEdit.toPlainText())) self.console.new_prompt(">>> ") robjects.r("dev.off()\n")
def __init__(self, parent=None, signalManager=None, name="R Script"): OWWidget.__init__(self, parent, signalManager, name) self.inputs = [("in_data", ExampleTable, self.setData), ("in_distance", orange.SymMatrix, self.setDistance)] self.outputs = [("out_data", ExampleTable), ("out_distance", orange.SymMatrix), ("out_learner", orange.Learner), ("out_classifier", orange.Classifier)] self.in_data, self.in_distance = None, None self.scriptLibraryList = [RScript("New script", "x <- c(1,2,5)\ny <- c(2,1 6)\nplot(x,y)\n")] self.selectedScriptIndex = 0 self.selectedGrDev = "PNG" self.lastDir = os.path.expanduser("~/script.R") self.loadSettings() self.defaultFont = QFont("Monaco") if sys.platform == "darwin" else QFont("Courier") self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) self.scriptEdit = RScriptEditor() self.splitter.addWidget(self.scriptEdit) self.console = RPy2Console({}, self) self.splitter.addWidget(self.console) self.splitter.setSizes([2,1]) self.libraryModel = PyListModel([], self, Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable) self.libraryModel.wrap(self.scriptLibraryList) self.infoBox = OWGUI.widgetLabel(OWGUI.widgetBox(self.controlArea, "Info", addSpace=True), "") self.infoBox.setText("<p>Execute R script</p>Input variables<li><ul>in_data</ul><ul>in_distance</ul></li>Output variables:<li><ul>out_data</ul></p/>") box = OWGUI.widgetBox(self.controlArea, "Library", addSpace=True) self.libraryWidget = LibraryWidget() self.libraryView = self.libraryWidget.view box.layout().addWidget(self.libraryWidget) self.libraryWidget.view.setItemDelegate(ScriptItemDelegate(self)) self.libraryWidget.setScriptModel(self.libraryModel) self.libraryWidget.setDocumentEditor(self.scriptEdit) box = OWGUI.widgetBox(self.controlArea, "Run") OWGUI.button(box, self, "Execute", callback=self.runScript, tooltip="Execute the script") OWGUI.rubber(self.controlArea) self.connect(self.libraryWidget.addScriptAction, SIGNAL("triggered()"), self.onAddNewScript) self.connect(self.libraryWidget.updateScriptAction, SIGNAL("triggered()"), self.onUpdateScript) self.connect(self.libraryWidget.removeScriptAction, SIGNAL("triggered()"), self.onRemoveScript) self.connect(self.libraryWidget.addScriptFromFile, SIGNAL("triggered()"), self.onAddScriptFromFile) self.connect(self.libraryWidget.saveScriptToFile, SIGNAL("triggered()"), self.onSaveScriptToFile) self.connect(self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onScriptSelection) self._cachedDocuments = {} self.grView = QLabel() self.resize(800, 600) QTimer.singleShot(30, self.initGrDevice)