def __init__(self, parent=None, orientation=Qt.Horizontal, **kwargs): sizePolicy = kwargs.pop("sizePolicy", None) super().__init__(None, **kwargs) self.__orientation = Qt.Horizontal if sizePolicy is None: sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setControlType(QSizePolicy.Frame) self.setSizePolicy(sizePolicy) else: self.setSizePolicy(sizePolicy) self.setOrientation(orientation) if parent is not None: self.setParentItem(parent)
def __init__(self, parent=None, items=None, **kwargs): super().__init__(parent, **kwargs) self.setFlag(QGraphicsWidget.ItemClipsChildrenToShape, True) self.__items = [] self.__textitems = [] self.__group = None self.__spacing = 0 sp = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sp.setWidthForHeight(True) self.setSizePolicy(sp) if items is not None: self.setItems(items)
def __init__(self, parent=None, bridge=None, *, debug=False, **kwargs): super().__init__(parent, sizeHint=QSize(500, 400), sizePolicy=QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding), **kwargs) if isinstance(parent, QWidget) and parent.layout() is not None: parent.layout().addWidget(self) # TODO REMOVE self.bridge = bridge self.frame = None self.debug = debug def _onload(_ok): if _ok: self.frame = self.page().mainFrame() self.frame.javaScriptWindowObjectCleared.connect( lambda: self.frame.addToJavaScriptWindowObject('pybridge', bridge)) with open(_WEBVIEW_HELPERS, encoding="utf-8") as f: self.frame.evaluateJavaScript(f.read()) self.loadFinished.connect(_onload) _onload(True) history = self.history() history.setMaximumItemCount(0) settings = self.settings() settings.setMaximumPagesInCache(0) settings.setAttribute(settings.LocalContentCanAccessFileUrls, True) settings.setAttribute(settings.LocalContentCanAccessRemoteUrls, False) if debug: settings.setAttribute(settings.LocalStorageEnabled, True) settings.setAttribute(settings.DeveloperExtrasEnabled, True) settings.setObjectCacheCapacities(4e6, 4e6, 4e6) settings.enablePersistentStorage()
def _create_layout(self): box = gui.widgetBox(self.controlArea, orientation='horizontal') self.varmodel = VariableListModel(parent=self) self.attr_combo = gui.comboBox(box, self, 'selected_attr', orientation=Qt.Horizontal, label='Region attribute:', callback=self.on_attr_change, sendSelectedValue=True) self.attr_combo.setModel(self.varmodel) self.map_combo = gui.comboBox(box, self, 'selected_map', orientation=Qt.Horizontal, label='Map type:', callback=self.on_map_change, items=Map.all) hexpand = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.attr_combo.setSizePolicy(hexpand) self.map_combo.setSizePolicy(hexpand) url = urljoin( 'file:', pathname2url( os.path.join(os.path.dirname(__file__), 'resources', 'owgeomap.html'))) self.webview = gui.WebviewWidget(self.controlArea, self, url=QUrl(url)) self.controlArea.layout().addWidget(self.webview) QTimer.singleShot( 0, lambda: self.webview.evalJS('REGIONS = {};'.format({ Map.WORLD: CC_WORLD, Map.EUROPE: CC_EUROPE, Map.USA: CC_USA })))
def __init__(self, parent: QWidget, variable: ContinuousVariable, min_value: float, max_value: float, callback: Callable): super().__init__(parent, callback) if np.isnan(min_value) or np.isnan(max_value): raise ValueError("Min/Max cannot be NaN.") n_decimals = variable.number_of_decimals abs_max = max(abs(min_value), max_value) if abs_max * 10**n_decimals > self.MAX_FLOAT: n_decimals = int(np.log10(self.MAX_FLOAT / abs_max)) self._value: float = min_value self._n_decimals: int = n_decimals self._min_value: float = self.__round_value(min_value) self._max_value: float = self.__round_value(max_value) sp_spin = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sp_spin.setHorizontalStretch(1) sp_slider = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sp_slider.setHorizontalStretch(5) sp_edit = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sp_edit.setHorizontalStretch(1) class DoubleSpinBox(QDoubleSpinBox): def sizeHint(self) -> QSize: size: QSize = super().sizeHint() return QSize(size.width(), size.height() + 2) self._spin = DoubleSpinBox( parent, value=self._min_value, minimum=-np.inf, maximum=np.inf, singleStep=10**(-self._n_decimals), decimals=self._n_decimals, minimumWidth=70, sizePolicy=sp_spin, ) self._slider = QSlider( parent, minimum=self.__map_to_slider(self._min_value), maximum=self.__map_to_slider(self._max_value), singleStep=1, orientation=Qt.Horizontal, sizePolicy=sp_slider, ) self._label_min = QLabel( parent, text=variable.repr_val(min_value), alignment=Qt.AlignRight, minimumWidth=60, sizePolicy=sp_edit, ) self._label_max = QLabel( parent, text=variable.repr_val(max_value), alignment=Qt.AlignLeft, minimumWidth=60, sizePolicy=sp_edit, ) self._slider.valueChanged.connect(self._apply_slider_value) self._spin.valueChanged.connect(self._apply_spin_value) self.layout().addWidget(self._spin) self.layout().addWidget(self._label_min) self.layout().addWidget(self._slider) self.layout().addWidget(self._label_max) self.setFocusProxy(self._spin) def deselect(): self._spin.lineEdit().deselect() try: self._spin.lineEdit().selectionChanged.disconnect(deselect) except TypeError: pass # Invoking self.setFocusProxy(self._spin), causes the # self._spin.lineEdit()s to have selected texts (focus is set to # provide keyboard functionality, i.e.: pressing ESC after changing # spinbox value). Since the spin text is selected only after the # delegate draws it, it cannot be deselected during initialization. # Therefore connect the deselect() function to # self._spin.lineEdit().selectionChanged only for editor creation. self._spin.lineEdit().selectionChanged.connect(deselect) self._slider.installEventFilter(self) self._spin.installEventFilter(self)
def __init__(self, scene, parent): super().__init__(scene, parent, sizePolicy=QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum))
def __init__(self): super().__init__() self.selected_node = None self.root_node = None self.model = None box = gui.vBox(self.controlArea, 'Tree', addSpace=20, sizePolicy=QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)) self.info = gui.widgetLabel(box, 'No tree.') layout = QFormLayout() layout.setVerticalSpacing(20) layout.setFieldGrowthPolicy(layout.ExpandingFieldsGrow) box = self.display_box = \ gui.widgetBox(self.controlArea, "Display", addSpace=True, orientation=layout) layout.addRow( "Zoom: ", gui.hSlider(box, self, 'zoom', minValue=1, maxValue=10, step=1, ticks=False, callback=self.toggle_zoom_slider, createLabel=False, addToLayout=False, addSpace=False)) layout.addRow( "Width: ", gui.hSlider(box, self, 'max_node_width', minValue=50, maxValue=200, step=1, ticks=False, callback=self.toggle_node_size, createLabel=False, addToLayout=False, addSpace=False)) policy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) layout.addRow( "Depth: ", gui.comboBox(box, self, 'max_tree_depth', items=["Unlimited"] + ["{} levels".format(x) for x in range(2, 10)], addToLayout=False, sendSelectedValue=False, callback=self.toggle_tree_depth, sizePolicy=policy)) layout.addRow( "Edge width: ", gui.comboBox( box, self, 'line_width_method', items=['Fixed', 'Relative to root', 'Relative to parent'], addToLayout=False, callback=self.toggle_line_width, sizePolicy=policy)) gui.rubber(self.controlArea) self.resize(800, 500) self.scene = TreeGraphicsScene(self) self.scene_view = TreeGraphicsView(self.scene) self.scene_view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) self.mainArea.layout().addWidget(self.scene_view) self.toggle_zoom_slider() self.scene.selectionChanged.connect(self.update_selection)
def __init__(self): super().__init__() for name in self.signal_names: setattr(self, name, {}) for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = gui.vBox(self.controlArea, '信息') gui.label( self.infoBox, self, "<p>执行Python脚本。</p><p>输入变量:<ul><li> " + "<li>".join(map("in_{0}, in_{0}s".format, self.signal_names)) + "</ul></p><p>输出变量:<ul><li>" + "<li>".join(map("out_{0}".format, self.signal_names)) + "</ul></p>") self.libraryList = itemmodels.PyListModel( [], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = gui.vBox(self.controlArea, '脚本库') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = itemmodels.ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("向库中添加新脚本") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("从库中删除脚本") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("保存", self) action.setToolTip("将编辑器中的更改的脚本保存到库中") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("更多", self, toolTip="更多操作") new_from_file = QAction("从文件导入脚本", self) save_to_file = QAction("将所选脚本保存到文件", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) auto = gui.auto_commit(self.controlArea, self, "auto_execute", "运行", checkbox_label="对新数据自动运行") self.execute_button, self.autobox = auto.button, auto.checkbox self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = gui.vBox(self, 'Python脚本') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.setToolTip("Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) action.triggered.connect(self.saveScript) self.consoleBox = gui.vBox(self, '控制台') self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole({}, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600)
def __init__(self): super().__init__() self.data = None form = QGridLayout() self.row_type = "" gui.lineEdit(self.controlArea, self, "row_type", "Row Type", callback=self.send_output) self.col_type = "" gui.lineEdit(self.controlArea, self, "col_type", "Column Type", callback=self.send_output) methodbox = gui.radioButtonsInBox(self.controlArea, self, "method", [], box=self.tr("Sampling method"), orientation=form) rows = gui.appendRadioButton(methodbox, "Rows", addToLayout=False) form.addWidget(rows, 0, 0, Qt.AlignLeft) cols = gui.appendRadioButton(methodbox, "Columns", addToLayout=False) form.addWidget(cols, 0, 1, Qt.AlignLeft) rows_and_cols = gui.appendRadioButton(methodbox, "Rows and columns", addToLayout=False) form.addWidget(rows_and_cols, 1, 0, Qt.AlignLeft) entries = gui.appendRadioButton(methodbox, "Entries", addToLayout=False) form.addWidget(entries, 1, 1, Qt.AlignLeft) sample_size = gui.widgetBox(self.controlArea, "Proportion of data in the sample") gui.hSlider(sample_size, self, 'percent', minValue=1, maxValue=100, step=5, ticks=10, labelFormat=" %d%%") gui.button(self.controlArea, self, "&Apply", callback=self.send_output, default=True) self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.setMinimumWidth(250) self.send_output()
def _create_buttons(self, box): """Create radio buttons""" def intspin(): s = QSpinBox(self) s.setMinimum(2) s.setMaximum(10) s.setFixedWidth(60) s.setAlignment(Qt.AlignRight) s.setContentsMargins(0, 0, 0, 0) return s, s.valueChanged def widthline(validator): s = QLineEdit(self) s.setFixedWidth(60) s.setAlignment(Qt.AlignRight) s.setValidator(validator) s.setContentsMargins(0, 0, 0, 0) return s, s.textChanged def manual_cut_editline(text="", enabled=True) -> QLineEdit: edit = QLineEdit( text=text, placeholderText="e.g. 0.0, 0.5, 1.0", toolTip='<p style="white-space:pre">' + 'Enter cut points as a comma-separate list of \n' 'strictly increasing numbers e.g. 0.0, 0.5, 1.0).</p>', enabled=enabled, ) edit.setValidator(IncreasingNumbersListValidator()) edit.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) @edit.textChanged.connect def update(): validator = edit.validator() if validator is not None and edit.text().strip(): state, _, _ = validator.validate(edit.text(), 0) else: state = QValidator.Acceptable palette = edit.palette() colors = { QValidator.Intermediate: (Qt.yellow, Qt.black), QValidator.Invalid: (Qt.red, Qt.black), }.get(state, None) if colors is None: palette = QPalette() else: palette.setColor(QPalette.Base, colors[0]) palette.setColor(QPalette.Text, colors[1]) cr = edit.cursorRect() p = edit.mapToGlobal(cr.bottomRight()) edit.setPalette(palette) if state != QValidator.Acceptable and edit.isVisible(): validator.show_tip(edit, p, edit.toolTip(), textFormat=Qt.RichText) else: validator.show_tip(edit, p, "") return edit, edit.textChanged children = [] def button(id_, *controls, stretch=True): layout = QHBoxLayout() desc = Options[id_] button = QRadioButton(desc.label) button.setToolTip(desc.tooltip) self.button_group.addButton(button, id_) layout.addWidget(button) if controls: if stretch: layout.addStretch(1) for c, signal in controls: layout.addWidget(c) if signal is not None: @signal.connect def arg_changed(): self.button_group.button(id_).setChecked(True) self.update_hints(id_) children.append(layout) button_box.layout().addLayout(layout) return (*controls, (None, ))[0][0] button_box = gui.vBox(box) button_box.layout().setSpacing(0) button_box.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)) self.button_group = QButtonGroup(self) self.button_group.idClicked.connect(self.update_hints) button(Methods.Keep) button(Methods.Remove) self.binning_spin = button(Methods.Binning, intspin()) validator = QDoubleValidator() validator.setBottom(0) self.width_line = button(Methods.FixedWidth, widthline(validator)) self.width_time_unit = u = QComboBox(self) u.setContentsMargins(0, 0, 0, 0) u.addItems([unit + "(s)" for unit in time_units]) validator = QIntValidator() validator.setBottom(1) self.width_time_line = button(Methods.FixedWidthTime, widthline(validator), (u, u.currentTextChanged)) self.freq_spin = button(Methods.EqualFreq, intspin()) self.width_spin = button(Methods.EqualWidth, intspin()) button(Methods.MDL) self.copy_to_custom = FixedSizeButton( text="CC", toolTip="Copy the current cut points to manual mode") self.copy_to_custom.clicked.connect(self._copy_to_manual) self.threshold_line = button(Methods.Custom, manual_cut_editline(), (self.copy_to_custom, None), stretch=False) button(Methods.Default) maxheight = max(w.sizeHint().height() for w in children) for w in children: w.itemAt(0).widget().setFixedHeight(maxheight) button_box.layout().addStretch(1)
def __init__(self): super().__init__() # var models self.x_var_model = itemmodels.VariableListModel() self.y_var_model = itemmodels.VariableListModel() # info box self.info_box = gui.widgetBox(self.controlArea, "Info") self.learner_label = gui.label(widget=self.info_box, master=self, label="") # options box policy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.options_box = gui.widgetBox(self.controlArea, "Data") opts = dict(widget=self.options_box, master=self, orientation=Qt.Horizontal, callback=self.change_attributes, sendSelectedValue=True, maximumContentsLength=15) self.cbx = gui.comboBox(value='attr_x', label='X:', **opts) self.cby = gui.comboBox(value='attr_y', label='Y:', **opts) self.target_class_combobox = gui.comboBox(value='target_class', label='Target class: ', **opts) self.cbx.setModel(self.x_var_model) self.cby.setModel(self.y_var_model) gui.separator(self.controlArea, 20, 20) # properties box self.properties_box = gui.widgetBox(self.controlArea, "Properties") self.alpha_spin = gui.spin(widget=self.properties_box, master=self, callback=self.change_alpha, value="alpha", label="Learning rate: ", minv=0.001, maxv=100, step=0.001, spinType=float, decimals=3, alignment=Qt.AlignRight, controlWidth=80) self.stochastic_checkbox = gui.checkBox( widget=self.properties_box, master=self, callback=self.change_stochastic, value="stochastic", label="Stochastic ") self.step_size_spin = gui.spin(widget=self.properties_box, master=self, callback=self.change_step, value="step_size", label="Step size: ", minv=1, maxv=100, step=1, alignment=Qt.AlignRight, controlWidth=80) self.restart_button = gui.button(widget=self.properties_box, master=self, callback=self.restart, label="Restart") self.alpha_spin.setSizePolicy(policy) self.step_size_spin.setSizePolicy(policy) gui.separator(self.controlArea, 20, 20) # step box self.step_box = gui.widgetBox(self.controlArea, "Manually step through") self.step_button = gui.button(widget=self.step_box, master=self, callback=self.step, label="Step", default=True) self.step_back_button = gui.button(widget=self.step_box, master=self, callback=self.step_back, label="Step back") gui.separator(self.controlArea, 20, 20) # run box self.run_box = gui.widgetBox(self.controlArea, "Run") self.auto_play_button = gui.button(widget=self.run_box, master=self, label=self.auto_play_button_text[0], callback=self.auto_play) self.auto_play_speed_spinner = gui.hSlider(widget=self.run_box, master=self, value='auto_play_speed', minValue=0, maxValue=1.91, step=0.1, intOnly=False, createLabel=False, label='Speed:') # graph in mainArea self.scatter = Scatterplot( click_callback=self.change_theta, xAxis_gridLineWidth=0, yAxis_gridLineWidth=0, title_text='', tooltip_shared=False, legend=dict(enabled=False), ) gui.rubber(self.controlArea) # Just render an empty chart so it shows a nice 'No data to display' self.scatter.chart() self.mainArea.layout().addWidget(self.scatter) self.step_size_lock() self.step_back_button_lock()
def __init__(self, parent=None, bridge=None, *, debug=False, **kwargs): debug = debug or _ORANGE_DEBUG if debug: port = os.environ.setdefault("QTWEBENGINE_REMOTE_DEBUGGING", "12088") warnings.warn( "To debug QWebEngineView, set environment variable " "QTWEBENGINE_REMOTE_DEBUGGING={port} and then visit " "http://127.0.0.1:{port}/ in a Chromium-based browser. " "See https://doc.qt.io/qt-5/qtwebengine-debugging.html " "This has also been done for you.".format(port=port)) super().__init__(parent, sizeHint=QSize(500, 400), sizePolicy=QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding), **kwargs) self.bridge = bridge self.debug = debug with open(_WEBVIEW_HELPERS, encoding="utf-8") as f: self._onloadJS( f.read(), name="webview_helpers", injection_point=QWebEngineScript.DocumentCreation, ) qtwebchannel_js = QFile("://qtwebchannel/qwebchannel.js") if qtwebchannel_js.open(QFile.ReadOnly): source = bytes(qtwebchannel_js.readAll()).decode("utf-8") with open(_WEBENGINE_INIT_WEBCHANNEL, encoding="utf-8") as f: init_webchannel_src = f.read() self._onloadJS( source + init_webchannel_src % dict(exposeObject_prefix=self._EXPOSED_OBJ_PREFIX), name="webchannel_init", injection_point=QWebEngineScript.DocumentCreation, ) else: warnings.warn( "://qtwebchannel/qwebchannel.js is not readable.", RuntimeWarning) self._onloadJS( ";window.__load_finished = true;", name="load_finished", injection_point=QWebEngineScript.DocumentReady, ) channel = QWebChannel(self) if bridge is not None: if isinstance(bridge, QWidget): warnings.warn( "Don't expose QWidgets in WebView. Construct minimal " "QObjects instead.", OrangeDeprecationWarning, stacklevel=2, ) channel.registerObject("pybridge", bridge) channel.registerObject("__bridge", _QWidgetJavaScriptWrapper(self)) self.page().setWebChannel(channel)
def __init__(self): super().__init__() self.corpus = None # Corpus self.n_matching = '' # Info on docs matching the word self.n_tokens = '' # Info on tokens self.n_types = '' # Info on types (unique tokens) self.is_word_on_input = False # Info attributes info_box = gui.widgetBox(self.controlArea, 'Info') gui.label(info_box, self, 'Tokens: %(n_tokens)s') gui.label(info_box, self, 'Types: %(n_types)s') gui.label(info_box, self, 'Matching: %(n_matching)s') # Width parameter gui.spin(self.controlArea, self, 'context_width', 3, 10, box=True, label="Number of words:", callback=self.set_width) gui.rubber(self.controlArea) # Search c_box = gui.widgetBox(self.mainArea, orientation="vertical") self.input = gui.lineEdit(c_box, self, 'word', orientation=Qt.Horizontal, sizePolicy=QSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Fixed), label='Query:', callback=self.set_word, callbackOnType=True) self.input.setFocus() # Concordances view self.conc_view = QTableView() self.model = ConcordanceModel() self.conc_view.setModel(self.model) self.conc_view.setWordWrap(False) self.conc_view.setSelectionBehavior(QTableView.SelectRows) self.conc_view.setSelectionModel(DocumentSelectionModel(self.model)) self.conc_view.setItemDelegate(HorizontalGridDelegate()) # connect selectionChanged to self.commit(), which will be # updated by gui.auto_commit() self.conc_view.selectionModel().selectionChanged.connect( lambda: self.commit()) self.conc_view.horizontalHeader().hide() self.conc_view.setShowGrid(False) self.mainArea.layout().addWidget(self.conc_view) self.set_width() # Auto-commit box gui.auto_commit(self.controlArea, self, 'autocommit', 'Commit', 'Auto commit is on')
def sizePolicy(self): return QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
def __init__(self): super().__init__() whole_box = gui.widgetBox(self.controlArea, "", orientation=False) left_box = gui.widgetBox(whole_box, "") right_box = gui.widgetBox(whole_box, "") info_box = gui.widgetBox(left_box, "Info") self.info = gui.widgetLabel( info_box, 'Input: no reporters, no partners, no commodities/services') size_policy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum) top_box = gui.widgetBox(left_box, "Type of output") gui.radioButtonsInBox(top_box, self, 'profiles_or_time_series', ['Profiles', 'Time series'], orientation=False, sizePolicy=size_policy, callback=self.clear_messages) reporter_partner_years_box = gui.widgetBox(left_box, "", orientation=False) size_policy.setHorizontalStretch(2) reporters_box = gui.widgetBox(reporter_partner_years_box, "Reporters", sizePolicy=size_policy) gui.lineEdit(reporters_box, self, 'reporter_filter', 'Filter ', callback=(lambda: self.filter(self.list_model_reporter[1], self.reporter_filter)), callbackOnType=True, orientation=False) self.list_model_reporter = self.make_continent_view( 'rep', self.on_continent_item_changed, reporters_box) size_policy.setHorizontalStretch(2) partners_box = gui.widgetBox(reporter_partner_years_box, "Partners", sizePolicy=size_policy) gui.lineEdit(partners_box, self, 'partner_filter', 'Filter ', callback=(lambda: self.filter(self.list_model_partner[1], self.partner_filter)), callbackOnType=True, orientation=False) self.list_model_partner = self.make_continent_view( 'par', self.on_continent_item_changed, partners_box) size_policy.setHorizontalStretch(1) years_box = gui.widgetBox(reporter_partner_years_box, "Years", sizePolicy=size_policy) gui.lineEdit(years_box, self, 'years_filter', 'Filter ', callback=(lambda: self.filter(self.list_model_years[1], self.years_filter)), callbackOnType=True, orientation=False) self.list_model_years = self.make_list_view(self.on_item_changed, years_box) trade_flows_box = gui.widgetBox(left_box, "Trade", orientation=False) gui.checkBox(trade_flows_box, self, 'tf_import', 'Import', callback=self.on_item_changed) exp = gui.checkBox(trade_flows_box, self, 'tf_export', 'Export', callback=self.on_item_changed) exp.setCheckState(Qt.Checked) gui.checkBox(trade_flows_box, self, 'tf_re_import', 'Re-import', callback=self.on_item_changed) gui.checkBox(trade_flows_box, self, 'tf_re_export', 'Re-export', callback=self.on_item_changed) commodities_services_box = gui.widgetBox(right_box, "Exchange Type") gui.radioButtonsInBox( commodities_services_box, self, 'commodities_or_services', ['Commodities', 'Services'], orientation=False, sizePolicy=size_policy, callback=(lambda: self.change_tree_view(commodities_services_box))) gui.lineEdit(commodities_services_box, self, 'comm_ser_filter', 'Filter ', callback=(lambda: self.filter(self.tree_model_cs[1], self. comm_ser_filter)), callbackOnType=True, orientation=False) self.tree_model_cs = self.make_tree_view('comm', self.on_item_changed, commodities_services_box) button_box = gui.widgetBox(left_box, "") self.commit_button = gui.button(button_box, self, "Commit", callback=self.commit) self.commit_button.setEnabled(False) # activate filters self.filter(self.list_model_reporter[1], self.reporter_filter) self.filter(self.list_model_partner[1], self.partner_filter) self.filter(self.list_model_years[1], self.years_filter) self.filter(self.tree_model_cs[1], self.comm_ser_filter)
def __init__(self): super().__init__() self.data = None self.editors = {} box = gui.vBox(self.controlArea, "变量定义") toplayout = QHBoxLayout() toplayout.setContentsMargins(0, 0, 0, 0) box.layout().addLayout(toplayout) self.editorstack = QStackedWidget(sizePolicy=QSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)) for descclass, editorclass in self.EDITORS: editor = editorclass() editor.featureChanged.connect(self._on_modified) self.editors[descclass] = editor self.editorstack.addWidget(editor) self.editorstack.setEnabled(False) buttonlayout = QVBoxLayout(spacing=10) buttonlayout.setContentsMargins(0, 0, 0, 0) self.addbutton = QPushButton("新建", toolTip="Create a new variable", minimumWidth=120, shortcut=QKeySequence.New) def unique_name(fmt, reserved): candidates = (fmt.format(i) for i in count(1)) return next(c for c in candidates if c not in reserved) def generate_newname(fmt): return unique_name(fmt, self.reserved_names()) menu = QMenu(self.addbutton) cont = menu.addAction("数值数据") cont.triggered.connect(lambda: self.addFeature( ContinuousDescriptor(generate_newname("X{}"), "", 3))) disc = menu.addAction("分类数据") disc.triggered.connect(lambda: self.addFeature( DiscreteDescriptor(generate_newname("D{}"), "", (), False))) string = menu.addAction("文本") string.triggered.connect(lambda: self.addFeature( StringDescriptor(generate_newname("S{}"), ""))) datetime = menu.addAction("日期/时间") datetime.triggered.connect(lambda: self.addFeature( DateTimeDescriptor(generate_newname("T{}"), ""))) menu.addSeparator() self.duplicateaction = menu.addAction("复制选中变量") self.duplicateaction.triggered.connect(self.duplicateFeature) self.duplicateaction.setEnabled(False) self.addbutton.setMenu(menu) self.removebutton = QPushButton("删除", toolTip="删除选中变量", minimumWidth=120, shortcut=QKeySequence.Delete) self.removebutton.clicked.connect(self.removeSelectedFeature) buttonlayout.addWidget(self.addbutton) buttonlayout.addWidget(self.removebutton) buttonlayout.addStretch(10) toplayout.addLayout(buttonlayout, 0) toplayout.addWidget(self.editorstack, 10) # Layout for the list view layout = QVBoxLayout(spacing=1, margin=0) self.featuremodel = DescriptorModel(parent=self) self.featureview = QListView(minimumWidth=200, minimumHeight=50, sizePolicy=QSizePolicy( QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)) self.featureview.setItemDelegate(FeatureItemDelegate(self)) self.featureview.setModel(self.featuremodel) self.featureview.selectionModel().selectionChanged.connect( self._on_selectedVariableChanged) layout.addWidget(self.featureview) box.layout().addLayout(layout, 1) self.fix_button = gui.button(self.buttonsArea, self, "Upgrade Expressions", callback=self.fix_expressions) self.fix_button.setHidden(True) gui.button(self.buttonsArea, self, "Send", callback=self.apply, default=True)
def set_numeric_le(le): """ Smaller line edit that does not expand. """ le.sizeHintFactor = 0.8 le.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)) return le
def __init__(self): super().__init__() self.matrix = None self._matrix_range = 0. self._tree = None self._ordered_tree = None self._sorted_matrix = None self._sort_indices = None self._selection = None self.sorting_cb = gui.comboBox( self.controlArea, self, "sorting", box="Element Sorting", items=["None", "Clustering", "Clustering with ordered leaves"], callback=self._invalidate_ordering) box = gui.vBox(self.controlArea, "Colors") self.color_map_widget = cmw = ColorGradientSelection( thresholds=(self.color_low, self.color_high), ) model = itemmodels.ContinuousPalettesModel(parent=self) cmw.setModel(model) idx = cmw.findData(self.palette_name, model.KeyRole) if idx != -1: cmw.setCurrentIndex(idx) cmw.activated.connect(self._update_color) def _set_thresholds(low, high): self.color_low, self.color_high = low, high self._update_color() cmw.thresholdsChanged.connect(_set_thresholds) box.layout().addWidget(self.color_map_widget) self.annot_combo = gui.comboBox(self.controlArea, self, "annotation_idx", box="Annotations", contentsLength=12, searchable=True, callback=self._invalidate_annotations) self.annot_combo.setModel(itemmodels.VariableListModel()) self.annot_combo.model()[:] = ["None", "Enumeration"] gui.rubber(self.controlArea) gui.auto_send(self.buttonsArea, self, "autocommit") self.view = GraphicsView(background=None) self.mainArea.layout().addWidget(self.view) self.grid_widget = pg.GraphicsWidget() self.grid = QGraphicsGridLayout() self.grid_widget.setLayout(self.grid) self.gradient_legend = GradientLegendWidget(0, 1, self._color_map()) self.gradient_legend.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.gradient_legend.setMaximumWidth(250) self.grid.addItem(self.gradient_legend, 0, 1) self.viewbox = pg.ViewBox(enableMouse=False, enableMenu=False) self.viewbox.setAcceptedMouseButtons(Qt.NoButton) self.viewbox.setAcceptHoverEvents(False) self.grid.addItem(self.viewbox, 2, 1) self.left_dendrogram = DendrogramWidget( self.grid_widget, orientation=DendrogramWidget.Left, selectionMode=DendrogramWidget.NoSelection, hoverHighlightEnabled=False) self.left_dendrogram.setAcceptedMouseButtons(Qt.NoButton) self.left_dendrogram.setAcceptHoverEvents(False) self.top_dendrogram = DendrogramWidget( self.grid_widget, orientation=DendrogramWidget.Top, selectionMode=DendrogramWidget.NoSelection, hoverHighlightEnabled=False) self.top_dendrogram.setAcceptedMouseButtons(Qt.NoButton) self.top_dendrogram.setAcceptHoverEvents(False) self.grid.addItem(self.left_dendrogram, 2, 0) self.grid.addItem(self.top_dendrogram, 1, 1) self.right_labels = TextList(alignment=Qt.AlignLeft | Qt.AlignVCenter, sizePolicy=QSizePolicy( QSizePolicy.Fixed, QSizePolicy.Expanding)) self.bottom_labels = TextList( orientation=Qt.Horizontal, alignment=Qt.AlignRight | Qt.AlignVCenter, sizePolicy=QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)) self.grid.addItem(self.right_labels, 2, 2) self.grid.addItem(self.bottom_labels, 3, 1) self.view.setCentralItem(self.grid_widget) self.gradient_legend.hide() self.left_dendrogram.hide() self.top_dendrogram.hide() self.right_labels.hide() self.bottom_labels.hide() self.matrix_item = None self.dendrogram = None self.settingsAboutToBePacked.connect(self.pack_settings)
def __init__(self): super().__init__() self.data = None self.editors = {} box = gui.vBox(self.controlArea, "Variable Definitions") toplayout = QHBoxLayout() toplayout.setContentsMargins(0, 0, 0, 0) box.layout().addLayout(toplayout) self.editorstack = QStackedWidget( sizePolicy=QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) ) for descclass, editorclass in self.EDITORS: editor = editorclass() editor.featureChanged.connect(self._on_modified) self.editors[descclass] = editor self.editorstack.addWidget(editor) self.editorstack.setEnabled(False) buttonlayout = QVBoxLayout(spacing=10) buttonlayout.setContentsMargins(0, 0, 0, 0) self.addbutton = QPushButton( "New", toolTip="Create a new variable", minimumWidth=120, shortcut=QKeySequence.New ) def unique_name(fmt, reserved): candidates = (fmt.format(i) for i in count(1)) return next(c for c in candidates if c not in reserved) def reserved_names(): varnames = [] if self.data is not None: varnames = [var.name for var in self.data.domain.variables + self.data.domain.metas] varnames += [desc.name for desc in self.featuremodel] return set(varnames) def generate_newname(fmt): return unique_name(fmt, reserved_names()) menu = QMenu(self.addbutton) cont = menu.addAction("Continuous") cont.triggered.connect( lambda: self.addFeature( ContinuousDescriptor(generate_newname("X{}"), "", 3)) ) disc = menu.addAction("Discrete") disc.triggered.connect( lambda: self.addFeature( DiscreteDescriptor(generate_newname("D{}"), "", ("A", "B"), -1, False)) ) string = menu.addAction("String") string.triggered.connect( lambda: self.addFeature( StringDescriptor(generate_newname("S{}"), "")) ) menu.addSeparator() self.duplicateaction = menu.addAction("Duplicate Selected Variable") self.duplicateaction.triggered.connect(self.duplicateFeature) self.duplicateaction.setEnabled(False) self.addbutton.setMenu(menu) self.removebutton = QPushButton( "Remove", toolTip="Remove selected variable", minimumWidth=120, shortcut=QKeySequence.Delete ) self.removebutton.clicked.connect(self.removeSelectedFeature) buttonlayout.addWidget(self.addbutton) buttonlayout.addWidget(self.removebutton) buttonlayout.addStretch(10) toplayout.addLayout(buttonlayout, 0) toplayout.addWidget(self.editorstack, 10) # Layout for the list view layout = QVBoxLayout(spacing=1, margin=0) self.featuremodel = DescriptorModel(parent=self) self.featureview = QListView( minimumWidth=200, sizePolicy=QSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) ) self.featureview.setItemDelegate(FeatureItemDelegate(self)) self.featureview.setModel(self.featuremodel) self.featureview.selectionModel().selectionChanged.connect( self._on_selectedVariableChanged ) layout.addWidget(self.featureview) box.layout().addLayout(layout, 1) box = gui.hBox(self.controlArea) box.layout().addWidget(self.report_button) self.report_button.setMinimumWidth(180) gui.rubber(box) commit = gui.button(box, self, "Send", callback=self.apply, default=True) commit.setMinimumWidth(180)
def __init__(self): super().__init__() self.matrix = None self._tree = None self._ordered_tree = None self._sorted_matrix = None self._sort_indices = None self._selection = None self.sorting_cb = gui.comboBox( self.controlArea, self, "sorting", box="Element Sorting", items=["None", "Clustering", "Clustering with ordered leaves"], callback=self._invalidate_ordering) box = gui.vBox(self.controlArea, "Colors") self.color_box = gui.palette_combo_box(self.palette_name) self.color_box.currentIndexChanged.connect(self._update_color) box.layout().addWidget(self.color_box) form = QFormLayout( formAlignment=Qt.AlignLeft, labelAlignment=Qt.AlignLeft, fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow ) # form.addRow( # "Gamma", # gui.hSlider(box, self, "color_gamma", minValue=0.0, maxValue=1.0, # step=0.05, ticks=True, intOnly=False, # createLabel=False, callback=self._update_color) # ) form.addRow( "Low:", gui.hSlider(box, self, "color_low", minValue=0.0, maxValue=1.0, step=0.05, ticks=True, intOnly=False, createLabel=False, callback=self._update_color) ) form.addRow( "High:", gui.hSlider(box, self, "color_high", minValue=0.0, maxValue=1.0, step=0.05, ticks=True, intOnly=False, createLabel=False, callback=self._update_color) ) box.layout().addLayout(form) self.annot_combo = gui.comboBox( self.controlArea, self, "annotation_idx", box="Annotations", callback=self._invalidate_annotations, contentsLength=12) self.annot_combo.setModel(itemmodels.VariableListModel()) self.annot_combo.model()[:] = ["None", "Enumeration"] self.controlArea.layout().addStretch() gui.auto_send(self.controlArea, self, "autocommit") self.view = pg.GraphicsView(background="w") self.mainArea.layout().addWidget(self.view) self.grid_widget = pg.GraphicsWidget() self.grid = QGraphicsGridLayout() self.grid_widget.setLayout(self.grid) self.viewbox = pg.ViewBox(enableMouse=False, enableMenu=False) self.viewbox.setAcceptedMouseButtons(Qt.NoButton) self.viewbox.setAcceptHoverEvents(False) self.grid.addItem(self.viewbox, 1, 1) self.left_dendrogram = DendrogramWidget( self.grid_widget, orientation=DendrogramWidget.Left, selectionMode=DendrogramWidget.NoSelection, hoverHighlightEnabled=False ) self.left_dendrogram.setAcceptedMouseButtons(Qt.NoButton) self.left_dendrogram.setAcceptHoverEvents(False) self.top_dendrogram = DendrogramWidget( self.grid_widget, orientation=DendrogramWidget.Top, selectionMode=DendrogramWidget.NoSelection, hoverHighlightEnabled=False ) self.top_dendrogram.setAcceptedMouseButtons(Qt.NoButton) self.top_dendrogram.setAcceptHoverEvents(False) self.grid.addItem(self.left_dendrogram, 1, 0) self.grid.addItem(self.top_dendrogram, 0, 1) self.right_labels = TextList( alignment=Qt.AlignLeft | Qt.AlignVCenter, sizePolicy=QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) ) self.bottom_labels = TextList( orientation=Qt.Horizontal, alignment=Qt.AlignRight | Qt.AlignVCenter, sizePolicy=QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) ) self.grid.addItem(self.right_labels, 1, 2) self.grid.addItem(self.bottom_labels, 2, 1) self.view.setCentralItem(self.grid_widget) self.left_dendrogram.hide() self.top_dendrogram.hide() self.right_labels.hide() self.bottom_labels.hide() self.matrix_item = None self.dendrogram = None self.grid_widget.scene().installEventFilter(self) self.settingsAboutToBePacked.connect(self.pack_settings)
def __init__(self, *args, thresholds=(0.0, 1.0), center=None, **kwargs): super().__init__(*args, **kwargs) low = round(clip(thresholds[0], 0., 1.), 2) high = round(clip(thresholds[1], 0., 1.), 2) high = max(low, high) self.__threshold_low, self.__threshold_high = low, high self.__center = center form = QFormLayout( formAlignment=Qt.AlignLeft, labelAlignment=Qt.AlignLeft, fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow ) form.setContentsMargins(0, 0, 0, 0) self.gradient_cb = QComboBox( None, objectName="gradient-combo-box", ) self.gradient_cb.setAttribute(Qt.WA_LayoutUsesWidgetRect) icsize = self.style().pixelMetric( QStyle.PM_SmallIconSize, None, self.gradient_cb ) self.gradient_cb.setIconSize(QSize(64, icsize)) model = itemmodels.ContinuousPalettesModel() model.setParent(self) self.gradient_cb.setModel(model) self.gradient_cb.activated[int].connect(self.activated) self.gradient_cb.currentIndexChanged.connect(self.currentIndexChanged) if center is not None: def on_center_spin_value_changed(value): if self.__center != value: self.__center = value self.centerChanged.emit(self.__center) self.center_box = QWidget() center_layout = QHBoxLayout() self.center_box.setLayout(center_layout) self.center_edit = DoubleSpinBox( value=self.__center, minimum=DBL_MIN, maximum=DBL_MAX, minimumStep=0.01, minimumContentsLenght=8, stepType=DoubleSpinBox.AdaptiveDecimalStepType, keyboardTracking=False, sizePolicy=QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) ) self.center_edit.valueChanged.connect(on_center_spin_value_changed) center_layout.setContentsMargins(0, 0, 0, 0) center_layout.addStretch(1) center_layout.addWidget(QLabel("Centered at")) center_layout.addWidget(self.center_edit) self.gradient_cb.currentIndexChanged.connect( self.__update_center_visibility) else: self.center_box = None slider_low = Slider( objectName="threshold-low-slider", minimum=0, maximum=100, value=int(low * 100), orientation=Qt.Horizontal, tickPosition=QSlider.TicksBelow, pageStep=10, toolTip=self.tr("Low gradient threshold"), whatsThis=self.tr("Applying a low threshold will squeeze the " "gradient from the lower end") ) slider_high = Slider( objectName="threshold-low-slider", minimum=0, maximum=100, value=int(high * 100), orientation=Qt.Horizontal, tickPosition=QSlider.TicksAbove, pageStep=10, toolTip=self.tr("High gradient threshold"), whatsThis=self.tr("Applying a high threshold will squeeze the " "gradient from the higher end") ) form.setWidget(0, QFormLayout.SpanningRole, self.gradient_cb) if self.center_box: form.setWidget(1, QFormLayout.SpanningRole, self.center_box) form.addRow(self.tr("Low:"), slider_low) form.addRow(self.tr("High:"), slider_high) self.slider_low = slider_low self.slider_high = slider_high self.slider_low.valueChanged.connect(self.__on_slider_low_moved) self.slider_high.valueChanged.connect(self.__on_slider_high_moved) self.setLayout(form)
def _init_ui(self): namesBox = gui.vBox(self.controlArea, "Names") hbox = gui.hBox(namesBox, margin=0, spacing=0) gui.lineEdit(hbox, self, "attr1", "Variable X: ", controlWidth=80, orientation=Qt.Horizontal, callback=self._attr_name_changed) gui.separator(hbox, 21) hbox = gui.hBox(namesBox, margin=0, spacing=0) attr2 = gui.lineEdit(hbox, self, "attr2", "Variable Y: ", controlWidth=80, orientation=Qt.Horizontal, callback=self._attr_name_changed) gui.separator(hbox) gui.checkBox(hbox, self, "hasAttr2", '', disables=attr2, labelWidth=0, callback=self.set_dimensions) gui.widgetLabel(namesBox, "Labels") self.classValuesView = listView = gui.ListViewWithSizeHint( preferred_size=(-1, 30)) listView.setModel(self.class_model) itemmodels.select_row(listView, 0) namesBox.layout().addWidget(listView) self.addClassLabel = QAction("+", self, toolTip="Add new class label", triggered=self.add_new_class_label) self.removeClassLabel = QAction( unicodedata.lookup("MINUS SIGN"), self, toolTip="Remove selected class label", triggered=self.remove_selected_class_label) actionsWidget = itemmodels.ModelActionsWidget( [self.addClassLabel, self.removeClassLabel], self) actionsWidget.layout().addStretch(10) actionsWidget.layout().setSpacing(1) namesBox.layout().addWidget(actionsWidget) tBox = gui.vBox(self.buttonsArea, "Tools") toolsBox = gui.widgetBox(tBox, orientation=QGridLayout()) self.toolActions = QActionGroup(self) self.toolActions.setExclusive(True) self.toolButtons = [] for i, (name, tooltip, tool, icon) in enumerate(self.TOOLS): action = QAction( name, self, toolTip=tooltip, checkable=tool.checkable, icon=QIcon(icon), ) action.triggered.connect(partial(self.set_current_tool, tool)) button = QToolButton(iconSize=QSize(24, 24), toolButtonStyle=Qt.ToolButtonTextUnderIcon, sizePolicy=QSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)) button.setDefaultAction(action) self.toolButtons.append((button, tool)) toolsBox.layout().addWidget(button, i / 3, i % 3) self.toolActions.addAction(action) for column in range(3): toolsBox.layout().setColumnMinimumWidth(column, 10) toolsBox.layout().setColumnStretch(column, 1) undo = self.undo_stack.createUndoAction(self) redo = self.undo_stack.createRedoAction(self) undo.setShortcut(QKeySequence.Undo) redo.setShortcut(QKeySequence.Redo) self.addActions([undo, redo]) self.undo_stack.indexChanged.connect(self.invalidate) indBox = gui.indentedBox(tBox, sep=8) form = QFormLayout(formAlignment=Qt.AlignLeft, labelAlignment=Qt.AlignLeft, fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow) indBox.layout().addLayout(form) slider = gui.hSlider(indBox, self, "brushRadius", minValue=1, maxValue=100, createLabel=False, addToLayout=False) form.addRow("Radius:", slider) slider = gui.hSlider(indBox, self, "density", None, minValue=1, maxValue=100, createLabel=False, addToLayout=False) form.addRow("Intensity:", slider) slider = gui.hSlider(indBox, self, "symbol_size", None, minValue=1, maxValue=100, createLabel=False, callback=self.set_symbol_size, addToLayout=False) form.addRow("Symbol:", slider) self.btResetToInput = gui.button(tBox, self, "Reset to Input Data", self.reset_to_input) self.btResetToInput.setDisabled(True) gui.auto_send(self.buttonsArea, self, "autocommit") # main area GUI viewbox = PaintViewBox(enableMouse=False) self.plotview = pg.PlotWidget(background="w", viewBox=viewbox) self.plotview.sizeHint = lambda: QSize( 200, 100) # Minimum size for 1-d painting self.plot = self.plotview.getPlotItem() axis_color = self.palette().color(QPalette.Text) axis_pen = QPen(axis_color) tickfont = QFont(self.font()) tickfont.setPixelSize(max(int(tickfont.pixelSize() * 2 // 3), 11)) axis = self.plot.getAxis("bottom") axis.setLabel(self.attr1) axis.setPen(axis_pen) axis.setTickFont(tickfont) axis = self.plot.getAxis("left") axis.setLabel(self.attr2) axis.setPen(axis_pen) axis.setTickFont(tickfont) if not self.hasAttr2: self.plot.hideAxis('left') self.plot.hideButtons() self.plot.setXRange(0, 1, padding=0.01) self.mainArea.layout().addWidget(self.plotview) # enable brush tool self.toolActions.actions()[0].setChecked(True) self.set_current_tool(self.TOOLS[0][2]) self.set_dimensions()
def _setup_gui(self): # control area library_box: QGroupBox = gui.vBox(self.controlArea, "Library") library_box.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Maximum) edit_triggers = QListView.DoubleClicked | QListView.EditKeyPressed self.__library_view = QListView( editTriggers=int(edit_triggers), minimumWidth=200, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding), ) self.__library_view.setFixedHeight(100) self.__library_view.setItemDelegate(LibraryItemDelegate(self)) self.__library_view.setModel(self.__model) self.__library_view.selectionModel().selectionChanged.connect( self.__on_selection_changed ) actions_widget = ModelActionsWidget() actions_widget.layout().setSpacing(1) tool_tip = "Add a new ontology to the library" action = QAction("+", self, toolTip=tool_tip) action.triggered.connect(self.__on_add) actions_widget.addAction(action) tool_tip = "Remove the ontology from the library" action = QAction("\N{MINUS SIGN}", self, toolTip=tool_tip) action.triggered.connect(self.__on_remove) actions_widget.addAction(action) tool_tip = "Save changes in the editor to the library" action = QAction("Update", self, toolTip=tool_tip) action.triggered.connect(self.__on_update) actions_widget.addAction(action) gui.rubber(actions_widget) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import Ontology from File", self) new_from_file.triggered.connect(self.__on_import_file) new_from_url = QAction("Import Ontology from URL", self) new_from_url.triggered.connect(self.__on_import_url) save_to_file = QAction("Save Ontology to File", self) save_to_file.triggered.connect(self.__on_save) menu = QMenu(actions_widget) menu.addAction(new_from_file) menu.addAction(new_from_url) menu.addAction(save_to_file) action.setMenu(menu) button = actions_widget.addAction(action) button.setPopupMode(QToolButton.InstantPopup) vlayout = QVBoxLayout() vlayout.setSpacing(1) vlayout.setContentsMargins(0, 0, 0, 0) vlayout.addWidget(self.__library_view) vlayout.addWidget(actions_widget) library_box.layout().setSpacing(1) library_box.layout().addLayout(vlayout) input_box: QGroupBox = gui.vBox(self.controlArea, "Input") self.__input_view = ListViewSearch( sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding), selectionMode=QListView.ExtendedSelection, dragEnabled=True, ) self.__input_view.setModel(self.__input_model) self.__input_view.selectionModel().selectionChanged.connect( self._enable_include_button ) self.__inc_button = gui.button( None, self, self.INC_BUTTON, enabled=False, toolTip="Include selected words into the ontology", autoDefault=False, callback=self.__on_toggle_include ) input_box.layout().setSpacing(1) input_box.layout().addWidget(self.__input_view) input_box.layout().addWidget(self.__inc_button) self.__run_button = gui.button( self.controlArea, self, self.RUN_BUTTON, callback=self.__on_toggle_run ) gui.checkBox( self.controlArea, self, "include_children", "Include subtree", box="Output", callback=self.commit.deferred ) box = gui.vBox(self.controlArea, "Ontology info") gui.label(box, self, "%(ontology_info)s") gui.auto_send(self.buttonsArea, self, "auto_commit") # main area ontology_box: QGroupBox = gui.vBox(self.mainArea, box=True) self.__ontology_view = EditableTreeView(self) self.__ontology_view.dataChanged.connect( self.__on_ontology_data_changed ) self.__ontology_view.selectionChanged.connect(self.commit.deferred) ontology_box.layout().setSpacing(1) ontology_box.layout().addWidget(self.__ontology_view) self._enable_include_button()
def __init__(self): super().__init__() self.corpus = None # Corpus self.corpus_docs = None # Documents generated from Corpus self.output_mask = [] # Output corpus indices self.doc_webview = None # WebView for showing content self.search_features = [ ] # two copies are needed since Display allows drag & drop self.display_list_indices = [0] # Info attributes self.update_info() info_box = gui.widgetBox(self.controlArea, 'Info') gui.label(info_box, self, 'Documents: %(n_documents)s') gui.label(info_box, self, 'Preprocessed: %(is_preprocessed)s') gui.label(info_box, self, ' ◦ Tokens: %(n_tokens)s') gui.label(info_box, self, ' ◦ Types: %(n_types)s') gui.label(info_box, self, 'POS tagged: %(is_pos_tagged)s') gui.label(info_box, self, 'N-grams range: %(ngram_range)s') gui.label(info_box, self, 'Matching: %(n_matching)s') # Search features self.search_listbox = gui.listBox( self.controlArea, self, 'search_indices', 'search_features', selectionMode=QListView.ExtendedSelection, box='Search features', callback=self.search_features_changed) # Display features display_box = gui.widgetBox(self.controlArea, 'Display features') self.display_listbox = gui.listBox( display_box, self, 'display_list_indices', 'display_features', selectionMode=QListView.ExtendedSelection, callback=self.show_docs, enableDragDrop=True) self.show_tokens_checkbox = gui.checkBox(display_box, self, 'show_tokens', 'Show Tokens && Tags', callback=self.show_docs) # Auto-commit box gui.auto_commit(self.controlArea, self, 'autocommit', 'Send data', 'Auto send is on') # Search self.filter_input = gui.lineEdit(self.mainArea, self, 'regexp_filter', orientation=Qt.Horizontal, sizePolicy=QSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Fixed), label='RegExp Filter:') self.filter_input.textChanged.connect(self.refresh_search) # Main area self.splitter = QSplitter( orientation=Qt.Horizontal, childrenCollapsible=False, ) # Document list self.doc_list = QTableView() self.doc_list.setSelectionBehavior(QTableView.SelectRows) self.doc_list.setSelectionMode(QTableView.ExtendedSelection) self.doc_list.setEditTriggers(QAbstractItemView.NoEditTriggers) self.doc_list.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) self.doc_list.horizontalHeader().setVisible(False) self.splitter.addWidget(self.doc_list) self.doc_list_model = QStandardItemModel(self) self.doc_list.setModel(self.doc_list_model) self.doc_list.selectionModel().selectionChanged.connect(self.show_docs) # Document contents self.doc_webview = gui.WebviewWidget(self.splitter, debug=False) self.doc_webview.loadFinished.connect(self.highlight_docs) self.mainArea.layout().addWidget(self.splitter)
def __init__(self): super().__init__() self.in_data = None self.in_distance = None self.in_learner = None self.in_classifier = None self.in_object = None for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = gui.vBox(self.controlArea, 'Info') gui.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ "<li>".join(t.name for t in self.inputs) + \ "</ul></p><p>Output variables:<ul><li>" + \ "<li>".join(t.name for t in self.outputs) + \ "</ul></p>" ) self.libraryList = itemmodels.PyListModel( [], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = gui.vBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = itemmodels.ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import Script from File", self) save_to_file = QAction("Save Selected Script to File", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.execute_button = gui.auto_commit(self.controlArea, self, "auto_execute", "Execute", auto_label="Auto Execute") self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = gui.vBox(self, 'Python Script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.setToolTip("Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) action.triggered.connect(self.saveScript) self.consoleBox = gui.vBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole({}, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600)
def __init__(self): super().__init__() for name in self.signal_names: setattr(self, name, []) self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) # Styling self.defaultFont = defaultFont = ( 'Menlo' if sys.platform == 'darwin' else 'Courier' if sys.platform in ['win32', 'cygwin'] else 'DejaVu Sans Mono') self.defaultFontSize = defaultFontSize = 13 self.editorBox = gui.vBox(self, box="Editor", spacing=4) self.splitCanvas.addWidget(self.editorBox) darkMode = QApplication.instance().property('darkMode') scheme_name = 'Dark' if darkMode else 'Light' syntax_highlighting_scheme = SYNTAX_HIGHLIGHTING_STYLES[scheme_name] self.pygments_style_class = make_pygments_style(scheme_name) eFont = QFont(defaultFont) eFont.setPointSize(defaultFontSize) # Fake Signature self.func_sig = func_sig = FunctionSignature( self.editorBox, syntax_highlighting_scheme, eFont) # Editor editor = PythonEditor(self) editor.setFont(eFont) editor.setup_completer_appearance((300, 180), eFont) # Fake return return_stmt = ReturnStatement(self.editorBox, syntax_highlighting_scheme, eFont) self.return_stmt = return_stmt # Match indentation textEditBox = QWidget(self.editorBox) textEditBox.setLayout(QHBoxLayout()) char_4_width = QFontMetrics(eFont).horizontalAdvance('0000') @editor.viewport_margins_updated.connect def _(width): func_sig.setIndent(width) textEditMargin = max(0, round(char_4_width - width)) return_stmt.setIndent(textEditMargin + width) textEditBox.layout().setContentsMargins(textEditMargin, 0, 0, 0) self.text = editor textEditBox.layout().addWidget(editor) self.editorBox.layout().addWidget(func_sig) self.editorBox.layout().addWidget(textEditBox) self.editorBox.layout().addWidget(return_stmt) self.editorBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) # Controls self.editor_controls = gui.vBox(self.controlArea, box='Preferences') self.vim_box = gui.hBox(self.editor_controls, spacing=20) self.vim_indicator = VimIndicator(self.vim_box) vim_sp = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) vim_sp.setRetainSizeWhenHidden(True) self.vim_indicator.setSizePolicy(vim_sp) def enable_vim_mode(): editor.vimModeEnabled = self.vimModeEnabled self.vim_indicator.setVisible(self.vimModeEnabled) enable_vim_mode() gui.checkBox(self.vim_box, self, 'vimModeEnabled', 'Vim mode', tooltip="Only for the coolest.", callback=enable_vim_mode) self.vim_box.layout().addWidget(self.vim_indicator) @editor.vimModeIndicationChanged.connect def _(color, text): self.vim_indicator.indicator_color = color self.vim_indicator.indicator_text = text self.vim_indicator.update() # Library self.libraryListSource = [] self._cachedDocuments = {} self.libraryList = itemmodels.PyListModel( [], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = gui.vBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = itemmodels.ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import Script from File", self) save_to_file = QAction("Save Selected Script to File", self) restore_saved = QAction("Undo Changes to Selected Script", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) restore_saved.triggered.connect(self.restoreSaved) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) menu.addAction(restore_saved) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.execute_button = gui.button(self.buttonsArea, self, 'Run', callback=self.commit) self.run_action = QAction("Run script", self, triggered=self.commit, shortcut=QKeySequence(Qt.ControlModifier | Qt.Key_R)) self.addAction(self.run_action) self.saveAction = action = QAction("&Save", self.text) action.setToolTip("Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) action.triggered.connect(self.saveScript) self.consoleBox = gui.vBox(self.splitCanvas, 'Console') self.console = PythonConsole({}, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.splitCanvas.setSizes([2, 1]) self.controlArea.layout().addStretch(10) self._restoreState() self.settingsAboutToBePacked.connect(self._saveState)
def setupViewport(self, widget: QWidget) -> None: """Reimplemented""" super().setupViewport(widget) sp = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) header = _HeaderGraphicsView( objectName="sticky-header-view", sizePolicy=sp, verticalScrollBarPolicy=Qt.ScrollBarAlwaysOff, horizontalScrollBarPolicy=Qt.ScrollBarAlwaysOff, alignment=self.alignment()) header.setFocusProxy(self) header.viewport().installEventFilter(self) header.setFrameStyle(QGraphicsView.NoFrame) footer = _HeaderGraphicsView( objectName="sticky-footer-view", sizePolicy=sp, verticalScrollBarPolicy=Qt.ScrollBarAlwaysOff, horizontalScrollBarPolicy=Qt.ScrollBarAlwaysOff, alignment=self.alignment()) footer.setFocusProxy(self) footer.viewport().installEventFilter(self) footer.setFrameStyle(QGraphicsView.NoFrame) over = _OverlayWidget( widget, objectName="sticky-header-overlay-container", alignment=Qt.AlignTop, sizePolicy=sp, visible=False, ) over.setLayout(QVBoxLayout(margin=0)) over.layout().addWidget(header) over.setWidget(widget) over = _OverlayWidget(widget, objectName="sticky-footer-overlay-container", alignment=Qt.AlignBottom, sizePolicy=sp, visible=False) over.setLayout(QVBoxLayout(margin=0)) over.layout().addWidget(footer) over.setWidget(widget) def bind(source: QScrollBar, target: QScrollBar) -> None: # bind target scroll bar to `source` (range and value). target.setRange(source.minimum(), source.maximum()) target.setValue(source.value()) source.rangeChanged.connect(target.setRange) source.valueChanged.connect(target.setValue) hbar = self.horizontalScrollBar() footer_hbar = footer.horizontalScrollBar() header_hbar = header.horizontalScrollBar() bind(hbar, footer_hbar) bind(hbar, header_hbar) self.__headerView = header self.__footerView = footer self.__updateView(header, self.__footerRect) self.__updateView(footer, self.__footerRect)
def __init__(self): super().__init__() self.libraryListSource = [] for name in self.signal_names: setattr(self, name, {}) self._cachedDocuments = {} self.infoBox = gui.vBox(self.controlArea, 'Info') gui.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + "<li>".join(map("in_{0}, in_{0}s".format, self.signal_names)) + "</ul></p><p>Output variables:<ul><li>" + "<li>".join(map("out_{0}".format, self.signal_names)) + "</ul></p>") self.libraryList = itemmodels.PyListModel( [], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = gui.vBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = itemmodels.ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import Script from File", self) save_to_file = QAction("Save Selected Script to File", self) restore_saved = QAction("Undo Changes to Selected Script", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) restore_saved.triggered.connect(self.restoreSaved) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) menu.addAction(restore_saved) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.execute_button = gui.button(self.controlArea, self, 'Run', callback=self.commit) run = QAction("Run script", self, triggered=self.commit, shortcut=QKeySequence(Qt.ControlModifier | Qt.Key_R)) self.addAction(run) self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = gui.vBox(self, 'Python Script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.setToolTip("Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) action.triggered.connect(self.saveScript) self.consoleBox = gui.vBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole({}, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) self.splitCanvas.setSizes([2, 1]) self.setAcceptDrops(True) self.controlArea.layout().addStretch(10) self._restoreState() self.settingsAboutToBePacked.connect(self._saveState)
def __init__(self): super().__init__() self.selected_node = None self.root_node = None self.model = None box = gui.vBox(self.controlArea, '树', sizePolicy=QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)) self.infolabel = gui.widgetLabel(box, '没有树.') layout = QFormLayout() layout.setFieldGrowthPolicy(layout.ExpandingFieldsGrow) box = self.display_box = gui.widgetBox(self.controlArea, "显示", orientation=layout) layout.addRow( "缩放: ", gui.hSlider(box, self, 'zoom', minValue=1, maxValue=10, step=1, ticks=False, callback=self.toggle_zoom_slider, createLabel=False, addToLayout=False)) layout.addRow( "宽度: ", gui.hSlider(box, self, 'max_node_width', minValue=50, maxValue=200, step=1, ticks=False, callback=self.toggle_node_size, createLabel=False, addToLayout=False)) policy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) layout.addRow( "深度: ", gui.comboBox(box, self, 'max_tree_depth', items=["无限制"] + ["{} 层".format(x) for x in range(2, 10)], addToLayout=False, sendSelectedValue=False, callback=self.toggle_tree_depth, sizePolicy=policy)) layout.addRow( "边缘宽度: ", gui.comboBox(box, self, 'line_width_method', items=['固定', '相对于根', '相对于父级'], addToLayout=False, callback=self.toggle_line_width, sizePolicy=policy)) gui.rubber(self.controlArea) self.scene = TreeGraphicsScene(self) self.scene_view = TreeGraphicsView(self.scene) self.scene_view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) self.mainArea.layout().addWidget(self.scene_view) self.toggle_zoom_slider() self.scene.selectionChanged.connect(self.update_selection)