From 8bd542c1fcc11548d1d0a21da927cb2ef4477e0e Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 6 Jan 2021 15:34:20 +0200 Subject: [PATCH] - for QRCode and Subtraction Tools added also a Beginner/Advanced mode --- CHANGELOG.md | 1 + appTools/ToolFiducials.py | 115 ++++++++++++++++++++++++++++++-------- appTools/ToolQRCode.py | 102 +++++++++++++++++++++++++++------ appTools/ToolSub.py | 106 ++++++++++++++++++++++++++++------- 4 files changed, 267 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56208fb3..bcfa5835 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ CHANGELOG for FlatCAM beta - allowed some more parameters to have negative values (tool diameters especially) - some more tools now have a Beginner/Advanced mode +- for QRCode and Subtraction Tools added also a Beginner/Advanced mode 5.01.2021 diff --git a/appTools/ToolFiducials.py b/appTools/ToolFiducials.py index 02acd98b..e1e7b19c 100644 --- a/appTools/ToolFiducials.py +++ b/appTools/ToolFiducials.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui from appTool import AppTool -from appGUI.GUIElements import FCDoubleSpinner, RadioSet, EvalEntry, FCTable, FCComboBox +from appGUI.GUIElements import FCDoubleSpinner, RadioSet, EvalEntry, FCTable, FCComboBox, FCButton, FCLabel from shapely.geometry import Point, Polygon, MultiPolygon, LineString from shapely.geometry import box as box @@ -79,7 +79,10 @@ class ToolFiducials(AppTool): self.handlers_connected = False - # SIGNALS + # ############################################################################# + # ############################ SIGNALS ######################################## + # ############################################################################# + self.ui.level.toggled.connect(self.on_level_changed) self.ui.add_cfid_button.clicked.connect(self.add_fiducials) self.ui.add_sm_opening_button.clicked.connect(self.add_soldermask_opening) @@ -155,6 +158,55 @@ class ToolFiducials(AppTool): self.copper_obj_set = set() self.sm_obj_set = set() + # Show/Hide Advanced Options + app_mode = self.app.defaults["global_app_level"] + self.change_level(app_mode) + + def change_level(self, level): + """ + + :param level: application level: either 'b' or 'a' + :type level: str + :return: + """ + + if level == 'a': + self.ui.level.setChecked(True) + else: + self.ui.level.setChecked(False) + self.on_level_changed(self.ui.level.isChecked()) + + def on_level_changed(self, checked): + if not checked: + self.ui.level.setText('%s' % _('Beginner')) + self.ui.level.setStyleSheet(""" + QToolButton + { + color: green; + } + """) + + self.ui.separator_line.hide() + self.ui.fid_type_label.hide() + self.ui.fid_type_radio.hide() + self.ui.line_thickness_label.hide() + self.ui.line_thickness_entry.hide() + + else: + self.ui.level.setText('%s' % _('Advanced')) + self.ui.level.setStyleSheet(""" + QToolButton + { + color: red; + } + """) + + self.ui.separator_line.show() + self.ui.fid_type_label.show() + self.ui.fid_type_radio.show() + self.ui.line_thickness_label.show() + self.ui.line_thickness_entry.show() + def on_second_point(self, val): if val == 'no': self.ui.id_item_3.setFlags(QtCore.Qt.NoItemFlags) @@ -699,8 +751,11 @@ class FidoUI: self.decimals = self.app.decimals self.layout = layout + self.title_box = QtWidgets.QHBoxLayout() + self.layout.addLayout(self.title_box) + # ## Title - title_label = QtWidgets.QLabel("%s" % self.toolName) + title_label = FCLabel("%s" % self.toolName) title_label.setStyleSheet(""" QLabel { @@ -708,10 +763,26 @@ class FidoUI: font-weight: bold; } """) - self.layout.addWidget(title_label) - self.layout.addWidget(QtWidgets.QLabel("")) + self.title_box.addWidget(title_label) - self.points_label = QtWidgets.QLabel('%s:' % _('Fiducials Coordinates')) + # App Level label + self.level = QtWidgets.QToolButton() + self.level.setToolTip( + _( + "BASIC is suitable for a beginner. Many parameters\n" + "are hidden from the user in this mode.\n" + "ADVANCED mode will make available all parameters.\n\n" + "To change the application LEVEL, go to:\n" + "Edit -> Preferences -> General and check:\n" + "'APP. LEVEL' radio button." + ) + ) + self.level.setCheckable(True) + self.title_box.addWidget(self.level) + + self.layout.addWidget(FCLabel("")) + + self.points_label = FCLabel('%s:' % _('Fiducials Coordinates')) self.points_label.setToolTip( _("A table with the fiducial points coordinates,\n" "in the format (x, y).") @@ -807,14 +878,14 @@ class FidoUI: grid_lay.setColumnStretch(0, 0) grid_lay.setColumnStretch(1, 1) - self.param_label = QtWidgets.QLabel('%s:' % _('Parameters')) + self.param_label = FCLabel('%s:' % _('Parameters')) self.param_label.setToolTip( _("Parameters used for this tool.") ) grid_lay.addWidget(self.param_label, 0, 0, 1, 2) # DIAMETER # - self.size_label = QtWidgets.QLabel('%s:' % _("Size")) + self.size_label = FCLabel('%s:' % _("Size")) self.size_label.setToolTip( _("This set the fiducial diameter if fiducial type is circular,\n" "otherwise is the size of the fiducial.\n" @@ -830,7 +901,7 @@ class FidoUI: grid_lay.addWidget(self.fid_size_entry, 1, 1) # MARGIN # - self.margin_label = QtWidgets.QLabel('%s:' % _("Margin")) + self.margin_label = FCLabel('%s:' % _("Margin")) self.margin_label.setToolTip( _("Bounding box margin.") ) @@ -847,7 +918,7 @@ class FidoUI: {'label': _('Auto'), 'value': 'auto'}, {"label": _("Manual"), "value": "manual"} ], stretch=False) - self.mode_label = QtWidgets.QLabel(_("Mode:")) + self.mode_label = FCLabel(_("Mode:")) self.mode_label.setToolTip( _("- 'Auto' - automatic placement of fiducials in the corners of the bounding box.\n" "- 'Manual' - manual placement of fiducials.") @@ -861,7 +932,7 @@ class FidoUI: {"label": _("Down"), "value": "down"}, {"label": _("None"), "value": "no"} ], stretch=False) - self.pos_label = QtWidgets.QLabel('%s:' % _("Second fiducial")) + self.pos_label = FCLabel('%s:' % _("Second fiducial")) self.pos_label.setToolTip( _("The position for the second fiducial.\n" "- 'Up' - the order is: bottom-left, top-left, top-right.\n" @@ -871,10 +942,10 @@ class FidoUI: grid_lay.addWidget(self.pos_label, 4, 0) grid_lay.addWidget(self.pos_radio, 4, 1) - separator_line = QtWidgets.QFrame() - separator_line.setFrameShape(QtWidgets.QFrame.HLine) - separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid_lay.addWidget(separator_line, 5, 0, 1, 2) + self.separator_line = QtWidgets.QFrame() + self.separator_line.setFrameShape(QtWidgets.QFrame.HLine) + self.separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(self.separator_line, 5, 0, 1, 2) # Fiducial type # self.fid_type_radio = RadioSet([ @@ -882,7 +953,7 @@ class FidoUI: {"label": _("Cross"), "value": "cross"}, {"label": _("Chess"), "value": "chess"} ], stretch=False) - self.fid_type_label = QtWidgets.QLabel('%s:' % _("Fiducial Type")) + self.fid_type_label = FCLabel('%s:' % _("Fiducial Type")) self.fid_type_label.setToolTip( _("The type of fiducial.\n" "- 'Circular' - this is the regular fiducial.\n" @@ -893,7 +964,7 @@ class FidoUI: grid_lay.addWidget(self.fid_type_radio, 6, 1) # Line Thickness # - self.line_thickness_label = QtWidgets.QLabel('%s:' % _("Line thickness")) + self.line_thickness_label = FCLabel('%s:' % _("Line thickness")) self.line_thickness_label.setToolTip( _("Thickness of the line that makes the fiducial.") ) @@ -917,7 +988,7 @@ class FidoUI: self.grb_object_combo.is_last = True self.grb_object_combo.obj_type = "Gerber" - self.grbobj_label = QtWidgets.QLabel("%s:" % _("GERBER")) + self.grbobj_label = FCLabel("%s:" % _("GERBER")) self.grbobj_label.setToolTip( _("Gerber Object to which will be added a copper thieving.") ) @@ -926,7 +997,7 @@ class FidoUI: grid_lay.addWidget(self.grb_object_combo, 10, 0, 1, 2) # ## Insert Copper Fiducial - self.add_cfid_button = QtWidgets.QPushButton(_("Add Fiducial")) + self.add_cfid_button = FCButton(_("Add Fiducial")) self.add_cfid_button.setIcon(QtGui.QIcon(self.app.resource_location + '/fiducials_32.png')) self.add_cfid_button.setToolTip( _("Will add a polygon on the copper layer to serve as fiducial.") @@ -945,7 +1016,7 @@ class FidoUI: grid_lay.addWidget(separator_line_2, 12, 0, 1, 2) # Soldermask Gerber object # - self.sm_object_label = QtWidgets.QLabel('%s:' % _("Soldermask Gerber")) + self.sm_object_label = FCLabel('%s:' % _("Soldermask Gerber")) self.sm_object_label.setToolTip( _("The Soldermask Gerber object.") ) @@ -959,7 +1030,7 @@ class FidoUI: grid_lay.addWidget(self.sm_object_combo, 14, 0, 1, 2) # ## Insert Soldermask opening for Fiducial - self.add_sm_opening_button = QtWidgets.QPushButton(_("Add Soldermask Opening")) + self.add_sm_opening_button = FCButton(_("Add Soldermask Opening")) self.add_sm_opening_button.setToolTip( _("Will add a polygon on the soldermask layer\n" "to serve as fiducial opening.\n" @@ -977,7 +1048,7 @@ class FidoUI: self.layout.addStretch() # ## Reset Tool - self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) + self.reset_button = FCButton(_("Reset Tool")) self.reset_button.setIcon(QtGui.QIcon(self.app.resource_location + '/reset32.png')) self.reset_button.setToolTip( _("Will reset the tool parameters.") diff --git a/appTools/ToolQRCode.py b/appTools/ToolQRCode.py index cfa83b24..0e1de30a 100644 --- a/appTools/ToolQRCode.py +++ b/appTools/ToolQRCode.py @@ -71,7 +71,10 @@ class QRCode(AppTool): self.old_back_color = '' - # Signals # + # ############################################################################# + # ############################ SIGNALS ######################################## + # ############################################################################# + self.ui.level.toggled.connect(self.on_level_changed) self.ui.qrcode_button.clicked.connect(self.execute) self.ui.export_cb.stateChanged.connect(self.on_export_frame) self.ui.export_png_button.clicked.connect(self.export_png_file) @@ -155,6 +158,49 @@ class QRCode(AppTool): self.ui.back_color_button.setStyleSheet("background-color:%s" % str(self.app.defaults['tools_qrcode_back_color'])[:7]) + # Show/Hide Advanced Options + app_mode = self.app.defaults["global_app_level"] + self.change_level(app_mode) + + def change_level(self, level): + """ + + :param level: application level: either 'b' or 'a' + :type level: str + :return: + """ + + if level == 'a': + self.ui.level.setChecked(True) + else: + self.ui.level.setChecked(False) + self.on_level_changed(self.ui.level.isChecked()) + + def on_level_changed(self, checked): + if not checked: + self.ui.level.setText('%s' % _('Beginner')) + self.ui.level.setStyleSheet(""" + QToolButton + { + color: green; + } + """) + + self.ui.export_cb.hide() + self.ui.export_frame.hide() + else: + self.ui.level.setText('%s' % _('Advanced')) + self.ui.level.setStyleSheet(""" + QToolButton + { + color: red; + } + """) + + self.ui.export_cb.show() + if self.ui.export_cb.get_value(): + self.ui.export_frame.show() + def on_export_frame(self, state): self.ui.export_frame.setVisible(state) self.ui.qrcode_button.setVisible(not state) @@ -657,6 +703,9 @@ class QRcodeUI: self.decimals = self.app.decimals self.layout = layout + self.title_box = QtWidgets.QHBoxLayout() + self.layout.addLayout(self.title_box) + # ## Title title_label = QtWidgets.QLabel("%s" % self.toolName) title_label.setStyleSheet(""" @@ -666,7 +715,23 @@ class QRcodeUI: font-weight: bold; } """) - self.layout.addWidget(title_label) + self.title_box.addWidget(title_label) + + # App Level label + self.level = QtWidgets.QToolButton() + self.level.setToolTip( + _( + "BASIC is suitable for a beginner. Many parameters\n" + "are hidden from the user in this mode.\n" + "ADVANCED mode will make available all parameters.\n\n" + "To change the application LEVEL, go to:\n" + "Edit -> Preferences -> General and check:\n" + "'APP. LEVEL' radio button." + ) + ) + self.level.setCheckable(True) + self.title_box.addWidget(self.level) + self.layout.addWidget(QtWidgets.QLabel('')) # ## Grid Layout @@ -733,8 +798,8 @@ class QRcodeUI: self.version_entry.set_range(1, 40) self.version_entry.setWrapping(True) - grid_lay.addWidget(self.version_label, 1, 0) - grid_lay.addWidget(self.version_entry, 1, 1) + grid_lay.addWidget(self.version_label, 2, 0) + grid_lay.addWidget(self.version_entry, 2, 1) # ERROR CORRECTION # self.error_label = QtWidgets.QLabel('%s:' % _("Error correction")) @@ -756,8 +821,8 @@ class QRcodeUI: "Q = maximum 25%% errors can be corrected\n" "H = maximum 30%% errors can be corrected.") ) - grid_lay.addWidget(self.error_label, 2, 0) - grid_lay.addWidget(self.error_radio, 2, 1) + grid_lay.addWidget(self.error_label, 4, 0) + grid_lay.addWidget(self.error_radio, 4, 1) # BOX SIZE # self.bsize_label = QtWidgets.QLabel('%s:' % _("Box Size")) @@ -769,8 +834,8 @@ class QRcodeUI: self.bsize_entry.set_range(1, 9999) self.bsize_entry.setWrapping(True) - grid_lay.addWidget(self.bsize_label, 3, 0) - grid_lay.addWidget(self.bsize_entry, 3, 1) + grid_lay.addWidget(self.bsize_label, 6, 0) + grid_lay.addWidget(self.bsize_entry, 6, 1) # BORDER SIZE # self.border_size_label = QtWidgets.QLabel('%s:' % _("Border Size")) @@ -782,8 +847,8 @@ class QRcodeUI: self.border_size_entry.set_range(1, 9999) self.border_size_entry.setWrapping(True) - grid_lay.addWidget(self.border_size_label, 4, 0) - grid_lay.addWidget(self.border_size_entry, 4, 1) + grid_lay.addWidget(self.border_size_label, 8, 0) + grid_lay.addWidget(self.border_size_entry, 8, 1) # POLARITY CHOICE # self.pol_label = QtWidgets.QLabel('%s:' % _("Polarity")) @@ -800,8 +865,8 @@ class QRcodeUI: "be added as positive. If it is added to a Copper Gerber\n" "file then perhaps the QRCode can be added as negative.") ) - grid_lay.addWidget(self.pol_label, 7, 0) - grid_lay.addWidget(self.pol_radio, 7, 1) + grid_lay.addWidget(self.pol_label, 10, 0) + grid_lay.addWidget(self.pol_radio, 10, 1) # BOUNDING BOX TYPE # self.bb_label = QtWidgets.QLabel('%s:' % _("Bounding Box")) @@ -815,8 +880,13 @@ class QRcodeUI: _("The bounding box, meaning the empty space that surrounds\n" "the QRCode geometry, can have a rounded or a square shape.") ) - grid_lay.addWidget(self.bb_label, 8, 0) - grid_lay.addWidget(self.bb_radio, 8, 1) + grid_lay.addWidget(self.bb_label, 12, 0) + grid_lay.addWidget(self.bb_radio, 12, 1) + + self.separator_line_2 = QtWidgets.QFrame() + self.separator_line_2.setFrameShape(QtWidgets.QFrame.HLine) + self.separator_line_2.setFrameShadow(QtWidgets.QFrame.Sunken) + grid_lay.addWidget(self.separator_line_2, 14, 0, 1, 2) # Export QRCode self.export_cb = FCCheckBox(_("Export QRCode")) @@ -824,7 +894,7 @@ class QRcodeUI: _("Show a set of controls allowing to export the QRCode\n" "to a SVG file or an PNG file.") ) - grid_lay.addWidget(self.export_cb, 9, 0, 1, 2) + grid_lay.addWidget(self.export_cb, 16, 0, 1, 2) # this way I can hide/show the frame self.export_frame = QtWidgets.QFrame() @@ -924,7 +994,7 @@ class QRcodeUI: """) self.layout.addWidget(self.qrcode_button) - self.layout.addStretch() + self.layout.addStretch(1) # ## Reset Tool self.reset_button = QtWidgets.QPushButton(_("Reset Tool")) diff --git a/appTools/ToolSub.py b/appTools/ToolSub.py index 2670c878..c4c2670f 100644 --- a/appTools/ToolSub.py +++ b/appTools/ToolSub.py @@ -8,7 +8,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui from appTool import AppTool -from appGUI.GUIElements import FCCheckBox, FCButton, FCComboBox +from appGUI.GUIElements import FCCheckBox, FCButton, FCComboBox, FCLabel from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString from shapely.ops import unary_union @@ -86,7 +86,10 @@ class ToolSub(AppTool): self.pool = self.app.pool self.results = [] - # Signals + # ############################################################################# + # ############################ SIGNALS ######################################## + # ############################################################################# + self.ui.level.toggled.connect(self.on_level_changed) self.ui.intersect_btn.clicked.connect(self.on_subtract_gerber_click) self.ui.intersect_geo_btn.clicked.connect(self.on_subtract_geo_click) self.ui.reset_button.clicked.connect(self.set_tool_ui) @@ -186,6 +189,50 @@ class ToolSub(AppTool): self.ui.close_paths_cb.setChecked(self.app.defaults["tools_sub_close_paths"]) self.ui.delete_sources_cb.setChecked(self.app.defaults["tools_sub_delete_sources"]) + # Show/Hide Advanced Options + app_mode = self.app.defaults["global_app_level"] + self.change_level(app_mode) + + def change_level(self, level): + """ + + :param level: application level: either 'b' or 'a' + :type level: str + :return: + """ + + if level == 'a': + self.ui.level.setChecked(True) + else: + self.ui.level.setChecked(False) + self.on_level_changed(self.ui.level.isChecked()) + + def on_level_changed(self, checked): + if not checked: + self.ui.level.setText('%s' % _('Beginner')) + self.ui.level.setStyleSheet(""" + QToolButton + { + color: green; + } + """) + + self.ui.delete_sources_cb.hide() + self.ui.separator_line.hide() + self.ui.extra_empty_label.hide() + else: + self.ui.level.setText('%s' % _('Advanced')) + self.ui.level.setStyleSheet(""" + QToolButton + { + color: red; + } + """) + + self.ui.delete_sources_cb.show() + self.ui.separator_line.show() + self.ui.extra_empty_label.show() + def on_subtract_gerber_click(self): # reset previous values self.new_apertures.clear() @@ -703,8 +750,11 @@ class SubUI: self.decimals = self.app.decimals self.layout = layout + self.title_box = QtWidgets.QHBoxLayout() + self.layout.addLayout(self.title_box) + # ## Title - title_label = QtWidgets.QLabel("%s" % self.toolName) + title_label = FCLabel("%s" % self.toolName) title_label.setStyleSheet(""" QLabel { @@ -712,8 +762,24 @@ class SubUI: font-weight: bold; } """) - self.layout.addWidget(title_label) - self.layout.addWidget(QtWidgets.QLabel("")) + self.title_box.addWidget(title_label) + + # App Level label + self.level = QtWidgets.QToolButton() + self.level.setToolTip( + _( + "BASIC is suitable for a beginner. Many parameters\n" + "are hidden from the user in this mode.\n" + "ADVANCED mode will make available all parameters.\n\n" + "To change the application LEVEL, go to:\n" + "Edit -> Preferences -> General and check:\n" + "'APP. LEVEL' radio button." + ) + ) + self.level.setCheckable(True) + self.title_box.addWidget(self.level) + + self.layout.addWidget(FCLabel("")) self.tools_frame = QtWidgets.QFrame() self.tools_frame.setContentsMargins(0, 0, 0, 0) @@ -735,14 +801,15 @@ class SubUI: ) grid0.addWidget(self.delete_sources_cb, 0, 0, 1, 2) - separator_line = QtWidgets.QFrame() - separator_line.setFrameShape(QtWidgets.QFrame.HLine) - separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - grid0.addWidget(separator_line, 2, 0, 1, 3) + self.separator_line = QtWidgets.QFrame() + self.separator_line.setFrameShape(QtWidgets.QFrame.HLine) + self.separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid0.addWidget(self.separator_line, 2, 0, 1, 3) - grid0.addWidget(QtWidgets.QLabel(''), 4, 0, 1, 2) + self.extra_empty_label = FCLabel('') + grid0.addWidget(self.extra_empty_label, 4, 0, 1, 2) - self.gerber_title = QtWidgets.QLabel("%s" % _("GERBER")) + self.gerber_title = FCLabel("%s" % _("GERBER")) grid0.addWidget(self.gerber_title, 6, 0, 1, 2) # Target Gerber Object @@ -753,7 +820,7 @@ class SubUI: self.target_gerber_combo.is_last = True self.target_gerber_combo.obj_type = "Gerber" - self.target_gerber_label = QtWidgets.QLabel('%s:' % _("Target")) + self.target_gerber_label = FCLabel('%s:' % _("Target")) self.target_gerber_label.setToolTip( _("Gerber object from which to subtract\n" "the subtractor Gerber object.") @@ -769,7 +836,7 @@ class SubUI: self.sub_gerber_combo.is_last = True self.sub_gerber_combo.obj_type = "Gerber" - self.sub_gerber_label = QtWidgets.QLabel('%s:' % _("Subtractor")) + self.sub_gerber_label = FCLabel('%s:' % _("Subtractor")) self.sub_gerber_label.setToolTip( _("Gerber object that will be subtracted\n" "from the target Gerber object.") @@ -793,9 +860,9 @@ class SubUI: } """) grid0.addWidget(self.intersect_btn, 12, 0, 1, 2) - grid0.addWidget(QtWidgets.QLabel(''), 14, 0, 1, 2) + grid0.addWidget(FCLabel(''), 14, 0, 1, 2) - self.geo_title = QtWidgets.QLabel("%s" % _("GEOMETRY")) + self.geo_title = FCLabel("%s" % _("GEOMETRY")) grid0.addWidget(self.geo_title, 16, 0, 1, 2) # Target Geometry Object @@ -806,7 +873,7 @@ class SubUI: self.target_geo_combo.is_last = True self.target_geo_combo.obj_type = "Geometry" - self.target_geo_label = QtWidgets.QLabel('%s:' % _("Target")) + self.target_geo_label = FCLabel('%s:' % _("Target")) self.target_geo_label.setToolTip( _("Geometry object from which to subtract\n" "the subtractor Geometry object.") @@ -822,7 +889,7 @@ class SubUI: self.sub_geo_combo.is_last = True self.sub_geo_combo.obj_type = "Geometry" - self.sub_geo_label = QtWidgets.QLabel('%s:' % _("Subtractor")) + self.sub_geo_label = FCLabel('%s:' % _("Subtractor")) self.sub_geo_label.setToolTip( _("Geometry object that will be subtracted\n" "from the target Geometry object.") @@ -850,9 +917,10 @@ class SubUI: """) grid0.addWidget(self.intersect_geo_btn, 24, 0, 1, 2) - grid0.addWidget(QtWidgets.QLabel(''), 26, 0, 1, 2) - self.tools_box.addStretch() + grid0.addWidget(FCLabel(''), 26, 0, 1, 2) + + self.tools_box.addStretch(1) # ## Reset Tool self.reset_button = QtWidgets.QPushButton(_("Reset Tool"))