def __init__(self): super().__init__() self.data_points_interpolate = None dbox = gui.widgetBox(self.controlArea, "Interpolation") rbox = gui.radioButtons( dbox, self, "input_radio", callback=self._change_input) gui.appendRadioButton(rbox, "Enable automatic interpolation") gui.appendRadioButton(rbox, "Linear interval") ibox = gui.indentedBox(rbox) form = QWidget() formlayout = QFormLayout() form.setLayout(formlayout) ibox.layout().addWidget(form) self.xmin_edit = lineEditFloatOrNone(ibox, self, "xmin", callback=self.commit) formlayout.addRow("Min", self.xmin_edit) self.xmax_edit = lineEditFloatOrNone(ibox, self, "xmax", callback=self.commit) formlayout.addRow("Max", self.xmax_edit) self.dx_edit = lineEditFloatOrNone(ibox, self, "dx", callback=self.commit) formlayout.addRow("Δ", self.dx_edit) gui.appendRadioButton(rbox, "Reference data") self.data = None gui.auto_commit(self.controlArea, self, "autocommit", "Interpolate") self._change_input()
def test_overlay(self): container = QWidget() overlay = MessageOverlayWidget(parent=container) overlay.setWidget(container) overlay.setIcon(QStyle.SP_MessageBoxInformation) container.show() container.raise_() self._exec(500) self.assertTrue(overlay.isVisible()) overlay.setText("Hello world! It's so nice here") self._exec(500) button_ok = overlay.addButton(MessageOverlayWidget.Ok) button_close = overlay.addButton(MessageOverlayWidget.Close) button_help = overlay.addButton(MessageOverlayWidget.Help) self.assertTrue(all([button_ok, button_close, button_help])) self.assertIs(overlay.button(MessageOverlayWidget.Ok), button_ok) self.assertIs(overlay.button(MessageOverlayWidget.Close), button_close) self.assertIs(overlay.button(MessageOverlayWidget.Help), button_help) button = overlay.addButton("Click Me!", MessageOverlayWidget.AcceptRole) self.assertIsNot(button, None) self.assertTrue(overlay.buttonRole(button), MessageOverlayWidget.AcceptRole) self._exec(10000)
def __init__(self, var, lc, widget_parent=None, widget=None): QWidget.__init__(self) self.list_view = QListView() text = [] model = QStandardItemModel(self.list_view) for (i, val) in enumerate(var.values): item = QStandardItem(val) item.setCheckable(True) if i + 1 in lc: item.setCheckState(Qt.Checked) text.append(val) model.appendRow(item) model.itemChanged.connect(widget_parent.conditions_changed) self.list_view.setModel(model) layout = QGridLayout(self) layout.addWidget(self.list_view) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.adjustSize() self.setWindowFlags(Qt.Popup) self.widget = widget self.widget.desc_text = ', '.join(text) self.widget.set_text()
def __init__(self, parent=None, **kwargs): QWidget.__init__(self, parent, **kwargs) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) self.setLayout(layout) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.__tabs = [] self.__currentIndex = -1 self.__changeOnHover = False self.__iconSize = QSize(26, 26) self.__group = QButtonGroup(self, exclusive=True) self.__group.buttonPressed[QAbstractButton].connect( self.__onButtonPressed ) self.setMouseTracking(True) self.__sloppyButton = None self.__sloppyRegion = QRegion() self.__sloppyTimer = QTimer(self, singleShot=True) self.__sloppyTimer.timeout.connect(self.__onSloppyTimeout)
def __init__(self, orientation, parent): QWidget.__init__(self, parent) if orientation == Qt.Vertical: self._layout = QVBoxLayout() else: self._layout = QHBoxLayout() self.setLayout(self._layout)
def test_dock_standalone(self): widget = QWidget() layout = QHBoxLayout() widget.setLayout(layout) layout.addStretch(1) widget.show() dock = CollapsibleDockWidget() layout.addWidget(dock) list_view = QListView() list_view.setModel(QStringListModel(["a", "b"], list_view)) label = QLabel("A label. ") label.setWordWrap(True) dock.setExpandedWidget(label) dock.setCollapsedWidget(list_view) dock.setExpanded(True) self.app.processEvents() def toogle(): dock.setExpanded(not dock.expanded()) self.singleShot(2000, toogle) toogle() self.app.exec_()
def test_toolbox(self): w = QWidget() layout = QHBoxLayout() reg = global_registry() qt_reg = QtWidgetRegistry(reg) triggered_actions = [] model = qt_reg.model() file_action = qt_reg.action_for_widget( "Orange.widgets.data.owfile.OWFile" ) box = WidgetToolBox() box.setModel(model) box.triggered.connect(triggered_actions.append) layout.addWidget(box) box.setButtonSize(QSize(50, 80)) w.setLayout(layout) w.show() file_action.trigger() box.setButtonSize(QSize(60, 80)) box.setIconSize(QSize(35, 35)) box.setTabButtonHeight(40) box.setTabIconSize(QSize(30, 30)) self.app.exec_()
def __init__(self, master): QWidget.__init__(self) gui.OWComponent.__init__(self, master) self.master = master self.preprocessor = master.preprocessor self.value = getattr(self.preprocessor, self.attribute) # Title bar. title_holder = QWidget() title_holder.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) title_holder.setStyleSheet(""" .QWidget { background: qlineargradient( x1:0 y1:0, x2:0 y2:1, stop:0 #F8F8F8, stop:1 #C8C8C8); border-bottom: 1px solid #B3B3B3; } """) self.titleArea = QHBoxLayout() self.titleArea.setContentsMargins(10, 5, 10, 5) self.titleArea.setSpacing(0) title_holder.setLayout(self.titleArea) self.title_label = QLabel(self.title) self.title_label.mouseDoubleClickEvent = self.on_toggle self.title_label.setStyleSheet('font-size: 12px; border: 2px solid red;') self.titleArea.addWidget(self.title_label) self.off_label = QLabel('[disabled]') self.off_label.setStyleSheet('color: #B0B0B0; margin-left: 5px;') self.titleArea.addWidget(self.off_label) self.off_label.hide() self.titleArea.addStretch() # Root. self.rootArea = QVBoxLayout() self.rootArea.setContentsMargins(0, 0, 0, 0) self.rootArea.setSpacing(0) self.setLayout(self.rootArea) self.rootArea.addWidget(title_holder) self.contents = QWidget() contentArea = QVBoxLayout() contentArea.setContentsMargins(15, 10, 15, 10) self.contents.setLayout(contentArea) self.rootArea.addWidget(self.contents) self.method_layout = self.Layout() self.setup_method_layout() self.contents.layout().addLayout(self.method_layout) if self.toggle_enabled: self.on_off_button = OnOffButton(enabled=self.enabled) self.on_off_button.stateChanged.connect(self.on_toggle) self.on_off_button.setContentsMargins(0, 0, 0, 0) self.titleArea.addWidget(self.on_off_button) self.display_widget(update_master_width=False)
def box_spacing(self, widget): if isinstance(widget.layout(), QGridLayout): widget = widget.layout() if isinstance(widget, QGridLayout): space = QWidget() space.setFixedSize(12, 12) widget.addWidget(space, widget.rowCount(), 0) else: gui.separator(widget)
def __init__(self, *args, **kwargs): QWidget.__init__(self, *args, **kwargs) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.__text = "" self.__textElideMode = Qt.ElideMiddle self.__sizeHint = None self.__alignment = Qt.AlignLeft | Qt.AlignVCenter
def __init__(self, parent=None, windowTitle="Color Palette List", **kwargs): super().__init__(parent, windowTitle=windowTitle, **kwargs) self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) sa = QScrollArea( horizontalScrollBarPolicy=Qt.ScrollBarAlwaysOff, verticalScrollBarPolicy=Qt.ScrollBarAlwaysOn ) sa.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) sa.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.layout().addWidget(sa) space = QWidget(self) space.setLayout(QVBoxLayout()) sa.setWidget(space) sa.setWidgetResizable(True) self.buttons = [] self.setMinimumWidth(400) box = gui.vBox(space, "Information", addSpace=True) gui.widgetLabel( box, '<p align="center">This dialog shows a list of predefined ' 'color palettes <br>from colorbrewer.org that can be used ' 'in Orange.<br/>You can select a palette by clicking on it.</p>' ) box = gui.vBox(space, "Default Palette", addSpace=True) butt = _ColorButton( DefaultRGBColors, flat=True, toolTip="Default color palette", clicked=self._buttonClicked ) box.layout().addWidget(butt) self.buttons.append(butt) for type in ["Qualitative", "Spectral", "Diverging", "Sequential", "Pastels"]: colorGroup = colorbrewer.colorSchemes.get(type.lower(), {}) if colorGroup: box = gui.vBox(space, type + " Palettes", addSpace=True) items = sorted(colorGroup.items()) for key, colors in items: butt = _ColorButton(colors, self, toolTip=key, flat=True, clicked=self._buttonClicked) box.layout().addWidget(butt) self.buttons.append(butt) buttons = QDialogButtonBox( QDialogButtonBox.Cancel, rejected=self.reject ) self.layout().addWidget(buttons) self.selectedColors = None
def __init__(self, parent): QWidget.__init__(self, parent) gui.OWComponent.__init__(self, parent) self.parameters = {} self.parent_callback = parent.settings_changed # GUI self.setMinimumWidth(221) self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.main_area = gui.vBox(self, spacing=0)
def __init__(self, tree, dataset, master, parent=None): QWidget.__init__(self, parent) Control.__init__(self, tree, dataset, master) self.tree = tree self.dataset = dataset self.master = master self.setObjectName(tree.internalName) self.setLayout(QGridLayout()) self.textWidget = QPlainTextEdit() # TODO: Subclass to receive drop events from item model views self.layout().addWidget(self.textWidget, 0, 0, 1, 1)
def __init__(self, parent=None, **kwargs): QWidget.__init__(self, parent, **kwargs) self.__lines = 5000 self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.__text = TerminalView() self.__currentCharFormat = self.__text.currentCharFormat() self.layout().addWidget(self.__text)
def __init__(self, actions=None, parent=None, direction=QBoxLayout.LeftToRight): QWidget.__init__(self, parent) self.actions = [] self.buttons = [] layout = QBoxLayout(direction) layout.setContentsMargins(0, 0, 0, 0) self.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) if actions is not None: for action in actions: self.addAction(action) self.setLayout(layout)
def __init__(self, parent=None, color=QColor(), radius=5, **kwargs): QWidget.__init__(self, parent, **kwargs) self.setAttribute(Qt.WA_TransparentForMouseEvents, True) self.setAttribute(Qt.WA_NoChildEventsForParent, True) self.setFocusPolicy(Qt.NoFocus) self.__color = QColor(color) self.__radius = radius self.__widget = None self.__widgetParent = None self.__updatePixmap()
def __init__(self, tree, dataset, master, parent=None): QWidget.__init__(self, parent) Control.__init__(self, tree, dataset, master) self.setLayout(QVBoxLayout()) self.setContentsMargins(0, 0, 0, 0) self.cb = QComboBox() self.idsEdit = QPlainTextEdit() self.layout().addWidget(self.cb) self.layout().addWidget(self.idsEdit) self.options = [] self.setOptions(tree.subelements_top("Option"))
def __init__(self, tree, dataset, master, parent=None): QWidget.__init__(self, parent) Control.__init__(self, tree, dataset, master) self.setLayout(QVBoxLayout()) self.buttonGroup = QButtonGroup(self) self.values = [] for i, option in enumerate(tree.subelements_top("Option")): rb = QRadioButton(option.displayName, self) self.buttonGroup.addButton(rb) self.buttonGroup.setId(rb, i) self.layout().addWidget(rb) self.values.append(option.value) self.buttonGroup.button(0).setChecked(True)
def insertRow(self, index, actions, background="light-orange"): """Insert a row with `actions` at `index`. """ widget = QWidget(objectName="icon-row") layout = QHBoxLayout() layout.setContentsMargins(40, 0, 40, 0) layout.setSpacing(65) widget.setLayout(layout) self.__mainLayout.insertWidget(index, widget, stretch=10, alignment=Qt.AlignCenter) for i, action in enumerate(actions): self.insertAction(index, i, action, background)
def __relayout(self): for slot in self.__buttons: self.layout().removeWidget(slot.button) order = { MessageOverlayWidget.HelpRole: 0, MessageOverlayWidget.AcceptRole: 2, MessageOverlayWidget.RejectRole: 3, } orderd = sorted(self.__buttons, key=lambda slot: order.get(slot.role, -1)) prev = self.__textlabel for slot in orderd: self.layout().addWidget(slot.button) QWidget.setTabOrder(prev, slot.button)
def __init__(self, parent=None, **kwargs): super().__init__(parent, acceptDrops=True, **kwargs) self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.addonwidget = AddonManagerWidget() self.layout().addWidget(self.addonwidget) info_bar = QWidget() info_layout = QHBoxLayout() info_bar.setLayout(info_layout) self.layout().addWidget(info_bar) buttons = QDialogButtonBox( orientation=Qt.Horizontal, standardButtons=QDialogButtonBox.Ok | QDialogButtonBox.Cancel ) buttons.accepted.connect(self.__accepted) buttons.rejected.connect(self.reject) self.layout().addWidget(buttons) # No system access => install into user site-packages self.user_install = not os.access(sysconfig.get_path("purelib"), os.W_OK) self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=1) if AddonManagerDialog._packages is None: self._f_pypi_addons = self._executor.submit(list_pypi_addons) else: self._f_pypi_addons = concurrent.futures.Future() self._f_pypi_addons.set_result(AddonManagerDialog._packages) self._f_pypi_addons.add_done_callback( method_queued(self._set_packages, (object,)) ) self.__progress = QProgressDialog( self, Qt.Sheet, minimum=0, maximum=0, labelText=self.tr("Retrieving package list"), sizeGripEnabled=False, windowTitle="Progress" ) self.__progress.rejected.connect(self.reject) self.__thread = None self.__installer = None
def __init__(self, parent=None, color=None, radius=5, **kwargs): QWidget.__init__(self, parent, **kwargs) self.setAttribute(Qt.WA_TransparentForMouseEvents, True) self.setAttribute(Qt.WA_NoChildEventsForParent, True) self.setFocusPolicy(Qt.NoFocus) if color is None: color = self.palette().color(QPalette.Dark) self.__color = color self.__radius = radius self.__widget = None self.__widgetParent = None self.__updatePixmap()
def __init__(self, state=AVAILABLE, parent=None): QWidget.__init__(self, parent) layout = QHBoxLayout() layout.setSpacing(1) layout.setContentsMargins(1, 1, 1, 1) self.checkButton = QCheckBox() layout.addWidget(self.checkButton) self.setLayout(layout) self.setMinimumHeight(20) self.setMaximumHeight(20) self.state = -1 self.setState(state)
def __init__(self, parent=None, label=""): QWidget.__init__(self, parent) OWComponent.__init__(self, None) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.position = 0 self.edit = lineEditFloatRange(self, self, "position", callback=self.edited.emit) layout.addWidget(self.edit) self.edit.focusIn.connect(self.focusIn.emit) self.line = MovableVline(position=self.position, label=label) connect_line(self.line, self, "position") self.line.sigMoveFinished.connect(self.edited.emit)
def __init__(self): super().__init__() # data self.dataA = None self.dataB = None # GUI w = QWidget(self) self.controlArea.layout().addWidget(w) grid = QGridLayout() grid.setContentsMargins(0, 0, 0, 0) w.setLayout(grid) # attribute A selection boxAttrA = gui.vBox(self, self.tr("Attribute A"), addToLayout=False) grid.addWidget(boxAttrA, 0, 0) self.attrViewA = gui.comboBox(boxAttrA, self, 'attr_a', orientation=Qt.Horizontal, sendSelectedValue=True, callback=self._invalidate) self.attrModelA = itemmodels.VariableListModel() self.attrViewA.setModel(self.attrModelA) # attribute B selection boxAttrB = gui.vBox(self, self.tr("Attribute B"), addToLayout=False) grid.addWidget(boxAttrB, 0, 1) self.attrViewB = gui.comboBox(boxAttrB, self, 'attr_b', orientation=Qt.Horizontal, sendSelectedValue=True, callback=self._invalidate) self.attrModelB = itemmodels.VariableListModel() self.attrViewB.setModel(self.attrModelB) # info A boxDataA = gui.vBox(self, self.tr("Data A Input"), addToLayout=False) grid.addWidget(boxDataA, 1, 0) self.infoBoxDataA = gui.widgetLabel(boxDataA, self.dataInfoText(None)) # info B boxDataB = gui.vBox(self, self.tr("Data B Input"), addToLayout=False) grid.addWidget(boxDataB, 1, 1) self.infoBoxDataB = gui.widgetLabel(boxDataB, self.dataInfoText(None)) gui.rubber(self)
def __setupUi(self): layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setContentsMargins(0, 0, 0, 0) heading = self.tr("Preview") heading = "<h3>{0}</h3>".format(heading) self.__heading = QLabel(heading, self, objectName="heading") self.__heading.setContentsMargins(12, 12, 12, 0) self.__browser = previewbrowser.PreviewBrowser(self) self.__buttons = QDialogButtonBox(QDialogButtonBox.Open | \ QDialogButtonBox.Cancel, Qt.Horizontal,) self.__buttons.button(QDialogButtonBox.Open).setAutoDefault(True) # Set the Open dialog as disabled until the current index changes self.__buttons.button(QDialogButtonBox.Open).setEnabled(False) # The QDialogButtonsWidget messes with the layout if it is # contained directly in the QDialog. So we create an extra # layer of indirection. buttons = QWidget(objectName="button-container") buttons_l = QVBoxLayout() buttons_l.setContentsMargins(12, 0, 12, 12) buttons.setLayout(buttons_l) buttons_l.addWidget(self.__buttons) layout.addWidget(self.__heading) layout.addWidget(self.__browser) layout.addWidget(buttons) self.__buttons.accepted.connect(self.accept) self.__buttons.rejected.connect(self.reject) self.__browser.currentIndexChanged.connect( self.__on_currentIndexChanged ) self.__browser.activated.connect(self.__on_activated) layout.setSizeConstraint(QVBoxLayout.SetFixedSize) self.setLayout(layout) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
def __init__(self, parent=None, **kwargs): super().__init__(parent, acceptDrops=True, **kwargs) self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.addonwidget = AddonManagerWidget() self.layout().addWidget(self.addonwidget) info_bar = QWidget() info_layout = QHBoxLayout() info_bar.setLayout(info_layout) self.layout().addWidget(info_bar) buttons = QDialogButtonBox( orientation=Qt.Horizontal, standardButtons=QDialogButtonBox.Ok | QDialogButtonBox.Cancel, ) addmore = QPushButton( "Add more...", toolTip="Add an add-on not listed below", autoDefault=False ) self.addonwidget.tophlayout.addWidget(addmore) addmore.clicked.connect(self.__run_add_package_dialog) buttons.accepted.connect(self.__accepted) buttons.rejected.connect(self.reject) self.layout().addWidget(buttons) self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=1) if AddonManagerDialog._packages is None: self._f_pypi_addons = self._executor.submit(list_available_versions) else: self._f_pypi_addons = concurrent.futures.Future() self._f_pypi_addons.set_result(AddonManagerDialog._packages) self._f_pypi_addons.add_done_callback( method_queued(self._set_packages, (object,)) ) self.__progress = None # type: Optional[QProgressDialog] self.__thread = None self.__installer = None if not self._f_pypi_addons.done(): self.__progressDialog()
def test_widgettoolgrid(self): w = QWidget() layout = QHBoxLayout() reg = global_registry() qt_reg = QtWidgetRegistry(reg) triggered_actions1 = [] triggered_actions2 = [] model = qt_reg.model() data_descriptions = qt_reg.widgets("Data") file_action = qt_reg.action_for_widget( "Orange.widgets.data.owfile.OWFile" ) actions = list(map(qt_reg.action_for_widget, data_descriptions)) grid = ToolGrid(w) grid.setActions(actions) grid.actionTriggered.connect(triggered_actions1.append) layout.addWidget(grid) grid = WidgetToolGrid(w) # First category ("Data") grid.setModel(model, rootIndex=model.index(0, 0)) self.assertIs(model, grid.model()) # Test order of buttons grid_layout = grid.layout() for i in range(len(actions)): button = grid_layout.itemAtPosition(i / 4, i % 4).widget() self.assertIs(button.defaultAction(), actions[i]) grid.actionTriggered.connect(triggered_actions2.append) layout.addWidget(grid) w.setLayout(layout) w.show() file_action.trigger() self.app.exec_()
def _fullscreen_to_maximized(geometry): """Don't restore windows into full screen mode because it loses decorations and can't be de-fullscreened at least on some platforms. Use Maximized state insted.""" w = QWidget(visible=False) w.restoreGeometry(QByteArray(geometry)) if w.isFullScreen(): w.setWindowState( w.windowState() & ~Qt.WindowFullScreen | Qt.WindowMaximized) return w.saveGeometry()
def test1(self): class FT(QToolBar): def paintEvent(self, e): pass w = QMainWindow() ftt, ftb = FT(), FT() ftt.setFixedHeight(15) ftb.setFixedHeight(15) w.addToolBar(Qt.TopToolBarArea, ftt) w.addToolBar(Qt.BottomToolBarArea, ftb) f = dropshadow.DropShadowFrame() te = QTextEdit() c = QWidget() c.setLayout(QVBoxLayout()) c.layout().setContentsMargins(20, 0, 20, 0) c.layout().addWidget(te) w.setCentralWidget(c) f.setWidget(te) f.radius = 15 f.color = QColor(Qt.blue) w.show() self.singleShot(3000, lambda: f.setColor(Qt.red)) self.singleShot(4000, lambda: f.setRadius(30)) self.singleShot(5000, lambda: f.setRadius(40)) self.app.exec_()
def test_layout(self): container = QWidget() container.setLayout(QHBoxLayout()) container1 = QWidget() container.layout().addWidget(container1) container.show() QTest.qWaitForWindowExposed(container) container.resize(600, 600) overlay = OverlayWidget(parent=container) overlay.setWidget(container) overlay.resize(20, 20) overlay.show() center = overlay.geometry().center() self.assertTrue(290 < center.x() < 310) self.assertTrue(290 < center.y() < 310) overlay.setAlignment(Qt.AlignTop | Qt.AlignHCenter) geom = overlay.geometry() self.assertEqual(geom.top(), 0) self.assertTrue(290 < geom.center().x() < 310) overlay.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) geom = overlay.geometry() self.assertEqual(geom.left(), 0) self.assertTrue(290 < geom.center().y() < 310) overlay.setAlignment(Qt.AlignBottom | Qt.AlignRight) geom = overlay.geometry() self.assertEqual(geom.right(), 600 - 1) self.assertEqual(geom.bottom(), 600 - 1) overlay.setWidget(container1) geom = overlay.geometry() self.assertEqual(geom.right(), container1.geometry().right()) self.assertEqual(geom.bottom(), container1.geometry().bottom())
def leaveEvent(self, event): self.__sloppyButton = None self.__sloppyRegion = QRegion() return QWidget.leaveEvent(self, event)
def hide(self): """ Hide the control """ QWidget.hide(self)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) form = self.layout().itemAt(0) assert isinstance(form, QFormLayout) self.ordered_cb = QCheckBox("Ordered", self, toolTip="Is this an ordered categorical.") self.ordered_cb.toggled.connect(self._set_ordered) #: A list model of discrete variable's values. self.values_model = itemmodels.PyListModel( flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) vlayout = QVBoxLayout(spacing=1, margin=0) self.values_edit = QListView(editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed) self.values_edit.setItemDelegate(CategoriesEditDelegate(self)) self.values_edit.setModel(self.values_model) self.values_model.dataChanged.connect(self.on_values_changed) self.values_edit.selectionModel().selectionChanged.connect( self.on_value_selection_changed) self.values_model.layoutChanged.connect( self.on_value_selection_changed) self.values_model.rowsMoved.connect(self.on_value_selection_changed) vlayout.addWidget(self.values_edit) hlayout = QHBoxLayout(spacing=1, margin=0) self.categories_action_group = group = QActionGroup( self, objectName="action-group-categories", enabled=False) self.move_value_up = QAction( "\N{UPWARDS ARROW}", group, toolTip="Move the selected item up.", shortcut=QKeySequence(Qt.ControlModifier | Qt.AltModifier | Qt.Key_BracketLeft), shortcutContext=Qt.WidgetShortcut, ) self.move_value_up.triggered.connect(self.move_up) self.move_value_down = QAction( "\N{DOWNWARDS ARROW}", group, toolTip="Move the selected item down.", shortcut=QKeySequence(Qt.ControlModifier | Qt.AltModifier | Qt.Key_BracketRight), shortcutContext=Qt.WidgetShortcut, ) self.move_value_down.triggered.connect(self.move_down) self.add_new_item = QAction( "+", group, objectName="action-add-item", toolTip="Append a new item.", shortcut=QKeySequence(QKeySequence.New), shortcutContext=Qt.WidgetShortcut, ) self.remove_item = QAction( "\N{MINUS SIGN}", group, objectName="action-remove-item", toolTip="Delete the selected item.", shortcut=QKeySequence(QKeySequence.Delete), shortcutContext=Qt.WidgetShortcut, ) self.add_new_item.triggered.connect(self._add_category) self.remove_item.triggered.connect(self._remove_category) button1 = FixedSizeButton(self, defaultAction=self.move_value_up, accessibleName="Move up") button2 = FixedSizeButton(self, defaultAction=self.move_value_down, accessibleName="Move down") button3 = FixedSizeButton(self, defaultAction=self.add_new_item, accessibleName="Add") button4 = FixedSizeButton(self, defaultAction=self.remove_item, accessibleName="Remove") self.values_edit.addActions([ self.move_value_up, self.move_value_down, self.add_new_item, self.remove_item ]) hlayout.addWidget(button1) hlayout.addWidget(button2) hlayout.addSpacing(3) hlayout.addWidget(button3) hlayout.addWidget(button4) hlayout.addStretch(10) vlayout.addLayout(hlayout) form.insertRow(1, "", self.ordered_cb) form.insertRow(2, "Values:", vlayout) QWidget.setTabOrder(self.name_edit, self.ordered_cb) QWidget.setTabOrder(self.ordered_cb, self.values_edit) QWidget.setTabOrder(self.values_edit, button1) QWidget.setTabOrder(button1, button2) QWidget.setTabOrder(button2, button3) QWidget.setTabOrder(button3, button4)
def __init__(self, data): icon = QApplication.style().standardIcon(QStyle.SP_MessageBoxWarning) F = self.DataField def _finished(*, key=(data.get(F.MODULE), data.get(F.WIDGET_MODULE)), filename=data.get(F.WIDGET_SCHEME)): self._cache.add(key) try: os.remove(filename) except Exception: pass super().__init__(None, Qt.Window, modal=True, sizeGripEnabled=True, windowIcon=icon, windowTitle='Unexpected Error', finished=_finished) self._data = data layout = QVBoxLayout(self) self.setLayout(layout) labels = QWidget(self) labels_layout = QHBoxLayout(self) labels.setLayout(labels_layout) labels_layout.addWidget(QLabel(pixmap=icon.pixmap(50, 50))) labels_layout.addWidget( QLabel('The program encountered an unexpected error. Please<br>' 'report it anonymously to the developers.<br><br>' 'The following data will be reported:')) labels_layout.addStretch(1) layout.addWidget(labels) font = QFont('Monospace', 10) font.setStyleHint(QFont.Monospace) font.setFixedPitch(True) textbrowser = QTextBrowser(self, font=font, openLinks=False, lineWrapMode=QTextBrowser.NoWrap, anchorClicked=QDesktopServices.openUrl) layout.addWidget(textbrowser) def _reload_text(): add_scheme = cb.isChecked() settings.setValue('error-reporting/add-scheme', add_scheme) lines = ['<table>'] for k, v in data.items(): if k.startswith('_'): continue _v, v = v, escape(str(v)) if k == F.WIDGET_SCHEME: if not add_scheme: continue v = '<a href="{}">{}</a>'.format( urljoin('file:', pathname2url(_v)), v) if k in (F.STACK_TRACE, F.LOCALS): v = v.replace('\n', '<br>').replace(' ', ' ') lines.append( '<tr><th align="left">{}:</th><td>{}</td></tr>'.format( k, v)) lines.append('</table>') textbrowser.setHtml(''.join(lines)) settings = QSettings() cb = QCheckBox('Include workflow (data will NOT be transmitted)', self, checked=settings.value('error-reporting/add-scheme', True, type=bool)) cb.stateChanged.connect(_reload_text) _reload_text() layout.addWidget(cb) buttons = QWidget(self) buttons_layout = QHBoxLayout(self) buttons.setLayout(buttons_layout) buttons_layout.addWidget( QPushButton('Send Report (Thanks!)', default=True, clicked=self.accept)) buttons_layout.addWidget( QPushButton("Don't Send", default=False, clicked=self.reject)) layout.addWidget(buttons)
def __init__(self): super().__init__() self.data = None self.features = None # Schedule interface updates (enabled buttons) using a coalescing # single shot timer (complex interactions on selection and filtering # updates in the 'available_attrs_view') self.__interface_update_timer = QTimer(self, interval=0, singleShot=True) self.__interface_update_timer.timeout.connect( self.__update_interface_state) # The last view that has the selection for move operation's source self.__last_active_view = None # type: Optional[QListView] def update_on_change(view): # Schedule interface state update on selection change in `view` self.__last_active_view = view self.__interface_update_timer.start() new_control_area = QWidget(self.controlArea) self.controlArea.layout().addWidget(new_control_area) self.controlArea = new_control_area # init grid layout = QGridLayout() self.controlArea.setLayout(layout) layout.setContentsMargins(0, 0, 0, 0) box = gui.vBox(self.controlArea, "Ignored", addToLayout=False) self.available_attrs = VariablesListItemModel() filter_edit, self.available_attrs_view = variables_filter( parent=self, model=self.available_attrs) box.layout().addWidget(filter_edit) def dropcompleted(action): if action == Qt.MoveAction: self.commit.deferred() self.available_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.available_attrs_view)) self.available_attrs_view.dragDropActionDidComplete.connect( dropcompleted) box.layout().addWidget(self.available_attrs_view) layout.addWidget(box, 0, 0, 3, 1) # 3rd column box = gui.vBox(self.controlArea, "Features", addToLayout=False) self.used_attrs = VariablesListItemModel() filter_edit, self.used_attrs_view = variables_filter( parent=self, model=self.used_attrs, accepted_type=(Orange.data.DiscreteVariable, Orange.data.ContinuousVariable)) self.used_attrs.rowsInserted.connect(self.__used_attrs_changed) self.used_attrs.rowsRemoved.connect(self.__used_attrs_changed) self.used_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.used_attrs_view)) self.used_attrs_view.dragDropActionDidComplete.connect(dropcompleted) self.use_features_box = gui.auto_commit( self.controlArea, self, "use_input_features", "Use input features", "Always use input features", box=False, commit=self.__use_features_clicked, callback=self.__use_features_changed, addToLayout=False) self.enable_use_features_box() box.layout().addWidget(self.use_features_box) box.layout().addWidget(filter_edit) box.layout().addWidget(self.used_attrs_view) layout.addWidget(box, 0, 2, 1, 1) box = gui.vBox(self.controlArea, "Target", addToLayout=False) self.class_attrs = VariablesListItemModel() self.class_attrs_view = VariablesListItemView( acceptedType=(Orange.data.DiscreteVariable, Orange.data.ContinuousVariable)) self.class_attrs_view.setModel(self.class_attrs) self.class_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.class_attrs_view)) self.class_attrs_view.dragDropActionDidComplete.connect(dropcompleted) box.layout().addWidget(self.class_attrs_view) layout.addWidget(box, 1, 2, 1, 1) box = gui.vBox(self.controlArea, "Metas", addToLayout=False) self.meta_attrs = VariablesListItemModel() self.meta_attrs_view = VariablesListItemView( acceptedType=Orange.data.Variable) self.meta_attrs_view.setModel(self.meta_attrs) self.meta_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.meta_attrs_view)) self.meta_attrs_view.dragDropActionDidComplete.connect(dropcompleted) box.layout().addWidget(self.meta_attrs_view) layout.addWidget(box, 2, 2, 1, 1) # 2nd column bbox = gui.vBox(self.controlArea, addToLayout=False, margin=0) self.move_attr_button = gui.button(bbox, self, ">", callback=partial( self.move_selected, self.used_attrs_view)) layout.addWidget(bbox, 0, 1, 1, 1) bbox = gui.vBox(self.controlArea, addToLayout=False, margin=0) self.move_class_button = gui.button(bbox, self, ">", callback=partial( self.move_selected, self.class_attrs_view)) layout.addWidget(bbox, 1, 1, 1, 1) bbox = gui.vBox(self.controlArea, addToLayout=False) self.move_meta_button = gui.button(bbox, self, ">", callback=partial( self.move_selected, self.meta_attrs_view)) layout.addWidget(bbox, 2, 1, 1, 1) # footer gui.button(self.buttonsArea, self, "Reset", callback=self.reset) bbox = gui.vBox(self.buttonsArea) gui.checkBox( widget=bbox, master=self, value="ignore_new_features", label="Ignore new variables by default", tooltip="When the widget receives data with additional columns " "they are added to the available attributes column if " "<i>Ignore new variables by default</i> is checked.") gui.rubber(self.buttonsArea) gui.auto_send(self.buttonsArea, self, "auto_commit") layout.setRowStretch(0, 2) layout.setRowStretch(1, 0) layout.setRowStretch(2, 1) layout.setHorizontalSpacing(0) self.controlArea.setLayout(layout) self.output_data = None self.original_completer_items = [] self.resize(600, 600)
def __init__(self): super().__init__() self.data = None # The following lists are of the same length as self.active_rules #: list of pairs with counts of matches for each patter when the # patterns are applied in order and when applied on the entire set, # disregarding the preceding patterns self.match_counts = [] #: list of list of QLineEdit: line edit pairs for each pattern self.line_edits = [] #: list of QPushButton: list of remove buttons self.remove_buttons = [] #: list of list of QLabel: pairs of labels with counts self.counts = [] gui.lineEdit(self.controlArea, self, "class_name", orientation=Qt.Horizontal, box="New Class Name") variable_select_box = gui.vBox(self.controlArea, "Match by Substring") combo = gui.comboBox(variable_select_box, self, "attribute", label="From column:", orientation=Qt.Horizontal, searchable=True, callback=self.update_rules, model=DomainModel(valid_types=(StringVariable, DiscreteVariable))) # Don't use setSizePolicy keyword argument here: it applies to box, # not the combo combo.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred) patternbox = gui.vBox(variable_select_box) #: QWidget: the box that contains the remove buttons, line edits and # count labels. The lines are added and removed dynamically. self.rules_box = rules_box = QGridLayout() rules_box.setSpacing(4) rules_box.setContentsMargins(4, 4, 4, 4) self.rules_box.setColumnMinimumWidth(1, 70) self.rules_box.setColumnMinimumWidth(0, 10) self.rules_box.setColumnStretch(0, 1) self.rules_box.setColumnStretch(1, 1) self.rules_box.setColumnStretch(2, 100) rules_box.addWidget(QLabel("Name"), 0, 1) rules_box.addWidget(QLabel("Substring"), 0, 2) rules_box.addWidget(QLabel("Count"), 0, 3, 1, 2) self.update_rules() widget = QWidget(patternbox) widget.setLayout(rules_box) patternbox.layout().addWidget(widget) box = gui.hBox(patternbox) gui.rubber(box) gui.button(box, self, "+", callback=self.add_row, autoDefault=False, width=34, sizePolicy=(QSizePolicy.Maximum, QSizePolicy.Maximum)) optionsbox = gui.vBox(self.controlArea, "Options") gui.checkBox(optionsbox, self, "match_beginning", "Match only at the beginning", callback=self.options_changed) gui.checkBox(optionsbox, self, "case_sensitive", "Case sensitive", callback=self.options_changed) gui.rubber(self.controlArea) gui.button(self.buttonsArea, self, "Apply", callback=self.apply) self.info.set_input_summary(self.info.NoInput) self.info.set_output_summary(self.info.NoOutput) # TODO: Resizing upon changing the number of rules does not work self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
class TestOverlay(GuiTest): def setUp(self) -> None: self.container = QWidget() stdb = NotificationWidget.Ok | NotificationWidget.Close self.overlay = NotificationOverlay(self.container) self.notif = NotificationWidget(title="lol", text="hihi", standardButtons=stdb) self.container.show() QTest.qWaitForWindowExposed(self.container) self.overlay.show() QTest.qWaitForWindowExposed(self.overlay) def tearDown(self) -> None: NotificationOverlay.overlayInstances = [] NotificationOverlay.notifQueue = [] self.container = None self.overlay = None self.notif = None def test_notification_dismiss(self): mock = unittest.mock.MagicMock() self.notif.clicked.connect(mock) NotificationOverlay.registerNotification(self.notif) QTest.mouseClick(self.notif._dismiss_button, Qt.LeftButton) mock.assert_called_once_with(self.notif._dismiss_button) def test_notification_message(self): self.notif.setText("Hello world! It's so nice here") QApplication.sendPostedEvents(self.notif, QEvent.LayoutRequest) self.assertTrue(self.notif.geometry().isValid()) button_ok = self.notif.button(NotificationWidget.Ok) button_close = self.notif.button(NotificationWidget.Close) self.assertTrue(all([button_ok, button_close])) self.assertIs(self.notif.button(NotificationWidget.Ok), button_ok) self.assertIs(self.notif.button(NotificationWidget.Close), button_close) button = self.notif.button(NotificationWidget.Ok) self.assertIsNot(button, None) self.assertTrue(self.notif.buttonRole(button), NotificationWidget.AcceptRole) mock = unittest.mock.MagicMock() self.notif.accepted.connect(mock) NotificationOverlay.registerNotification(self.notif) cloned = NotificationOverlay.overlayInstances[0].currentWidget() self.assertTrue(cloned.isVisible()) button = cloned._msgwidget.button(NotificationWidget.Ok) QTest.mouseClick(button, Qt.LeftButton) self.assertFalse(cloned.isVisible()) mock.assert_called_once() def test_queued_notifications(self): surveyDialogButtons = NotificationWidget.Ok | NotificationWidget.Close surveyDialog = NotificationWidget( title="Survey", text="We want to understand our users better.\n" "Would you like to take a short survey?", standardButtons=surveyDialogButtons) def handle_survey_response(b): self.assertEqual(self.notif.buttonRole(b), NotificationWidget.DismissRole) self.notif.clicked.connect(handle_survey_response) NotificationOverlay.registerNotification(self.notif) notif1 = NotificationOverlay.overlayInstances[0]._widgets[0] button = notif1._dismiss_button NotificationOverlay.registerNotification(surveyDialog) notif2 = NotificationOverlay.overlayInstances[0]._widgets[1] self.assertTrue(notif1.isVisible()) self.assertFalse(notif2.isVisible()) QTest.mouseClick(button, Qt.LeftButton) self.assertFalse(notif1.isVisible()) self.assertTrue(notif2.isVisible())
def setUpClass(cls): super().setUpClass() cls.parent = QWidget()
def __init__(self): super().__init__() #: widget's runtime state self.__state = State.NoState self.base_corpus = None self.corpus = None self.n_text_categories = 0 self.n_text_data = 0 self.skipped_documents = [] self.is_conllu = False self.tokens = None self.pos = None self.ner = None self.__invalidated = False self.__pendingTask = None layout = QGridLayout() layout.setSpacing(4) gui.widgetBox(self.controlArea, orientation=layout, box='Source') source_box = gui.radioButtons(None, self, "source", box=True, callback=self.start, addToLayout=False) rb_button = gui.appendRadioButton(source_box, "Folder:", addToLayout=False) layout.addWidget(rb_button, 0, 0, Qt.AlignVCenter) box = gui.hBox(None, addToLayout=False, margin=0) box.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.recent_cb = QComboBox( sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon, minimumContentsLength=16, acceptDrops=True) self.recent_cb.installEventFilter(self) self.recent_cb.activated[int].connect(self.__onRecentActivated) browseaction = QAction( "Open/Load Documents", self, iconText="\N{HORIZONTAL ELLIPSIS}", icon=self.style().standardIcon(QStyle.SP_DirOpenIcon), toolTip="Select a folder from which to load the documents") browseaction.triggered.connect(self.__runOpenDialog) reloadaction = QAction("Reload", self, icon=self.style().standardIcon( QStyle.SP_BrowserReload), toolTip="Reload current document set") reloadaction.triggered.connect(self.reload) self.__actions = namespace( browse=browseaction, reload=reloadaction, ) browsebutton = QPushButton( browseaction.iconText(), icon=browseaction.icon(), toolTip=browseaction.toolTip(), clicked=browseaction.trigger, default=False, autoDefault=False, ) reloadbutton = QPushButton( reloadaction.iconText(), icon=reloadaction.icon(), clicked=reloadaction.trigger, default=False, autoDefault=False, ) box.layout().addWidget(self.recent_cb) layout.addWidget(box, 0, 1) layout.addWidget(browsebutton, 0, 2) layout.addWidget(reloadbutton, 0, 3) rb_button = gui.appendRadioButton(source_box, "URL:", addToLayout=False) layout.addWidget(rb_button, 3, 0, Qt.AlignVCenter) self.url_combo = url_combo = QComboBox() url_model = PyListModel() url_model.wrap(self.recent_urls) url_combo.setLineEdit(LineEditSelectOnFocus()) url_combo.setModel(url_model) url_combo.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) url_combo.setEditable(True) url_combo.setInsertPolicy(url_combo.InsertAtTop) url_edit = url_combo.lineEdit() m = url_edit.textMargins() url_edit.setTextMargins(m.left() + 5, m.top(), m.right(), m.bottom()) layout.addWidget(url_combo, 3, 1, 1, 3) url_combo.activated.connect(self._url_set) # whit completer we set that combo box is case sensitive when # matching the history completer = QCompleter() completer.setCaseSensitivity(Qt.CaseSensitive) url_combo.setCompleter(completer) self.addActions([browseaction, reloadaction]) reloadaction.changed.connect( lambda: reloadbutton.setEnabled(reloadaction.isEnabled())) box = gui.hBox(self.controlArea, "Conllu import options") gui.checkBox(box, self, "lemma_cb", "Lemma", callback=self.commit) gui.checkBox(box, self, "pos_cb", "POS tags", callback=self.commit) gui.checkBox(box, self, "ner_cb", "NER", callback=self.commit) self.controlArea.layout().addWidget(box) box = gui.vBox(self.controlArea, "Info") self.infostack = QStackedWidget() self.info_area = QLabel(text="No document set selected", wordWrap=True) self.progress_widget = QProgressBar(minimum=0, maximum=100) self.cancel_button = QPushButton( "Cancel", icon=self.style().standardIcon(QStyle.SP_DialogCancelButton), default=False, autoDefault=False, ) self.cancel_button.clicked.connect(self.cancel) w = QWidget() vlayout = QVBoxLayout() vlayout.setContentsMargins(0, 0, 0, 0) hlayout = QHBoxLayout() hlayout.setContentsMargins(0, 0, 0, 0) hlayout.addWidget(self.progress_widget) hlayout.addWidget(self.cancel_button) vlayout.addLayout(hlayout) self.pathlabel = TextLabel() self.pathlabel.setTextElideMode(Qt.ElideMiddle) self.pathlabel.setAttribute(Qt.WA_MacSmallSize) vlayout.addWidget(self.pathlabel) w.setLayout(vlayout) self.infostack.addWidget(self.info_area) self.infostack.addWidget(w) box.layout().addWidget(self.infostack) self.__initRecentItemsModel() self.__invalidated = True self.__executor = ThreadExecutor(self) QApplication.postEvent(self, QEvent(RuntimeEvent.Init))
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) w = self.widget(0) # 'General' tab layout = w.layout() assert isinstance(layout, QFormLayout) cb = QCheckBox(self.tr("Automatically check for updates")) cb.setAttribute(Qt.WA_LayoutUsesWidgetRect) layout.addRow("Updates", cb) self.bind(cb, "checked", "startup/check-updates") # Error Reporting Tab tab = QWidget() self.addTab(tab, self.tr("Error Reporting"), toolTip="Settings related to error reporting") form = QFormLayout() line_edit_mid = QLineEdit() self.bind(line_edit_mid, "text", "error-reporting/machine-id") form.addRow("Machine ID:", line_edit_mid) box = QWidget() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) cb1 = QCheckBox( self.tr(""), toolTip=self.tr( "Share anonymous usage statistics to improve Orange")) self.bind(cb1, "checked", "error-reporting/send-statistics") cb1.clicked.connect(UsageStatistics.set_enabled) layout.addWidget(cb1) box.setLayout(layout) form.addRow(self.tr("Share Anonymous Statistics"), box) tab.setLayout(form) # Notifications Tab tab = QWidget() self.addTab(tab, self.tr("Notifications"), toolTip="Settings related to notifications") form = QFormLayout() notifs = QWidget(self, objectName="notifications-group") notifs.setLayout(QVBoxLayout()) notifs.layout().setContentsMargins(0, 0, 0, 0) cb1 = QCheckBox( self.tr("Announcements"), self, toolTip="Show notifications about Biolab announcements.\n" "This entails events and courses hosted by the developers of " "Orange.") cb2 = QCheckBox(self.tr("Blog posts"), self, toolTip="Show notifications about blog posts.\n" "We'll only send you the highlights.") cb3 = QCheckBox( self.tr("New features"), self, toolTip="Show notifications about new features in Orange when a new " "version is downloaded and installed, should the new version " "entail notable updates.") self.bind(cb1, "checked", "notifications/announcements") self.bind(cb2, "checked", "notifications/blog") self.bind(cb3, "checked", "notifications/new-features") notifs.layout().addWidget(cb1) notifs.layout().addWidget(cb2) notifs.layout().addWidget(cb3) form.addRow(self.tr("Show notifications about"), notifs) tab.setLayout(form)
class OWSelectAttributes(widget.OWWidget): # pylint: disable=too-many-instance-attributes name = "Select Columns" description = "Select columns from the data table and assign them to " \ "data features, classes or meta variables." icon = "icons/SelectColumns.svg" priority = 100 keywords = ["filter", "attributes", "target", "variable"] class Inputs: data = Input("Data", Table, default=True) features = Input("Features", AttributeList) class Outputs: data = Output("Data", Table) features = Output("Features", AttributeList, dynamic=False) want_main_area = False want_control_area = True settingsHandler = SelectAttributesDomainContextHandler(first_match=False) domain_role_hints = ContextSetting({}) use_input_features = Setting(False) auto_commit = Setting(True) class Warning(widget.OWWidget.Warning): mismatching_domain = Msg("Features and data domain do not match") def __init__(self): super().__init__() self.data = None self.features = None # Schedule interface updates (enabled buttons) using a coalescing # single shot timer (complex interactions on selection and filtering # updates in the 'available_attrs_view') self.__interface_update_timer = QTimer(self, interval=0, singleShot=True) self.__interface_update_timer.timeout.connect( self.__update_interface_state) # The last view that has the selection for move operation's source self.__last_active_view = None # type: Optional[QListView] def update_on_change(view): # Schedule interface state update on selection change in `view` self.__last_active_view = view self.__interface_update_timer.start() self.controlArea = QWidget(self.controlArea) self.layout().addWidget(self.controlArea) layout = QGridLayout() self.controlArea.setLayout(layout) layout.setContentsMargins(4, 4, 4, 4) box = gui.vBox(self.controlArea, "Available Variables", addToLayout=False) self.available_attrs = VariablesListItemModel() filter_edit, self.available_attrs_view = variables_filter( parent=self, model=self.available_attrs) box.layout().addWidget(filter_edit) def dropcompleted(action): if action == Qt.MoveAction: self.commit() self.available_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.available_attrs_view)) self.available_attrs_view.dragDropActionDidComplete.connect( dropcompleted) box.layout().addWidget(self.available_attrs_view) layout.addWidget(box, 0, 0, 3, 1) box = gui.vBox(self.controlArea, "Features", addToLayout=False) self.used_attrs = VariablesListItemModel() filter_edit, self.used_attrs_view = variables_filter( parent=self, model=self.used_attrs, accepted_type=(Orange.data.DiscreteVariable, Orange.data.ContinuousVariable)) self.used_attrs.rowsInserted.connect(self.__used_attrs_changed) self.used_attrs.rowsRemoved.connect(self.__used_attrs_changed) self.used_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.used_attrs_view)) self.used_attrs_view.dragDropActionDidComplete.connect(dropcompleted) self.use_features_box = gui.auto_commit( self.controlArea, self, "use_input_features", "Use input features", "Always use input features", box=False, commit=self.__use_features_clicked, callback=self.__use_features_changed, addToLayout=False) self.enable_use_features_box() box.layout().addWidget(self.use_features_box) box.layout().addWidget(filter_edit) box.layout().addWidget(self.used_attrs_view) layout.addWidget(box, 0, 2, 1, 1) box = gui.vBox(self.controlArea, "Target Variable", addToLayout=False) self.class_attrs = VariablesListItemModel() self.class_attrs_view = VariablesListItemView( acceptedType=(Orange.data.DiscreteVariable, Orange.data.ContinuousVariable)) self.class_attrs_view.setModel(self.class_attrs) self.class_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.class_attrs_view)) self.class_attrs_view.dragDropActionDidComplete.connect(dropcompleted) self.class_attrs_view.setMaximumHeight(72) box.layout().addWidget(self.class_attrs_view) layout.addWidget(box, 1, 2, 1, 1) box = gui.vBox(self.controlArea, "Meta Attributes", addToLayout=False) self.meta_attrs = VariablesListItemModel() self.meta_attrs_view = VariablesListItemView( acceptedType=Orange.data.Variable) self.meta_attrs_view.setModel(self.meta_attrs) self.meta_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.meta_attrs_view)) self.meta_attrs_view.dragDropActionDidComplete.connect(dropcompleted) box.layout().addWidget(self.meta_attrs_view) layout.addWidget(box, 2, 2, 1, 1) bbox = gui.vBox(self.controlArea, addToLayout=False, margin=0) layout.addWidget(bbox, 0, 1, 1, 1) self.up_attr_button = gui.button(bbox, self, "Up", callback=partial( self.move_up, self.used_attrs_view)) self.move_attr_button = gui.button(bbox, self, ">", callback=partial( self.move_selected, self.used_attrs_view)) self.down_attr_button = gui.button(bbox, self, "Down", callback=partial( self.move_down, self.used_attrs_view)) bbox = gui.vBox(self.controlArea, addToLayout=False, margin=0) layout.addWidget(bbox, 1, 1, 1, 1) self.up_class_button = gui.button(bbox, self, "Up", callback=partial( self.move_up, self.class_attrs_view)) self.move_class_button = gui.button(bbox, self, ">", callback=partial( self.move_selected, self.class_attrs_view)) self.down_class_button = gui.button(bbox, self, "Down", callback=partial( self.move_down, self.class_attrs_view)) bbox = gui.vBox(self.controlArea, addToLayout=False, margin=0) layout.addWidget(bbox, 2, 1, 1, 1) self.up_meta_button = gui.button(bbox, self, "Up", callback=partial( self.move_up, self.meta_attrs_view)) self.move_meta_button = gui.button(bbox, self, ">", callback=partial( self.move_selected, self.meta_attrs_view)) self.down_meta_button = gui.button(bbox, self, "Down", callback=partial( self.move_down, self.meta_attrs_view)) autobox = gui.auto_send(None, self, "auto_commit") layout.addWidget(autobox, 3, 0, 1, 3) reset = gui.button(None, self, "Reset", callback=self.reset, width=120) autobox.layout().insertWidget(0, reset) autobox.layout().insertStretch(1, 20) layout.setRowStretch(0, 4) layout.setRowStretch(1, 0) layout.setRowStretch(2, 2) layout.setHorizontalSpacing(0) self.controlArea.setLayout(layout) self.output_data = None self.original_completer_items = [] self.info.set_input_summary(self.info.NoInput) self.info.set_output_summary(self.info.NoOutput) self.resize(600, 600) @property def features_from_data_attributes(self): if self.data is None or self.features is None: return [] domain = self.data.domain return [ domain[feature.name] for feature in self.features if feature.name in domain and domain[feature.name] in domain.attributes ] def can_use_features(self): return bool(self.features_from_data_attributes) and \ self.features_from_data_attributes != self.used_attrs[:] def __use_features_changed(self): # Use input features check box # Needs a check since callback is invoked before object is created if not hasattr(self, "use_features_box"): return self.enable_used_attrs(not self.use_input_features) if self.use_input_features and self.can_use_features(): self.use_features() if not self.use_input_features: self.enable_use_features_box() def __use_features_clicked(self): # Use input features button self.use_features() def __used_attrs_changed(self): self.enable_use_features_box() @Inputs.data def set_data(self, data=None): self.update_domain_role_hints() self.closeContext() self.domain_role_hints = {} self.data = data if data is None: self.used_attrs[:] = [] self.class_attrs[:] = [] self.meta_attrs[:] = [] self.available_attrs[:] = [] self.info.set_input_summary(self.info.NoInput) return self.openContext(data) all_vars = data.domain.variables + data.domain.metas def attrs_for_role(role): selected_attrs = [ attr for attr in all_vars if domain_hints[attr][0] == role ] return sorted(selected_attrs, key=lambda attr: domain_hints[attr][1]) domain = data.domain domain_hints = {} domain_hints.update( self._hints_from_seq("attribute", domain.attributes)) domain_hints.update(self._hints_from_seq("meta", domain.metas)) domain_hints.update(self._hints_from_seq("class", domain.class_vars)) domain_hints.update(self.domain_role_hints) self.used_attrs[:] = attrs_for_role("attribute") self.class_attrs[:] = attrs_for_role("class") self.meta_attrs[:] = attrs_for_role("meta") self.available_attrs[:] = attrs_for_role("available") self.info.set_input_summary(len(data), format_summary_details(data)) def update_domain_role_hints(self): """ Update the domain hints to be stored in the widgets settings. """ hints = {} hints.update(self._hints_from_seq("available", self.available_attrs)) hints.update(self._hints_from_seq("attribute", self.used_attrs)) hints.update(self._hints_from_seq("class", self.class_attrs)) hints.update(self._hints_from_seq("meta", self.meta_attrs)) self.domain_role_hints = hints @staticmethod def _hints_from_seq(role, model): return [(attr, (role, i)) for i, attr in enumerate(model)] @Inputs.features def set_features(self, features): self.features = features def handleNewSignals(self): self.check_data() self.enable_used_attrs() self.enable_use_features_box() if self.use_input_features and self.features_from_data_attributes: self.enable_used_attrs(False) self.use_features() self.unconditional_commit() def check_data(self): self.Warning.mismatching_domain.clear() if self.data is not None and self.features is not None and \ not self.features_from_data_attributes: self.Warning.mismatching_domain() def enable_used_attrs(self, enable=True): self.up_attr_button.setEnabled(enable) self.move_attr_button.setEnabled(enable) self.down_attr_button.setEnabled(enable) self.used_attrs_view.setEnabled(enable) self.used_attrs_view.repaint() def enable_use_features_box(self): self.use_features_box.button.setEnabled(self.can_use_features()) enable_checkbox = bool(self.features_from_data_attributes) self.use_features_box.setHidden(not enable_checkbox) self.use_features_box.repaint() def use_features(self): attributes = self.features_from_data_attributes available, used = self.available_attrs[:], self.used_attrs[:] self.available_attrs[:] = [ attr for attr in used + available if attr not in attributes ] self.used_attrs[:] = attributes self.commit() @staticmethod def selected_rows(view): """ Return the selected rows in the view. """ rows = view.selectionModel().selectedRows() model = view.model() if isinstance(model, QSortFilterProxyModel): rows = [model.mapToSource(r) for r in rows] return [r.row() for r in rows] def move_rows(self, view: QListView, offset: int, roles=(Qt.EditRole, )): rows = [idx.row() for idx in view.selectionModel().selectedRows()] model = view.model() # type: QAbstractItemModel rowcount = model.rowCount() newrows = [min(max(0, row + offset), rowcount - 1) for row in rows] def itemData(index): return {role: model.data(index, role) for role in roles} for row, newrow in sorted(zip(rows, newrows), reverse=offset > 0): d1 = itemData(model.index(row, 0)) d2 = itemData(model.index(newrow, 0)) model.setItemData(model.index(row, 0), d2) model.setItemData(model.index(newrow, 0), d1) selection = QItemSelection() for nrow in newrows: index = model.index(nrow, 0) selection.select(index, index) view.selectionModel().select(selection, QItemSelectionModel.ClearAndSelect) self.commit() def move_up(self, view: QListView): self.move_rows(view, -1) def move_down(self, view: QListView): self.move_rows(view, 1) def move_selected(self, view): if self.selected_rows(view): self.move_selected_from_to(view, self.available_attrs_view) elif self.selected_rows(self.available_attrs_view): self.move_selected_from_to(self.available_attrs_view, view) def move_selected_from_to(self, src, dst): self.move_from_to(src, dst, self.selected_rows(src)) def move_from_to(self, src, dst, rows): src_model = source_model(src) attrs = [src_model[r] for r in rows] for s1, s2 in reversed(list(slices(rows))): del src_model[s1:s2] dst_model = source_model(dst) dst_model.extend(attrs) self.commit() def __update_interface_state(self): last_view = self.__last_active_view if last_view is not None: self.update_interface_state(last_view) def update_interface_state(self, focus=None): for view in [ self.available_attrs_view, self.used_attrs_view, self.class_attrs_view, self.meta_attrs_view ]: if view is not focus and not view.hasFocus() \ and view.selectionModel().hasSelection(): view.selectionModel().clear() def selected_vars(view): model = source_model(view) return [model[i] for i in self.selected_rows(view)] available_selected = selected_vars(self.available_attrs_view) attrs_selected = selected_vars(self.used_attrs_view) class_selected = selected_vars(self.class_attrs_view) meta_selected = selected_vars(self.meta_attrs_view) available_types = set(map(type, available_selected)) all_primitive = all(var.is_primitive() for var in available_types) move_attr_enabled = \ ((available_selected and all_primitive) or attrs_selected) and \ self.used_attrs_view.isEnabled() self.move_attr_button.setEnabled(bool(move_attr_enabled)) if move_attr_enabled: self.move_attr_button.setText(">" if available_selected else "<") move_class_enabled = bool(all_primitive and available_selected) or class_selected self.move_class_button.setEnabled(bool(move_class_enabled)) if move_class_enabled: self.move_class_button.setText(">" if available_selected else "<") move_meta_enabled = available_selected or meta_selected self.move_meta_button.setEnabled(bool(move_meta_enabled)) if move_meta_enabled: self.move_meta_button.setText(">" if available_selected else "<") self.__last_active_view = None self.__interface_update_timer.stop() def commit(self): self.update_domain_role_hints() if self.data is not None: attributes = list(self.used_attrs) class_var = list(self.class_attrs) metas = list(self.meta_attrs) domain = Orange.data.Domain(attributes, class_var, metas) newdata = self.data.transform(domain) self.output_data = newdata self.Outputs.data.send(newdata) self.Outputs.features.send(AttributeList(attributes)) self.info.set_output_summary(len(newdata), format_summary_details(newdata)) else: self.output_data = None self.Outputs.data.send(None) self.Outputs.features.send(None) self.info.set_output_summary(self.info.NoOutput) def reset(self): self.enable_used_attrs() self.use_features_box.checkbox.setChecked(False) if self.data is not None: self.available_attrs[:] = [] self.used_attrs[:] = self.data.domain.attributes self.class_attrs[:] = self.data.domain.class_vars self.meta_attrs[:] = self.data.domain.metas self.update_domain_role_hints() self.commit() def send_report(self): if not self.data or not self.output_data: return in_domain, out_domain = self.data.domain, self.output_data.domain self.report_domain("Input data", self.data.domain) if (in_domain.attributes, in_domain.class_vars, in_domain.metas) == (out_domain.attributes, out_domain.class_vars, out_domain.metas): self.report_paragraph("Output data", "No changes.") else: self.report_domain("Output data", self.output_data.domain) diff = list( set(in_domain.variables + in_domain.metas) - set(out_domain.variables + out_domain.metas)) if diff: text = "%i (%s)" % (len(diff), ", ".join(x.name for x in diff)) self.report_items((("Removed", text), ))
class ControlVisVis(ControlBase): def init_form(self): self._form = QWidget() layout = QVBoxLayout() if _api.USED_API == _api.QT_API_PYQT5: layout.setContentsMargins(0, 0, 0, 0) else: layout.setMargin(0) self._form.setLayout(layout) self._app = vv.use('pyqt5') self._app.Create() Figure = self._app.GetFigureClass() self._fig = Figure(self._form) policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) widget = self._fig._widget widget.setSizePolicy(policy) layout.addWidget(widget) def refresh(self): vv.figure(self._fig.nr) #self._app = vv.use() self.paint(vv) def paint(self, visvis): vv.clf() colors = ['r', 'g', 'b', 'c', 'm', 'y', 'k'] for index, dataset in enumerate(self._value): l = visvis.plot(dataset, ms='o', mc=colors[index % len(colors)], mw='3', ls='', mew=0) l.alpha = 0.3 self._a = vv.gca() self._a.daspectAuto = True ############################################################################ ############ Properties #################################################### ############################################################################ @property def legend(self): return self._a.legend @legend.setter def legend(self, value): self._a.legend = value @property def show_grid(self): return self._a.axis.showGrid @show_grid.setter def show_grid(self, value): self._a.axis.showGrid = value @property def title(self): return '' @title.setter def title(self, value): vv.title(value) @property def xlabel(self): return self._a.axis.xlabel @xlabel.setter def xlabel(self, value): self._a.axis.xlabel = value @property def ylabel(self): return self._a.axis.ylabel @ylabel.setter def ylabel(self, value): self._a.axis.ylabel = value @property def zlabel(self): return self._a.axis.zlabel @ylabel.setter def zlabel(self, value): self._a.axis.zlabel = value @property def value(self): return None @value.setter def value(self, value): self._value = [] for dataset in value: if len(dataset) > 0: if isinstance(dataset[0], list) or isinstance( dataset[0], tuple): self._value.append(Pointset(np.array(dataset))) else: self._value.append(dataset) self.refresh()
def __init__(self, parent=None): QWidget.__init__(self, parent) self.var = None self.setup_gui()
def setContentsMargins(self, *args, **kwargs): QWidget.setContentsMargins(self, *args, **kwargs) self._updateShadowPixmap()
def changeEvent(self, event): if event.type() == QEvent.FontChange: self.__update() return QWidget.changeEvent(self, event)
def sizeHint(self, which, constraint): return QSizeF(self.width, self.height) def sizePolicy(self): return QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) if __name__ == '__main__': import sys from Orange.data.table import Table from AnyQt.QtWidgets import ( # pylint: disable=ungrouped-imports QGraphicsView, QGraphicsScene, QApplication, QWidget) app = QApplication(sys.argv) widget = QWidget() widget.resize(500, 300) scene = QGraphicsScene(widget) view = QGraphicsView(scene, widget) dataset = Table(sys.argv[1] if len(sys.argv) > 1 else 'iris') histogram = Histogram( dataset, variable=0, height=300, width=500, n_bins=20, bar_spacing=2, border=(0, 0, 5, 0), border_color='#000', color_attribute='iris', )
def __init__(self): super().__init__() self.data = None # type: Optional[Orange.data.Table] self.learner = None # type: Optional[Learner] self.default_learner = SimpleTreeLearner(min_instances=10, max_depth=10) self.modified = False self.executor = qconcurrent.ThreadExecutor(self) self.__task = None main_layout = self.controlArea.layout() box = gui.vBox(self.controlArea, "Default Method") box_layout = QGridLayout() box_layout.setSpacing(8) box.layout().addLayout(box_layout) button_group = QButtonGroup() button_group.buttonClicked[int].connect(self.set_default_method) for i, (method, _) in enumerate(list(METHODS.items())[1:-1]): imputer = self.create_imputer(method) button = QRadioButton(imputer.name) button.setChecked(method == self.default_method_index) button_group.addButton(button, method) box_layout.addWidget(button, i % 3, i // 3) def set_default_time(datetime): datetime = datetime.toSecsSinceEpoch() if datetime != self.default_time: self.default_time = datetime if self.default_method_index == Method.Default: self._invalidate() hlayout = QHBoxLayout() box.layout().addLayout(hlayout) button = QRadioButton("Fixed values; numeric variables:") button_group.addButton(button, Method.Default) button.setChecked(Method.Default == self.default_method_index) hlayout.addWidget(button) self.numeric_value_widget = DoubleSpinBox( minimum=DBL_MIN, maximum=DBL_MAX, singleStep=.1, value=self.default_numeric_value, alignment=Qt.AlignRight, enabled=self.default_method_index == Method.Default, ) self.numeric_value_widget.editingFinished.connect( self.__on_default_numeric_value_edited) self.connect_control("default_numeric_value", self.numeric_value_widget.setValue) hlayout.addWidget(self.numeric_value_widget) hlayout.addWidget(QLabel(", time:")) self.time_widget = gui.DateTimeEditWCalendarTime(self) self.time_widget.setEnabled( self.default_method_index == Method.Default) self.time_widget.setKeyboardTracking(False) self.time_widget.setContentsMargins(0, 0, 0, 0) self.time_widget.set_datetime( QDateTime.fromSecsSinceEpoch(self.default_time)) self.connect_control( "default_time", lambda value: self.time_widget.set_datetime( QDateTime.fromSecsSinceEpoch(value))) self.time_widget.dateTimeChanged.connect(set_default_time) hlayout.addWidget(self.time_widget) self.default_button_group = button_group box = gui.hBox(self.controlArea, self.tr("Individual Attribute Settings"), flat=False) self.varview = ListViewSearch( selectionMode=QListView.ExtendedSelection, uniformItemSizes=True) self.varview.setItemDelegate(DisplayFormatDelegate()) self.varmodel = itemmodels.VariableListModel() self.varview.setModel(self.varmodel) self.varview.selectionModel().selectionChanged.connect( self._on_var_selection_changed) self.selection = self.varview.selectionModel() box.layout().addWidget(self.varview) vertical_layout = QVBoxLayout(margin=0) self.methods_container = QWidget(enabled=False) method_layout = QVBoxLayout(margin=0) self.methods_container.setLayout(method_layout) button_group = QButtonGroup() for method in Method: imputer = self.create_imputer(method) button = QRadioButton(text=imputer.name) button_group.addButton(button, method) method_layout.addWidget(button) self.value_combo = QComboBox( minimumContentsLength=8, sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon, activated=self._on_value_selected) self.value_double = DoubleSpinBox( editingFinished=self._on_value_selected, minimum=DBL_MIN, maximum=DBL_MAX, singleStep=.1, ) self.value_stack = value_stack = QStackedWidget() value_stack.addWidget(self.value_combo) value_stack.addWidget(self.value_double) method_layout.addWidget(value_stack) button_group.buttonClicked[int].connect( self.set_method_for_current_selection) self.reset_button = QPushButton( "Restore All to Default", enabled=False, default=False, autoDefault=False, clicked=self.reset_variable_state, ) vertical_layout.addWidget(self.methods_container) vertical_layout.addStretch(2) vertical_layout.addWidget(self.reset_button) box.layout().addLayout(vertical_layout) self.variable_button_group = button_group gui.auto_apply(self.buttonsArea, self, "autocommit")
def __init__(self, label="", default=0, max=100): QWidget.__init__(self) ControlBase.__init__(self, label, default) self._max = 100 self._graphs_prop_win = GraphsProperties(self._time, self) self._graphsgenerator_win = GraphsEventsGenerator(self._time) self._graph2event_win = Graph2Event(self._time) # Popup menus that only show when clicking on a TIMELINEDELTA object self._deltaLockAction = self.add_popup_menu_option("Lock", self.__lockSelected, key='L') self._deltaColorAction = self.add_popup_menu_option( "Pick a color", self.__pickColor) self._deltaRemoveAction = self.add_popup_menu_option( "Remove", self.__removeSelected, key='Delete') self._deltaActions = [ self._deltaLockAction, self._deltaColorAction, self._deltaRemoveAction ] for action in self._deltaActions: action.setVisible(False) self.add_popup_menu_option("-") self.add_popup_menu_option("Graphs", self.show_graphs_properties, icon=conf.PYFORMS_ICON_EVENTTIMELINE_GRAPH) self.add_popup_menu_option("Apply a function to the graphs", self.__generate_graphs_events, icon=conf.PYFORMS_ICON_EVENTTIMELINE_GRAPH) self.add_popup_menu_option("Convert graph to events", self.__graph2event_event, icon=conf.PYFORMS_ICON_EVENTTIMELINE_GRAPH) self.add_popup_menu_option("-") # General righ click popup menus self.add_popup_menu_option("Rows", self.__setLinePropertiesEvent, icon=conf.PYFORMS_ICON_EVENTTIMELINE_REMOVE) self.add_popup_menu_option("-") self.add_popup_menu_option("-") self.add_popup_menu_option( "Auto adjust rows", self.__auto_adjust_tracks_evt, icon=conf.PYFORMS_ICON_EVENTTIMELINE_REFRESH) self.add_popup_menu_option("Add a row", self.__add_track_2_bottom_evt, icon=conf.PYFORMS_ICON_EVENTTIMELINE_ADD) self.add_popup_menu_option("-") clean_menu = self.add_popup_submenu('Clean') self.add_popup_menu_option('The current row', function_action=self.__cleanLine, submenu=clean_menu) self.add_popup_menu_option('-') self.add_popup_menu_option('All graphs', function_action=self.__cleanCharts, submenu=clean_menu) self.add_popup_menu_option('-') self.add_popup_menu_option('Everything', function_action=self.clean, submenu=clean_menu)
class ToolBox(QFrame): """ A tool box widget. """ # Emitted when a tab is toggled. tabToogled = Signal(int, bool) def setExclusive(self, exclusive): """ Set exclusive tabs (only one tab can be open at a time). """ if self.__exclusive != exclusive: self.__exclusive = exclusive self.__tabActionGroup.setExclusive(exclusive) checked = self.__tabActionGroup.checkedAction() if checked is None: # The action group can be out of sync with the actions state # when switching between exclusive states. actions_checked = [ page.action for page in self.__pages if page.action.isChecked() ] if actions_checked: checked = actions_checked[0] # Trigger/toggle remaining open pages if exclusive and checked is not None: for page in self.__pages: if checked != page.action and page.action.isChecked(): page.action.trigger() def exclusive(self): """ Are the tabs in the toolbox exclusive. """ return self.__exclusive exclusive_ = Property(bool, fget=exclusive, fset=setExclusive, designable=True, doc="Exclusive tabs") def __init__(self, parent=None, **kwargs): QFrame.__init__(self, parent, **kwargs) self.__pages = [] self.__tabButtonHeight = -1 self.__tabIconSize = QSize() self.__exclusive = False self.__setupUi() def __setupUi(self): layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) # Scroll area for the contents. self.__scrollArea = \ _ToolBoxScrollArea(self, objectName="toolbox-scroll-area") self.__scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.__scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.__scrollArea.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.__scrollArea.setFrameStyle(QScrollArea.NoFrame) self.__scrollArea.setWidgetResizable(True) # A widget with all of the contents. # The tabs/contents are placed in the layout inside this widget self.__contents = QWidget(self.__scrollArea, objectName="toolbox-contents") # The layout where all the tab/pages are placed self.__contentsLayout = QVBoxLayout() self.__contentsLayout.setContentsMargins(0, 0, 0, 0) self.__contentsLayout.setSizeConstraint(QVBoxLayout.SetMinAndMaxSize) self.__contentsLayout.setSpacing(0) self.__contents.setLayout(self.__contentsLayout) self.__scrollArea.setWidget(self.__contents) layout.addWidget(self.__scrollArea) self.setLayout(layout) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding) self.__tabActionGroup = \ QActionGroup(self, objectName="toolbox-tab-action-group") self.__tabActionGroup.setExclusive(self.__exclusive) self.__actionMapper = QSignalMapper(self) self.__actionMapper.mapped[QObject].connect(self.__onTabActionToogled) def setTabButtonHeight(self, height): """ Set the tab button height. """ if self.__tabButtonHeight != height: self.__tabButtonHeight = height for page in self.__pages: page.button.setFixedHeight(height) def tabButtonHeight(self): """ Return the tab button height. """ return self.__tabButtonHeight def setTabIconSize(self, size): """ Set the tab button icon size. """ if self.__tabIconSize != size: self.__tabIconSize = size for page in self.__pages: page.button.setIconSize(size) def tabIconSize(self): """ Return the tab icon size. """ return self.__tabIconSize def tabButton(self, index): """ Return the tab button at `index` """ return self.__pages[index].button def tabAction(self, index): """ Return open/close action for the tab at `index`. """ return self.__pages[index].action def addItem(self, widget, text, icon=None, toolTip=None): """ Append the `widget` in a new tab and return its index. Parameters ---------- widget : :class:`QWidget` A widget to be inserted. The toolbox takes ownership of the widget. text : str Name/title of the new tab. icon : :class:`QIcon`, optional An icon for the tab button. toolTip : str, optional Tool tip for the tab button. """ return self.insertItem(self.count(), widget, text, icon, toolTip) def insertItem(self, index, widget, text, icon=None, toolTip=None): """ Insert the `widget` in a new tab at position `index`. See also -------- ToolBox.addItem """ button = self.createTabButton(widget, text, icon, toolTip) self.__contentsLayout.insertWidget(index * 2, button) self.__contentsLayout.insertWidget(index * 2 + 1, widget) widget.hide() page = _ToolBoxPage(index, widget, button.defaultAction(), button) self.__pages.insert(index, page) for i in range(index + 1, self.count()): self.__pages[i] = self.__pages[i]._replace(index=i) self.__updatePositions() # Show (open) the first tab. if self.count() == 1 and index == 0: page.action.trigger() self.__updateSelected() self.updateGeometry() return index def removeItem(self, index): """ Remove the widget at `index`. .. note:: The widget hidden but is is not deleted. """ self.__contentsLayout.takeAt(2 * index + 1) self.__contentsLayout.takeAt(2 * index) page = self.__pages.pop(index) # Update the page indexes for i in range(index, self.count()): self.__pages[i] = self.__pages[i]._replace(index=i) page.button.deleteLater() # Hide the widget and reparent to self # This follows QToolBox.removeItem page.widget.hide() page.widget.setParent(self) self.__updatePositions() self.__updateSelected() self.updateGeometry() def count(self): """ Return the number of widgets inserted in the toolbox. """ return len(self.__pages) def widget(self, index): """ Return the widget at `index`. """ return self.__pages[index].widget def createTabButton(self, widget, text, icon=None, toolTip=None): """ Create the tab button for `widget`. """ action = QAction(text, self) action.setCheckable(True) if icon: action.setIcon(icon) if toolTip: action.setToolTip(toolTip) self.__tabActionGroup.addAction(action) self.__actionMapper.setMapping(action, action) action.toggled.connect(self.__actionMapper.map) button = ToolBoxTabButton(self, objectName="toolbox-tab-button") button.setDefaultAction(action) button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) if self.__tabIconSize.isValid(): button.setIconSize(self.__tabIconSize) if self.__tabButtonHeight > 0: button.setFixedHeight(self.__tabButtonHeight) return button def ensureWidgetVisible(self, child, xmargin=50, ymargin=50): """ Scroll the contents so child widget instance is visible inside the viewport. """ self.__scrollArea.ensureWidgetVisible(child, xmargin, ymargin) def sizeHint(self): hint = self.__contentsLayout.sizeHint() if self.count(): # Compute max width of hidden widgets also. scroll = self.__scrollArea scroll_w = scroll.verticalScrollBar().sizeHint().width() frame_w = self.frameWidth() * 2 + scroll.frameWidth() * 2 max_w = max([p.widget.sizeHint().width() for p in self.__pages]) hint = QSize( max(max_w, hint.width()) + scroll_w + frame_w, hint.height()) return QSize(200, 200).expandedTo(hint) def __onTabActionToogled(self, action): page = find(self.__pages, action, key=attrgetter("action")) on = action.isChecked() page.widget.setVisible(on) index = page.index if index > 0: # Update the `previous` tab buttons style hints previous = self.__pages[index - 1].button flag = QStyleOptionToolBox.NextIsSelected if on: previous.selected |= flag else: previous.selected &= ~flag previous.update() if index < self.count() - 1: next = self.__pages[index + 1].button flag = QStyleOptionToolBox.PreviousIsSelected if on: next.selected |= flag else: next.selected &= ~flag next.update() self.tabToogled.emit(index, on) self.__contentsLayout.invalidate() def __updateSelected(self): """Update the tab buttons selected style flags. """ if self.count() == 0: return opt = QStyleOptionToolBox def update(button, next_sel, prev_sel): if next_sel: button.selected |= opt.NextIsSelected else: button.selected &= ~opt.NextIsSelected if prev_sel: button.selected |= opt.PreviousIsSelected else: button.selected &= ~opt.PreviousIsSelected button.update() if self.count() == 1: update(self.__pages[0].button, False, False) elif self.count() >= 2: pages = self.__pages for i in range(1, self.count() - 1): update(pages[i].button, pages[i + 1].action.isChecked(), pages[i - 1].action.isChecked()) def __updatePositions(self): """Update the tab buttons position style flags. """ if self.count() == 0: return elif self.count() == 1: self.__pages[0].button.position = QStyleOptionToolBox.OnlyOneTab else: self.__pages[0].button.position = QStyleOptionToolBox.Beginning self.__pages[-1].button.position = QStyleOptionToolBox.End for p in self.__pages[1:-1]: p.button.position = QStyleOptionToolBox.Middle for p in self.__pages: p.button.update()
class OWImpute(OWWidget): name = "Impute" description = "Impute missing values in the data table." icon = "icons/Impute.svg" priority = 2130 keywords = ["substitute", "missing"] class Inputs: data = Input("Data", Orange.data.Table) learner = Input("Learner", Learner) class Outputs: data = Output("Data", Orange.data.Table) class Error(OWWidget.Error): imputation_failed = Msg("Imputation failed for '{}'") model_based_imputer_sparse = \ Msg("Model based imputer does not work for sparse data") class Warning(OWWidget.Warning): cant_handle_var = Msg("Default method can not handle '{}'") settingsHandler = settings.DomainContextHandler() _default_method_index = settings.Setting(int(Method.Leave)) # type: int # Per-variable imputation state (synced in storeSpecificSettings) _variable_imputation_state = settings.ContextSetting( {}) # type: VariableState autocommit = settings.Setting(True) default_numeric_value = settings.Setting(0.0) default_time = settings.Setting(0) want_main_area = False resizing_enabled = False def __init__(self): super().__init__() self.data = None # type: Optional[Orange.data.Table] self.learner = None # type: Optional[Learner] self.default_learner = SimpleTreeLearner(min_instances=10, max_depth=10) self.modified = False self.executor = qconcurrent.ThreadExecutor(self) self.__task = None main_layout = self.controlArea.layout() box = gui.vBox(self.controlArea, "Default Method") box_layout = QGridLayout() box_layout.setSpacing(8) box.layout().addLayout(box_layout) button_group = QButtonGroup() button_group.buttonClicked[int].connect(self.set_default_method) for i, (method, _) in enumerate(list(METHODS.items())[1:-1]): imputer = self.create_imputer(method) button = QRadioButton(imputer.name) button.setChecked(method == self.default_method_index) button_group.addButton(button, method) box_layout.addWidget(button, i % 3, i // 3) def set_default_time(datetime): datetime = datetime.toSecsSinceEpoch() if datetime != self.default_time: self.default_time = datetime if self.default_method_index == Method.Default: self._invalidate() hlayout = QHBoxLayout() box.layout().addLayout(hlayout) button = QRadioButton("Fixed values; numeric variables:") button_group.addButton(button, Method.Default) button.setChecked(Method.Default == self.default_method_index) hlayout.addWidget(button) self.numeric_value_widget = DoubleSpinBox( minimum=DBL_MIN, maximum=DBL_MAX, singleStep=.1, value=self.default_numeric_value, alignment=Qt.AlignRight, enabled=self.default_method_index == Method.Default, ) self.numeric_value_widget.editingFinished.connect( self.__on_default_numeric_value_edited) self.connect_control("default_numeric_value", self.numeric_value_widget.setValue) hlayout.addWidget(self.numeric_value_widget) hlayout.addWidget(QLabel(", time:")) self.time_widget = gui.DateTimeEditWCalendarTime(self) self.time_widget.setEnabled( self.default_method_index == Method.Default) self.time_widget.setKeyboardTracking(False) self.time_widget.setContentsMargins(0, 0, 0, 0) self.time_widget.set_datetime( QDateTime.fromSecsSinceEpoch(self.default_time)) self.connect_control( "default_time", lambda value: self.time_widget.set_datetime( QDateTime.fromSecsSinceEpoch(value))) self.time_widget.dateTimeChanged.connect(set_default_time) hlayout.addWidget(self.time_widget) self.default_button_group = button_group box = gui.hBox(self.controlArea, self.tr("Individual Attribute Settings"), flat=False) self.varview = ListViewSearch( selectionMode=QListView.ExtendedSelection, uniformItemSizes=True) self.varview.setItemDelegate(DisplayFormatDelegate()) self.varmodel = itemmodels.VariableListModel() self.varview.setModel(self.varmodel) self.varview.selectionModel().selectionChanged.connect( self._on_var_selection_changed) self.selection = self.varview.selectionModel() box.layout().addWidget(self.varview) vertical_layout = QVBoxLayout(margin=0) self.methods_container = QWidget(enabled=False) method_layout = QVBoxLayout(margin=0) self.methods_container.setLayout(method_layout) button_group = QButtonGroup() for method in Method: imputer = self.create_imputer(method) button = QRadioButton(text=imputer.name) button_group.addButton(button, method) method_layout.addWidget(button) self.value_combo = QComboBox( minimumContentsLength=8, sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon, activated=self._on_value_selected) self.value_double = DoubleSpinBox( editingFinished=self._on_value_selected, minimum=DBL_MIN, maximum=DBL_MAX, singleStep=.1, ) self.value_stack = value_stack = QStackedWidget() value_stack.addWidget(self.value_combo) value_stack.addWidget(self.value_double) method_layout.addWidget(value_stack) button_group.buttonClicked[int].connect( self.set_method_for_current_selection) self.reset_button = QPushButton( "Restore All to Default", enabled=False, default=False, autoDefault=False, clicked=self.reset_variable_state, ) vertical_layout.addWidget(self.methods_container) vertical_layout.addStretch(2) vertical_layout.addWidget(self.reset_button) box.layout().addLayout(vertical_layout) self.variable_button_group = button_group gui.auto_apply(self.buttonsArea, self, "autocommit") def create_imputer(self, method, *args): # type: (Method, ...) -> impute.BaseImputeMethod if method == Method.Model: if self.learner is not None: return impute.Model(self.learner) else: return impute.Model(self.default_learner) elif method == Method.AsAboveSoBelow: assert self.default_method_index != Method.AsAboveSoBelow default = self.create_imputer(Method(self.default_method_index)) m = AsDefault() m.method = default return m elif method == Method.Default and not args: # global default values return impute.FixedValueByType( default_continuous=self.default_numeric_value, default_time=self.default_time) else: return METHODS[method](*args) @property def default_method_index(self): return self._default_method_index @default_method_index.setter def default_method_index(self, index): if self._default_method_index != index: assert index != Method.AsAboveSoBelow self._default_method_index = index self.default_button_group.button(index).setChecked(True) self.time_widget.setEnabled(index == Method.Default) self.numeric_value_widget.setEnabled(index == Method.Default) # update variable view self.update_varview() self._invalidate() def set_default_method(self, index): """Set the current selected default imputation method. """ self.default_method_index = index def __on_default_numeric_value_edited(self): val = self.numeric_value_widget.value() if val != self.default_numeric_value: self.default_numeric_value = val if self.default_method_index == Method.Default: self._invalidate() @Inputs.data @check_sql_input def set_data(self, data): self.cancel() self.closeContext() self.varmodel[:] = [] self._variable_imputation_state = {} # type: VariableState self.modified = False self.data = data if data is not None: self.varmodel[:] = data.domain.variables self.openContext(data.domain) # restore per variable imputation state self._restore_state(self._variable_imputation_state) self.reset_button.setEnabled(len(self.varmodel) > 0) self.update_varview() self.commit.now() @Inputs.learner def set_learner(self, learner): self.cancel() self.learner = learner or self.default_learner imputer = self.create_imputer(Method.Model) button = self.default_button_group.button(Method.Model) button.setText(imputer.name) variable_button = self.variable_button_group.button(Method.Model) variable_button.setText(imputer.name) if learner is not None: self.default_method_index = Method.Model self.update_varview() self.commit.deferred() def get_method_for_column(self, column_index): # type: (int) -> impute.BaseImputeMethod """ Return the imputation method for column by its index. """ assert 0 <= column_index < len(self.varmodel) idx = self.varmodel.index(column_index, 0) state = idx.data(StateRole) if state is None: state = (Method.AsAboveSoBelow, ()) return self.create_imputer(state[0], *state[1]) def _invalidate(self): self.modified = True if self.__task is not None: self.cancel() self.commit.deferred() @gui.deferred def commit(self): self.cancel() self.warning() self.Error.imputation_failed.clear() self.Error.model_based_imputer_sparse.clear() if not self.data or not self.varmodel.rowCount(): self.Outputs.data.send(self.data) self.modified = False return data = self.data impute_state = [(i, var, self.get_method_for_column(i)) for i, var in enumerate(self.varmodel)] # normalize to the effective method bypasing AsDefault impute_state = [(i, var, m.method if isinstance(m, AsDefault) else m) for i, var, m in impute_state] def impute_one(method, var, data): # type: (impute.BaseImputeMethod, Variable, Table) -> Any # Readability counts, pylint: disable=no-else-raise if isinstance(method, impute.Model) and data.is_sparse(): raise SparseNotSupported() elif isinstance(method, impute.DropInstances): return RowMask(method(data, var)) elif not method.supports_variable(var): raise VariableNotSupported(var) else: return method(data, var) futures = [] for _, var, method in impute_state: f = self.executor.submit(impute_one, copy.deepcopy(method), var, data) futures.append(f) w = qconcurrent.FutureSetWatcher(futures) w.doneAll.connect(self.__commit_finish) w.progressChanged.connect(self.__progress_changed) self.__task = Task(futures, w) self.progressBarInit() self.setInvalidated(True) @Slot() def __commit_finish(self): assert QThread.currentThread() is self.thread() assert self.__task is not None futures = self.__task.futures assert len(futures) == len(self.varmodel) assert self.data is not None def get_variable(variable, future, drop_mask) \ -> Optional[List[Orange.data.Variable]]: # Returns a (potentially empty) list of variables, # or None on failure that should interrupt the imputation assert future.done() try: res = future.result() except SparseNotSupported: self.Error.model_based_imputer_sparse() return [] # None? except VariableNotSupported: self.Warning.cant_handle_var(variable.name) return [] except Exception: # pylint: disable=broad-except log = logging.getLogger(__name__) log.info("Error for %s", variable.name, exc_info=True) self.Error.imputation_failed(variable.name) return None if isinstance(res, RowMask): drop_mask |= res.mask newvar = variable else: newvar = res if isinstance(newvar, Orange.data.Variable): newvar = [newvar] return newvar def create_data(attributes, class_vars): domain = Orange.data.Domain(attributes, class_vars, self.data.domain.metas) try: return self.data.from_table(domain, self.data[~drop_mask]) except Exception: # pylint: disable=broad-except log = logging.getLogger(__name__) log.info("Error", exc_info=True) self.Error.imputation_failed("Unknown") return None self.__task = None self.setInvalidated(False) self.progressBarFinished() attributes = [] class_vars = [] drop_mask = np.zeros(len(self.data), bool) for i, (var, fut) in enumerate(zip(self.varmodel, futures)): newvar = get_variable(var, fut, drop_mask) if newvar is None: data = None break if i < len(self.data.domain.attributes): attributes.extend(newvar) else: class_vars.extend(newvar) else: data = create_data(attributes, class_vars) self.Outputs.data.send(data) self.modified = False @Slot(int, int) def __progress_changed(self, n, d): assert QThread.currentThread() is self.thread() assert self.__task is not None self.progressBarSet(100. * n / d) def cancel(self): self.__cancel(wait=False) def __cancel(self, wait=False): if self.__task is not None: task, self.__task = self.__task, None task.cancel() task.watcher.doneAll.disconnect(self.__commit_finish) task.watcher.progressChanged.disconnect(self.__progress_changed) if wait: concurrent.futures.wait(task.futures) task.watcher.flush() self.progressBarFinished() self.setInvalidated(False) def onDeleteWidget(self): self.__cancel(wait=True) super().onDeleteWidget() def send_report(self): specific = [] for i, var in enumerate(self.varmodel): method = self.get_method_for_column(i) if not isinstance(method, AsDefault): specific.append("{} ({})".format(var.name, str(method))) default = self.create_imputer(Method.AsAboveSoBelow) if specific: self.report_items((("Default method", default.name), ("Specific imputers", ", ".join(specific)))) else: self.report_items((("Method", default.name), )) def _on_var_selection_changed(self): # Method is well documented, splitting it is not needed for readability, # thus pylint: disable=too-many-branches indexes = self.selection.selectedIndexes() self.methods_container.setEnabled(len(indexes) > 0) defmethod = (Method.AsAboveSoBelow, ()) methods = [index.data(StateRole) for index in indexes] methods = [m if m is not None else defmethod for m in methods] methods = set(methods) selected_vars = [self.varmodel[index.row()] for index in indexes] has_discrete = any(var.is_discrete for var in selected_vars) fixed_value = None value_stack_enabled = False current_value_widget = None if len(methods) == 1: method_type, parameters = methods.pop() for m in Method: if method_type == m: self.variable_button_group.button(m).setChecked(True) if method_type == Method.Default: (fixed_value, ) = parameters elif self.variable_button_group.checkedButton() is not None: # Uncheck the current button self.variable_button_group.setExclusive(False) self.variable_button_group.checkedButton().setChecked(False) self.variable_button_group.setExclusive(True) assert self.variable_button_group.checkedButton() is None # Update variable methods GUI enabled state based on selection. for method in Method: # use a default constructed imputer to query support imputer = self.create_imputer(method) enabled = all( imputer.supports_variable(var) for var in selected_vars) button = self.variable_button_group.button(method) button.setEnabled(enabled) # Update the "Value" edit GUI. if not has_discrete: # no discrete variables -> allow mass edit for all (continuous vars) value_stack_enabled = True current_value_widget = self.value_double elif len(selected_vars) == 1: # single discrete var -> enable and fill the values combo value_stack_enabled = True current_value_widget = self.value_combo self.value_combo.clear() self.value_combo.addItems(selected_vars[0].values) else: # mixed type selection -> disable value_stack_enabled = False current_value_widget = None self.variable_button_group.button(Method.Default).setEnabled(False) self.value_stack.setEnabled(value_stack_enabled) if current_value_widget is not None: self.value_stack.setCurrentWidget(current_value_widget) if fixed_value is not None: # set current value if current_value_widget is self.value_combo: self.value_combo.setCurrentIndex(fixed_value) elif current_value_widget is self.value_double: self.value_double.setValue(fixed_value) else: assert False def set_method_for_current_selection(self, method_index): # type: (Method) -> None indexes = self.selection.selectedIndexes() self.set_method_for_indexes(indexes, method_index) def set_method_for_indexes(self, indexes, method_index): # type: (List[QModelIndex], Method) -> None if method_index == Method.AsAboveSoBelow: for index in indexes: self.varmodel.setData(index, None, StateRole) elif method_index == Method.Default: current = self.value_stack.currentWidget() if current is self.value_combo: value = self.value_combo.currentIndex() else: value = self.value_double.value() for index in indexes: state = (int(Method.Default), (value, )) self.varmodel.setData(index, state, StateRole) else: state = (int(method_index), ()) for index in indexes: self.varmodel.setData(index, state, StateRole) self.update_varview(indexes) self._invalidate() def update_varview(self, indexes=None): if indexes is None: indexes = map(self.varmodel.index, range(len(self.varmodel))) for index in indexes: self.varmodel.setData(index, self.get_method_for_column(index.row()), DisplayMethodRole) def _on_value_selected(self): # The fixed 'Value' in the widget has been changed by the user. self.variable_button_group.button(Method.Default).setChecked(True) self.set_method_for_current_selection(Method.Default) def reset_variable_state(self): indexes = list(map(self.varmodel.index, range(len(self.varmodel)))) self.set_method_for_indexes(indexes, Method.AsAboveSoBelow) self.variable_button_group.button( Method.AsAboveSoBelow).setChecked(True) def _store_state(self): # type: () -> VariableState """ Save the current variable imputation state """ state = {} # type: VariableState for i, var in enumerate(self.varmodel): index = self.varmodel.index(i) m = index.data(StateRole) if m is not None: state[var_key(var)] = m return state def _restore_state(self, state): # type: (VariableState) -> None """ Restore the variable imputation state from the saved state """ def check(state): # check if state is a proper State if isinstance(state, tuple) and len(state) == 2: m, p = state if isinstance(m, int) and isinstance(p, tuple) and \ 0 <= m < len(Method): return True return False for i, var in enumerate(self.varmodel): m = state.get(var_key(var), None) if check(m): self.varmodel.setData(self.varmodel.index(i), m, StateRole) def storeSpecificSettings(self): self._variable_imputation_state = self._store_state() super().storeSpecificSettings()
def create_widget_for_node(self, node): return QWidget()
def resizeEvent(self, event): QWidget.resizeEvent(self, event) if not self.__isTransparencySupported: self.__updateMask()
def __init__(self): super().__init__() self.data = None self.features = None # Schedule interface updates (enabled buttons) using a coalescing # single shot timer (complex interactions on selection and filtering # updates in the 'available_attrs_view') self.__interface_update_timer = QTimer(self, interval=0, singleShot=True) self.__interface_update_timer.timeout.connect( self.__update_interface_state) # The last view that has the selection for move operation's source self.__last_active_view = None # type: Optional[QListView] def update_on_change(view): # Schedule interface state update on selection change in `view` self.__last_active_view = view self.__interface_update_timer.start() self.controlArea = QWidget(self.controlArea) self.layout().addWidget(self.controlArea) layout = QGridLayout() self.controlArea.setLayout(layout) layout.setContentsMargins(4, 4, 4, 4) box = gui.vBox(self.controlArea, "Available Variables", addToLayout=False) self.available_attrs = VariablesListItemModel() filter_edit, self.available_attrs_view = variables_filter( parent=self, model=self.available_attrs) box.layout().addWidget(filter_edit) def dropcompleted(action): if action == Qt.MoveAction: self.commit() self.available_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.available_attrs_view)) self.available_attrs_view.dragDropActionDidComplete.connect( dropcompleted) box.layout().addWidget(self.available_attrs_view) layout.addWidget(box, 0, 0, 3, 1) box = gui.vBox(self.controlArea, "Features", addToLayout=False) self.used_attrs = VariablesListItemModel() filter_edit, self.used_attrs_view = variables_filter( parent=self, model=self.used_attrs, accepted_type=(Orange.data.DiscreteVariable, Orange.data.ContinuousVariable)) self.used_attrs.rowsInserted.connect(self.__used_attrs_changed) self.used_attrs.rowsRemoved.connect(self.__used_attrs_changed) self.used_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.used_attrs_view)) self.used_attrs_view.dragDropActionDidComplete.connect(dropcompleted) self.use_features_box = gui.auto_commit( self.controlArea, self, "use_input_features", "Use input features", "Always use input features", box=False, commit=self.__use_features_clicked, callback=self.__use_features_changed, addToLayout=False) self.enable_use_features_box() box.layout().addWidget(self.use_features_box) box.layout().addWidget(filter_edit) box.layout().addWidget(self.used_attrs_view) layout.addWidget(box, 0, 2, 1, 1) box = gui.vBox(self.controlArea, "Target Variable", addToLayout=False) self.class_attrs = VariablesListItemModel() self.class_attrs_view = VariablesListItemView( acceptedType=(Orange.data.DiscreteVariable, Orange.data.ContinuousVariable)) self.class_attrs_view.setModel(self.class_attrs) self.class_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.class_attrs_view)) self.class_attrs_view.dragDropActionDidComplete.connect(dropcompleted) self.class_attrs_view.setMaximumHeight(72) box.layout().addWidget(self.class_attrs_view) layout.addWidget(box, 1, 2, 1, 1) box = gui.vBox(self.controlArea, "Meta Attributes", addToLayout=False) self.meta_attrs = VariablesListItemModel() self.meta_attrs_view = VariablesListItemView( acceptedType=Orange.data.Variable) self.meta_attrs_view.setModel(self.meta_attrs) self.meta_attrs_view.selectionModel().selectionChanged.connect( partial(update_on_change, self.meta_attrs_view)) self.meta_attrs_view.dragDropActionDidComplete.connect(dropcompleted) box.layout().addWidget(self.meta_attrs_view) layout.addWidget(box, 2, 2, 1, 1) bbox = gui.vBox(self.controlArea, addToLayout=False, margin=0) layout.addWidget(bbox, 0, 1, 1, 1) self.up_attr_button = gui.button(bbox, self, "Up", callback=partial( self.move_up, self.used_attrs_view)) self.move_attr_button = gui.button(bbox, self, ">", callback=partial( self.move_selected, self.used_attrs_view)) self.down_attr_button = gui.button(bbox, self, "Down", callback=partial( self.move_down, self.used_attrs_view)) bbox = gui.vBox(self.controlArea, addToLayout=False, margin=0) layout.addWidget(bbox, 1, 1, 1, 1) self.up_class_button = gui.button(bbox, self, "Up", callback=partial( self.move_up, self.class_attrs_view)) self.move_class_button = gui.button(bbox, self, ">", callback=partial( self.move_selected, self.class_attrs_view)) self.down_class_button = gui.button(bbox, self, "Down", callback=partial( self.move_down, self.class_attrs_view)) bbox = gui.vBox(self.controlArea, addToLayout=False, margin=0) layout.addWidget(bbox, 2, 1, 1, 1) self.up_meta_button = gui.button(bbox, self, "Up", callback=partial( self.move_up, self.meta_attrs_view)) self.move_meta_button = gui.button(bbox, self, ">", callback=partial( self.move_selected, self.meta_attrs_view)) self.down_meta_button = gui.button(bbox, self, "Down", callback=partial( self.move_down, self.meta_attrs_view)) autobox = gui.auto_send(None, self, "auto_commit") layout.addWidget(autobox, 3, 0, 1, 3) reset = gui.button(None, self, "Reset", callback=self.reset, width=120) autobox.layout().insertWidget(0, reset) autobox.layout().insertStretch(1, 20) layout.setRowStretch(0, 4) layout.setRowStretch(1, 0) layout.setRowStretch(2, 2) layout.setHorizontalSpacing(0) self.controlArea.setLayout(layout) self.output_data = None self.original_completer_items = [] self.info.set_input_summary(self.info.NoInput) self.info.set_output_summary(self.info.NoOutput) self.resize(600, 600)
def __init__(self, parent): QWidget.__init__(self) OWComponent.__init__(self, parent) SelectionGroupMixin.__init__(self) ImageColorSettingMixin.__init__(self) ImageZoomMixin.__init__(self) ConcurrentMixin.__init__(self) self.parent = parent self.selection_type = SELECTMANY self.saving_enabled = True self.selection_enabled = True self.viewtype = INDIVIDUAL # required bt InteractiveViewBox self.highlighted = None self.data_points = None self.data_values = None self.data_imagepixels = None self.data_valid_positions = None self.plotview = pg.GraphicsLayoutWidget() self.plot = pg.PlotItem(background="w", viewBox=InteractiveViewBox(self)) self.plotview.addItem(self.plot) self.legend = ImageColorLegend() self.plotview.addItem(self.legend) self.plot.scene().installEventFilter( HelpEventDelegate(self.help_event, self)) layout = QVBoxLayout() self.setLayout(layout) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self.plotview) self.img = ImageItemNan() self.img.setOpts(axisOrder='row-major') self.plot.addItem(self.img) self.vis_img = pg.ImageItem() self.vis_img.setOpts(axisOrder='row-major') self.plot.vb.setAspectLocked() self.plot.scene().sigMouseMoved.connect(self.plot.vb.mouseMovedEvent) layout = QGridLayout() self.plotview.setLayout(layout) self.button = QPushButton("Menu", self.plotview) self.button.setAutoDefault(False) layout.setRowStretch(1, 1) layout.setColumnStretch(1, 1) layout.addWidget(self.button, 0, 0) view_menu = MenuFocus(self) self.button.setMenu(view_menu) # prepare interface according to the new context self.parent.contextAboutToBeOpened.connect( lambda x: self.init_interface_data(x[0])) actions = [] self.add_zoom_actions(view_menu) select_square = QAction( "Select (square)", self, triggered=self.plot.vb.set_mode_select_square, ) select_square.setShortcuts([Qt.Key_S]) select_square.setShortcutContext(Qt.WidgetWithChildrenShortcut) actions.append(select_square) select_polygon = QAction( "Select (polygon)", self, triggered=self.plot.vb.set_mode_select_polygon, ) select_polygon.setShortcuts([Qt.Key_P]) select_polygon.setShortcutContext(Qt.WidgetWithChildrenShortcut) actions.append(select_polygon) if self.saving_enabled: save_graph = QAction( "Save graph", self, triggered=self.save_graph, ) save_graph.setShortcuts( [QKeySequence(Qt.ControlModifier | Qt.Key_I)]) actions.append(save_graph) view_menu.addActions(actions) self.addActions(actions) common_options = dict(labelWidth=50, orientation=Qt.Horizontal, sendSelectedValue=True) choose_xy = QWidgetAction(self) box = gui.vBox(self) box.setFocusPolicy(Qt.TabFocus) self.xy_model = DomainModel(DomainModel.METAS | DomainModel.CLASSES, valid_types=DomainModel.PRIMITIVE) self.cb_attr_x = gui.comboBox(box, self, "attr_x", label="Axis x:", callback=self.update_attr, model=self.xy_model, **common_options) self.cb_attr_y = gui.comboBox(box, self, "attr_y", label="Axis y:", callback=self.update_attr, model=self.xy_model, **common_options) box.setFocusProxy(self.cb_attr_x) box.layout().addWidget(self.color_settings_box()) choose_xy.setDefaultWidget(box) view_menu.addAction(choose_xy) self.lsx = None # info about the X axis self.lsy = None # info about the Y axis self.data = None self.data_ids = {}
def __init__(self, *args): QWidget.__init__(self, *args) self.__model = None self.__currentIndex = -1 self.__template = DESCRIPTION_TEMPLATE self.__setupUi()
def __init__(self, *args, **kwargs): QWidget.__init__(self) ControlBase.__init__(self, *args, **kwargs)
def __init__(self): super().__init__() #: widget's runtime state self.__state = State.NoState self._soundMeta = [] self._soundCategories = {} self._data = [] self.__invalidated = False self.__pendingTask = None vbox = gui.vBox(self.controlArea) hbox = gui.hBox(vbox) self.recent_cb = QComboBox( sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon, minimumContentsLength=16, acceptDrops=True) self.recent_cb.installEventFilter(self) self.recent_cb.activated[int].connect(self.__onRecentActivated) icons = standard_icons(self) browseaction = QAction( "Open/Load Sounds", self, iconText="\N{HORIZONTAL ELLIPSIS}", icon=icons.dir_open_icon, toolTip="Select a directory from which to load the sounds") browseaction.triggered.connect(self.__runOpenDialog) reloadaction = QAction("Reload", self, icon=icons.reload_icon, toolTip="Reload current sounds set") reloadaction.triggered.connect(self.reload) self.__actions = namespace( browse=browseaction, reload=reloadaction, ) browsebutton = QPushButton(browseaction.iconText(), icon=browseaction.icon(), toolTip=browseaction.toolTip(), clicked=browseaction.trigger) reloadbutton = QPushButton( reloadaction.iconText(), icon=reloadaction.icon(), clicked=reloadaction.trigger, default=True, ) hbox.layout().addWidget(self.recent_cb) hbox.layout().addWidget(browsebutton) hbox.layout().addWidget(reloadbutton) self.addActions([browseaction, reloadaction]) reloadaction.changed.connect( lambda: reloadbutton.setEnabled(reloadaction.isEnabled())) box = gui.vBox(vbox, "Info") self.infostack = QStackedWidget() self.info_area = QLabel(text="No sound set selected", wordWrap=True) self.progress_widget = QProgressBar(minimum=0, maximum=0) self.cancel_button = QPushButton( "Cancel", icon=icons.cancel_icon, ) self.cancel_button.clicked.connect(self.cancel) w = QWidget() vlayout = QVBoxLayout() vlayout.setContentsMargins(0, 0, 0, 0) hlayout = QHBoxLayout() hlayout.setContentsMargins(0, 0, 0, 0) hlayout.addWidget(self.progress_widget) hlayout.addWidget(self.cancel_button) vlayout.addLayout(hlayout) self.pathlabel = TextLabel() self.pathlabel.setTextElideMode(Qt.ElideMiddle) self.pathlabel.setAttribute(Qt.WA_MacSmallSize) vlayout.addWidget(self.pathlabel) w.setLayout(vlayout) self.infostack.addWidget(self.info_area) self.infostack.addWidget(w) box.layout().addWidget(self.infostack) self.__initRecentItemsModel() self.__invalidated = True self.__executor = ThreadExecutor(self) QApplication.postEvent(self, QEvent(RuntimeEvent.Init))
def show(self): """ Show the control """ QWidget.show(self)
def repaint(self): QWidget.repaint(self) QApplication.flush()