def __init__( self, label: str, vmin: int, vmax: int, color: QtGui.QColor, color_pickable: bool = False, parent: "OverlayRows" = None, ): super().__init__(parent) self.label_name = QtWidgets.QLabel(label) self.colorrange = RangeSlider() self.colorrange.setRange(0, 99) self.colorrange.setValues(vmin, vmax) self.colorrange.valueChanged.connect(self.itemChanged) self.colorrange.value2Changed.connect(self.itemChanged) self.action_color = qAction( "color-picker", "Color", "Select the color for this element.", self.selectColor, ) self.action_close = qAction( "window-close", "Remove", "Remove this element.", self.close ) self.action_hide = qAction( "visibility", "Hide", "Toggle visibility of this element.", self.hideChanged ) self.action_hide.setCheckable(True) self.button_hide = qToolButton(action=self.action_hide) self.button_color = qToolButton(action=self.action_color) self.button_color.setEnabled(color_pickable) self.effect_color = QtWidgets.QGraphicsColorizeEffect() self.effect_color.setColor(color) self.button_color.setGraphicsEffect(self.effect_color) self.button_close = qToolButton(action=self.action_close) layout = QtWidgets.QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.label_name, 2) layout.addWidget(self.colorrange, 1) layout.addWidget(self.button_hide, 0) layout.addWidget(self.button_color, 0) layout.addWidget(self.button_close, 0, QtCore.Qt.AlignRight) self.setLayout(layout)
def __init__(self, widget: LaserWidget): super().__init__(widget, graphics_label="Preview") self.graphics = LaserGraphicsView(self.viewspace.options, parent=self) self.graphics.cursorValueChanged.connect( self.widget.updateCursorStatus) self.graphics.setMouseTracking(True) self.action_toggle_filter = qAction( "visibility", "Filter Visible", "Toggle visibility of the filtering.", self.toggleFilter, ) self.action_toggle_filter.setCheckable(True) self.button_hide_filter = qToolButton(action=self.action_toggle_filter) self.button_hide_filter.setToolButtonStyle( QtCore.Qt.ToolButtonTextBesideIcon) self.combo_element = QtWidgets.QComboBox() self.combo_element.activated.connect(self.completeChanged) self.combo_element.activated.connect(self.refresh) self.combo_filter = QtWidgets.QComboBox() self.combo_filter.addItems(FilteringTool.methods.keys()) self.combo_filter.setCurrentText("Rolling Median") self.combo_filter.activated.connect(self.filterChanged) self.combo_filter.activated.connect(self.completeChanged) self.combo_filter.activated.connect(self.refresh) nparams = np.amax( [len(f["params"]) for f in FilteringTool.methods.values()]) self.label_fparams = [QtWidgets.QLabel() for _ in range(nparams)] self.lineedit_fparams = [ValidColorLineEdit() for _ in range(nparams)] for le in self.lineedit_fparams: le.textEdited.connect(self.completeChanged) le.editingFinished.connect(self.refresh) le.setValidator( ConditionalLimitValidator(0.0, 0.0, 4, condition=None)) layout_graphics = QtWidgets.QVBoxLayout() layout_graphics.addWidget(self.graphics) layout_graphics.addWidget(self.combo_element, 0, QtCore.Qt.AlignRight) self.box_graphics.setLayout(layout_graphics) layout_controls = QtWidgets.QFormLayout() layout_controls.addWidget(self.combo_filter) for i in range(len(self.label_fparams)): layout_controls.addRow(self.label_fparams[i], self.lineedit_fparams[i]) layout_controls.addWidget(self.button_hide_filter) self.box_controls.setLayout(layout_controls) self.initialise()
def __init__( self, laser: Laser, item: QtWidgets.QListWidgetItem, close_button: bool, parent: "MergeLaserList", ): super().__init__(parent) self.laser = laser self.image: Optional[ScaledImageItem] = None self.item = item self.action_close = qAction( "window-close", "Remove", "Remove laser.", self.close ) self.label_name = QtWidgets.QLabel(laser.info["Name"]) self.label_offset = QtWidgets.QLabel("(0.0, 0.0)") self.combo_element = QtWidgets.QComboBox() self.combo_element.addItems(laser.elements) self.combo_element.currentTextChanged.connect( lambda _: self.elementChanged.emit(self.item) ) self.button_close = qToolButton(action=self.action_close) self.button_close.setEnabled(close_button) self.slider_alpha = QtWidgets.QSlider() self.slider_alpha.setMinimumWidth(200) self.slider_alpha.setOrientation(QtCore.Qt.Horizontal) self.slider_alpha.setRange(0, 100) self.slider_alpha.setValue(100) self.slider_alpha.valueChanged.connect( lambda _: self.alphaChanged.emit(self.item) ) layout = QtWidgets.QHBoxLayout() layout.addWidget(self.label_name, 2) layout.addWidget(self.label_offset, 0, QtCore.Qt.AlignRight) layout.addWidget(self.slider_alpha, 0, QtCore.Qt.AlignRight) layout.addWidget(self.combo_element, 0, QtCore.Qt.AlignRight) layout.addWidget(self.button_close, 0, QtCore.Qt.AlignRight) self.setLayout(layout)
def __init__(self, tabs: ViewTabBar, view: View): super().__init__(view) self.view = view self.split_button = qToolButton("view-split-left-right") self.split_button.addAction(self.view.viewspace.action_split_horz) self.split_button.addAction(self.view.viewspace.action_split_vert) self.split_button.addAction(self.view.viewspace.action_close_view) # self.split_button.addAction(self.view.viewspace.action_close_others) self.split_button.installEventFilter(self.view) # Layout the widgets layout = QtWidgets.QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(tabs, 1) layout.addWidget(self.split_button) self.setLayout(layout)
def __init__(self, config: Config, parent: QtWidgets.QWidget = None): super().__init__(parent) self.setWindowTitle("Configuration") self.config = copy.copy(config) self.action_copy = qAction( "edit-paste", "Copy to Clipboard", "Copy the current configuration to the system clipboard.", self.copyToClipboard, ) self.button_copy = qToolButton(action=self.action_copy) # Line edits self.lineedit_spotsize = QtWidgets.QLineEdit() self.lineedit_spotsize.setText(str(self.config.spotsize)) self.lineedit_spotsize.setValidator(DecimalValidator(0, 1e9, 4)) self.lineedit_spotsize.setToolTip("Diameter of the laser spot.") self.lineedit_spotsize.textChanged.connect(self.completeChanged) if isinstance(self.config, SpotConfig): self.lineedit_spotsize_y = QtWidgets.QLineEdit() self.lineedit_spotsize_y.setText(str(self.config.spotsize_y)) self.lineedit_spotsize_y.setValidator(DecimalValidator(0, 1e9, 4)) self.lineedit_spotsize_y.textChanged.connect(self.completeChanged) self.lineedit_speed = QtWidgets.QLineEdit() self.lineedit_speed.setText(str(self.config.speed)) self.lineedit_speed.setValidator(DecimalValidator(0, 1e9, 4)) self.lineedit_speed.setToolTip("Scanning speed of the laser.") self.lineedit_speed.textChanged.connect(self.completeChanged) self.lineedit_scantime = QtWidgets.QLineEdit() self.lineedit_scantime.setText(str(self.config.scantime)) self.lineedit_scantime.setValidator(DecimalValidator(0, 1e9, 4)) self.lineedit_scantime.setToolTip( "Total dwell time for one aquistion (pixel).") self.lineedit_scantime.textChanged.connect(self.completeChanged) if isinstance(self.config, SRRConfig): self.lineedit_warmup = QtWidgets.QLineEdit() self.lineedit_warmup.setText(str(self.config.warmup)) self.lineedit_warmup.setValidator(DecimalValidator(0, 1e3, 1)) self.lineedit_warmup.setToolTip( "Laser warmup time; delay before aquisition.") self.lineedit_warmup.textChanged.connect(self.completeChanged) self.spinbox_offsets = QtWidgets.QSpinBox() self.spinbox_offsets.setRange(2, 10) self.spinbox_offsets.setValue(self.config._subpixel_size) self.spinbox_offsets.setToolTip( "Number of subpixels per pixel. " "Offseting each layer by 50% will have a subpixel width of 2.") self.check_all = QtWidgets.QCheckBox("Apply config to all images.") # Form layout for line edits layout_form = QtWidgets.QFormLayout() layout_form.addRow("Spotsize (μm):", self.lineedit_spotsize) if isinstance(config, SpotConfig): layout_form.addRow("Spotsize Y (μm):", self.lineedit_spotsize_y) else: layout_form.addRow("Speed (μm/s):", self.lineedit_speed) layout_form.addRow("Scantime (s):", self.lineedit_scantime) if isinstance(config, SRRConfig): layout_form.addRow("Warmup (s):", self.lineedit_warmup) layout_form.addRow("Subpixel width:", self.spinbox_offsets) layout_horz = QtWidgets.QHBoxLayout() layout_horz.addLayout(layout_form, 1) layout_horz.addWidget(self.button_copy, 0, QtCore.Qt.AlignTop) self.layout_main.addLayout(layout_horz) self.layout_main.addWidget(self.check_all)
def __init__( self, data: np.ndarray, mask: np.ndarray = None, # colors: List[Tuple[float, ...]] = None, parent: QtWidgets.QWidget = None, ): assert data.dtype.names is not None super().__init__(parent) self.setWindowTitle("Colocalisation") self.data = data self.mask = mask self.chart = ColocalisationChart() self.combo_name1 = QtWidgets.QComboBox() self.combo_name1.addItems(data.dtype.names) self.combo_name1.currentIndexChanged.connect(self.refresh) self.combo_name2 = QtWidgets.QComboBox() self.combo_name2.addItems(data.dtype.names) self.combo_name2.setCurrentIndex(1) self.combo_name2.currentIndexChanged.connect(self.refresh) self.label_r = QtWidgets.QLabel() self.label_p = QtWidgets.QLabel() self.label_icq = QtWidgets.QLabel() self.label_m1 = QtWidgets.QLabel() self.label_m2 = QtWidgets.QLabel() self.button_p = qToolButton("view-refresh") self.button_p.setToolTip("Calculate Pearson r probability.") self.button_p.pressed.connect(self.calculatePearsonsProbablity) self.button_box = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.Close) self.button_box.rejected.connect(self.close) group_pearson = QtWidgets.QGroupBox("Pearson") layout_pearson = QtWidgets.QFormLayout() layout_pearson.addRow("r:", self.label_r) layout_p = QtWidgets.QHBoxLayout() layout_p.addWidget(self.label_p, 1) layout_p.addWidget(self.button_p, 0) layout_pearson.addRow("ρ:", layout_p) group_pearson.setLayout(layout_pearson) group_manders = QtWidgets.QGroupBox("Manders") layout_manders = QtWidgets.QFormLayout() layout_manders.addRow("M1:", self.label_m1) layout_manders.addRow("M2:", self.label_m2) group_manders.setLayout(layout_manders) group_li = QtWidgets.QGroupBox("Li") layout_li = QtWidgets.QFormLayout() layout_li.addRow("ICQ:", self.label_icq) group_li.setLayout(layout_li) layout_combos = QtWidgets.QFormLayout() layout_combos.addRow("Element 1:", self.combo_name1) layout_combos.addRow("Element 2:", self.combo_name2) layout_vert = QtWidgets.QVBoxLayout() layout_vert.addSpacing(12) layout_vert.addWidget(group_pearson) layout_vert.addWidget(group_manders) layout_vert.addWidget(group_li) layout_vert.addStretch(1) layout_vert.addLayout(layout_combos) layout_horz = QtWidgets.QHBoxLayout() layout_horz.addLayout(layout_vert) layout_horz.addWidget(self.chart, 1) layout_main = QtWidgets.QVBoxLayout() layout_main.addLayout(layout_horz) layout_main.addWidget(self.button_box) self.setLayout(layout_main) self.refresh()
def __init__( self, calibrations: Dict[str, Calibration], current_element: str, parent: QtWidgets.QWidget = None, ): super().__init__(parent) self.setWindowTitle("Calibration") self.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) self.calibrations = copy.deepcopy(calibrations) self.action_copy = qAction( "edit-paste", "Copy to Clipboard", "Copy the current calibration to the system clipboard.", self.copyToClipboard, ) self.action_copy_all = qAction( "edit-paste", "Copy All to Clipboard", "Copy the all calibrations to the system clipboard.", self.copyAllToClipboard, ) self.button_copy = qToolButton(action=self.action_copy) self.button_copy.addAction(self.action_copy_all) # LIne edits self.lineedit_gradient = QtWidgets.QLineEdit() self.lineedit_gradient.setValidator( DecimalValidatorNoZero(-1e10, 1e10, 4)) self.lineedit_gradient.setPlaceholderText("1.0000") self.lineedit_intercept = QtWidgets.QLineEdit() self.lineedit_intercept.setValidator(DecimalValidator(-1e10, 1e10, 4)) self.lineedit_intercept.setPlaceholderText("0.0000") self.lineedit_unit = QtWidgets.QLineEdit() self.lineedit_unit.setPlaceholderText("") # Element combo self.combo_element = QtWidgets.QComboBox() self.combo_element.addItems(list(self.calibrations.keys())) self.combo_element.setCurrentText(current_element) self.previous_index = self.combo_element.currentIndex() self.combo_element.currentIndexChanged.connect(self.comboChanged) # Check all self.check_all = QtWidgets.QCheckBox( "Apply calibration to all images.") # Button to plot self.button_plot = QtWidgets.QPushButton("Plot") self.button_plot.setEnabled( self.calibrations[current_element].points.size > 0) self.button_plot.pressed.connect(self.showCurve) self.points = CalibrationPointsWidget(self) self.points.levelsChanged.connect(self.updatePlotEnabled) self.points.weightingChanged.connect(self.updateLineEdits) self.points.model.dataChanged.connect(self.updateLineEdits) self.points.model.dataChanged.connect(self.updatePlotEnabled) layout_elements = QtWidgets.QHBoxLayout() layout_elements.addWidget(self.button_plot, 0, QtCore.Qt.AlignLeft) layout_elements.addWidget(self.combo_element, 0, QtCore.Qt.AlignRight) # Form layout for line edits layout_form = QtWidgets.QFormLayout() layout_form.addRow("Gradient:", self.lineedit_gradient) layout_form.addRow("Intercept:", self.lineedit_intercept) layout_form.addRow("Unit:", self.lineedit_unit) layout_horz = QtWidgets.QHBoxLayout() layout_horz.addLayout(layout_form, 1) layout_horz.addWidget(self.button_copy, 0, QtCore.Qt.AlignTop) self.layout_main.addLayout(layout_horz) self.layout_main.addWidget(self.points) self.layout_main.addWidget(self.check_all) self.layout_main.addLayout(layout_elements) self.updateLineEdits() self.updatePoints()
def __init__(self, parent: QtWidgets.QWidget): super().__init__("Points", parent) self.action_add_level = qAction( "list-add", "Add Level", "Adds a level to the calibraiton.", self.addCalibrationLevel, ) self.action_remove_level = qAction( "list-remove", "Remove Level", "Removes a level to the calibraiton.", self.removeCalibrationLevel, ) self.button_add = qToolButton(action=self.action_add_level) self.button_remove = qToolButton(action=self.action_remove_level) self.combo_weighting = QtWidgets.QComboBox() self.combo_weighting.addItems(Calibration.KNOWN_WEIGHTING) self.combo_weighting.addItem("Custom") self.combo_weighting.currentTextChanged.connect(self.weightingChanged) label_weighting = QtWidgets.QLabel("Weighting:") self.model = CalibrationPointsTableModel( Calibration(), axes=(1, 0), counts_editable=True, parent=self, ) self.levelsChanged.connect(self.updateButtonRemoveEnabled) self.model.modelReset.connect(self.updateButtonRemoveEnabled) self.combo_weighting.currentTextChanged.connect(self.updateWeighting) self.table = BasicTableView() self.table.setItemDelegate(DoubleSignificantFiguresDelegate(4)) self.table.setSizeAdjustPolicy( QtWidgets.QAbstractScrollArea.AdjustToContents) self.table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) self.table.setMaximumWidth(800) self.table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.table.setModel(self.model) self.table.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.ResizeToContents) layout_buttons = QtWidgets.QHBoxLayout() layout_buttons.addWidget(self.button_remove, 0, QtCore.Qt.AlignLeft) layout_buttons.addWidget(self.button_add, 0, QtCore.Qt.AlignLeft) layout_buttons.addStretch(1) layout_weighting = QtWidgets.QHBoxLayout() layout_weighting.addStretch(1) layout_weighting.addWidget(label_weighting, 0, QtCore.Qt.AlignRight) layout_weighting.addWidget(self.combo_weighting, 0, QtCore.Qt.AlignRight) layout = QtWidgets.QVBoxLayout() layout.addLayout(layout_buttons) layout.addWidget(self.table) layout.addLayout(layout_weighting) self.area.setLayout(layout)
def __init__(self, laser: Laser, options: GraphicsOptions, view: LaserView = None): super().__init__(view) self.laser = laser self.is_srr = isinstance(laser, SRRLaser) self.graphics = LaserGraphicsView(options, parent=self) self.graphics.setMouseTracking(True) self.graphics.cursorValueChanged.connect(self.updateCursorStatus) self.graphics.label.labelChanged.connect(self.renameCurrentElement) self.graphics.colorbar.editRequested.connect(self.actionRequestColorbarEdit) self.combo_layers = QtWidgets.QComboBox() self.combo_layers.addItem("*") self.combo_layers.addItems([str(i) for i in range(0, self.laser.layers)]) self.combo_layers.currentIndexChanged.connect(self.refresh) if not self.is_srr: self.combo_layers.setEnabled(False) self.combo_layers.setVisible(False) self.combo_element = LaserComboBox() self.combo_element.namesSelected.connect(self.updateNames) self.combo_element.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents) self.combo_element.currentIndexChanged.connect(self.refresh) self.populateElements() self.action_calibration = qAction( "go-top", "Ca&libration", "Edit the documents calibration.", self.actionCalibration, ) self.action_config = qAction( "document-edit", "&Config", "Edit the document's config.", self.actionConfig ) self.action_copy_image = qAction( "insert-image", "Copy &Image", "Copy image to clipboard.", self.actionCopyImage, ) self.action_duplicate = qAction( "edit-copy", "Duplicate image", "Open a copy of the image.", self.actionDuplicate, ) self.action_export = qAction( "document-save-as", "E&xport", "Export documents.", self.actionExport ) self.action_export.setShortcut("Ctrl+X") # Add the export action so we can use it via shortcut self.addAction(self.action_export) self.action_information = qAction( "documentinfo", "In&formation", "View and edit image information.", self.actionInformation, ) self.action_save = qAction( "document-save", "&Save", "Save document to numpy archive.", self.actionSave ) self.action_save.setShortcut("Ctrl+S") # Add the save action so we can use it via shortcut self.addAction(self.action_save) self.action_statistics = qAction( "dialog-information", "Statistics", "Open the statisitics dialog.", self.actionStatistics, ) self.action_select_statistics = qAction( "dialog-information", "Selection Statistics", "Open the statisitics dialog for the current selection.", self.actionStatisticsSelection, ) self.action_colocalisation = qAction( "dialog-information", "Colocalisation", "Open the colocalisation dialog.", self.actionColocal, ) self.action_select_colocalisation = qAction( "dialog-information", "Selection Colocalisation", "Open the colocalisation dialog for the current selection.", self.actionColocalSelection, ) # Toolbar actions self.action_select_none = qAction( "transform-move", "Clear Selection", "Clear any selections.", self.graphics.endSelection, ) self.action_widget_none = qAction( "transform-move", "Clear Widgets", "Closes any open widgets.", self.graphics.endWidget, ) self.action_select_rect = qAction( "draw-rectangle", "Rectangle Selector", "Start the rectangle selector tool, use 'Shift' " "to add to selection and 'Control' to subtract.", self.graphics.startRectangleSelection, ) self.action_select_lasso = qAction( "draw-freehand", "Lasso Selector", "Start the lasso selector tool, use 'Shift' " "to add to selection and 'Control' to subtract.", self.graphics.startLassoSelection, ) self.action_select_dialog = qAction( "dialog-information", "Selection Dialog", "Start the selection dialog.", self.actionSelectDialog, ) self.action_select_copy_text = qAction( "insert-table", "Copy Selection as Text", "Copy the current selection to the clipboard as a column of text values.", self.actionCopySelectionText, ) self.action_select_crop = qAction( "transform-crop", "Crop to Selection", "Crop the image to the current selection.", self.actionCropSelection, ) self.selection_button = qToolButton("select", "Selection") self.selection_button.addAction(self.action_select_none) self.selection_button.addAction(self.action_select_rect) self.selection_button.addAction(self.action_select_lasso) self.selection_button.addAction(self.action_select_dialog) self.action_ruler = qAction( "tool-measure", "Measure", "Use a ruler to measure distance.", self.graphics.startRulerWidget, ) self.action_slice = qAction( "tool-measure", "1D Slice", "Select and display a 1-dimensional slice of the image.", self.graphics.startSliceWidget, ) self.widgets_button = qToolButton("tool-measure", "Widgets") self.widgets_button.addAction(self.action_widget_none) self.widgets_button.addAction(self.action_ruler) self.widgets_button.addAction(self.action_slice) self.action_zoom_in = qAction( "zoom-in", "Zoom to Area", "Start zoom area selection.", self.graphics.zoomStart, ) self.action_zoom_out = qAction( "zoom-original", "Reset Zoom", "Reset zoom to full image extent.", self.graphics.zoomReset, ) self.view_button = qToolButton("zoom", "Zoom") self.view_button.addAction(self.action_zoom_in) self.view_button.addAction(self.action_zoom_out) self.graphics.viewport().installEventFilter(DragDropRedirectFilter(self)) # Filters for setting active view self.graphics.viewport().installEventFilter(self) self.combo_element.installEventFilter(self) self.selection_button.installEventFilter(self) self.widgets_button.installEventFilter(self) self.view_button.installEventFilter(self) layout_bar = QtWidgets.QHBoxLayout() layout_bar.addWidget(self.selection_button, 0, QtCore.Qt.AlignLeft) layout_bar.addWidget(self.widgets_button, 0, QtCore.Qt.AlignLeft) layout_bar.addWidget(self.view_button, 0, QtCore.Qt.AlignLeft) layout_bar.addStretch(1) layout_bar.addWidget(self.combo_layers, 0, QtCore.Qt.AlignRight) layout_bar.addWidget(self.combo_element, 0, QtCore.Qt.AlignRight) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.graphics, 1) layout.addLayout(layout_bar) self.setLayout(layout)
def __init__(self, widget: LaserWidget): super().__init__(widget, orientation=QtCore.Qt.Vertical, apply_all=False) self.button_box.removeButton( self.button_box.button(QtWidgets.QDialogButtonBox.Apply) ) self.graphics = MergeGraphicsView(self.viewspace.options, parent=self) self.graphics.setMouseTracking(True) self.list = MergeLaserList() self.list.rowElementChanged.connect(self.redrawRow) self.list.rowAlphaChanged.connect(self.updateRowAlpha) self.list.model().rowsMoved.connect(self.reassignZValues) self.button_add = QtWidgets.QPushButton("Add Laser") self.button_add.clicked.connect(self.addLaserDialog) box_align = QtWidgets.QGroupBox("Align Images") box_align.setLayout(QtWidgets.QVBoxLayout()) self.action_align_auto = qAction( "view-refresh", "FFT Register", "Register all images to the topmost image.", self.alignImagesFFT, ) self.action_align_horz = qAction( "align-vertical-top", "Left to Right", "Layout images in a horizontal line.", self.alignImagesLeftToRight, ) self.action_align_vert = qAction( "align-horizontal-left", "Top to Bottom", "Layout images in a vertical line.", self.alignImagesTopToBottom, ) self.button_align = qToolButton("align-horizontal-left", "Align Images") self.button_align.addAction(self.action_align_auto) self.button_align.addAction(self.action_align_horz) self.button_align.addAction(self.action_align_vert) layout_right = QtWidgets.QVBoxLayout() layout_right.addWidget(self.button_align) layout_right.addStretch(1) layout_right.addWidget(self.button_add) layout_graphics = QtWidgets.QVBoxLayout() layout_graphics.addWidget(self.graphics) layout_controls = QtWidgets.QHBoxLayout() layout_controls.addWidget(self.list, 1) # layout_controls.addWidget(self.button_add, 0) layout_controls.addLayout(layout_right) self.box_graphics.setLayout(layout_graphics) self.box_controls.setLayout(layout_controls) # Add the tool widgets laser, make unclosable self.list.addRow(self.widget.laser, close_button=False) self.refresh()