- a series of PEP8 corrections in the FlatCAMGeometry.py

- in Geometry UI finished a very basic way for the Polish feature (this will be upgraded in the future, for now is very rough)
- added some new GUI elements by subclassing some widgets for the dialog pop-ups
- in NCC Tool and Isolation Tool, pressing the shortcut key 'T' will bring the add new tool pop up in which now it is included the button to get the optimal diameter
- in Geometry UI and for Solderpaste Tool replaced the pop up window that is launched when using shortcut key with one that has the context menu translated
- some UI cleanup in the Geometry UI
This commit is contained in:
Marius Stanciu 2020-10-28 03:18:56 +02:00 committed by Marius
parent 77101be8fd
commit 51afa60e4a
11 changed files with 568 additions and 119 deletions

View File

@ -7,6 +7,15 @@ CHANGELOG for FlatCAM beta
=================================================
28.10.2020
- a series of PEP8 corrections in the FlatCAMGeometry.py
- in Geometry UI finished a very basic way for the Polish feature (this will be upgraded in the future, for now is very rough)
- added some new GUI elements by subclassing some widgets for the dialog pop-ups
- in NCC Tool and Isolation Tool, pressing the shortcut key 'T' will bring the add new tool pop up in which now it is included the button to get the optimal diameter
- in Geometry UI and for Solderpaste Tool replaced the pop up window that is launched when using shortcut key with one that has the context menu translated
- some UI cleanup in the Geometry UI
27.10.2020
- created custom classes derived from TextEdit and from LineEdit where I overloaded the context menu and I made all the other classes that were inheriting from them to inherit from those new classes

View File

@ -1224,6 +1224,55 @@ class FCSliderWithDoubleSpinner(QtWidgets.QFrame):
self.spinner.set_value(slider_value)
class FCButtonWithDoubleSpinner(QtWidgets.QFrame):
def __init__(self, min=0, max=100, step=1, decimals=4, button_text='', button_icon=None, callback=None, **kwargs):
super().__init__(**kwargs)
self.button = QtWidgets.QToolButton()
if button_text != '':
self.button.setText(button_text)
if button_icon:
self.button.setIcon(button_icon)
self.spinner = FCDoubleSpinner()
self.spinner.set_range(min, max)
self.spinner.set_step(step)
self.spinner.set_precision(decimals)
self.spinner.setMinimumWidth(70)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
self.spinner.setSizePolicy(sizePolicy)
self.layout = QtWidgets.QHBoxLayout()
self.layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.layout.setContentsMargins(0, 0, 0, 0)
self.layout.addWidget(self.spinner)
self.layout.addWidget(self.button)
self.setLayout(self.layout)
self.valueChanged = self.spinner.valueChanged
self._callback = callback
self.button.clicked.connect(self._callback)
def get_value(self) -> float:
return self.spinner.get_value()
def set_value(self, value: float):
self.spinner.set_value(value)
def set_callback(self, callback):
self._callback = callback
def set_text(self, txt: str):
if txt:
self.button.setText(txt)
def set_icon(self, icon: QtGui.QIcon):
self.button.setIcon(icon)
class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
returnPressed = QtCore.pyqtSignal()
confirmation_signal = QtCore.pyqtSignal(bool, float, float)
@ -2112,6 +2161,7 @@ class FCInputDialog(QtWidgets.QInputDialog):
def __init__(self, parent=None, ok=False, val=None, title=None, text=None, min=None, max=None, decimals=None,
init_val=None):
super(FCInputDialog, self).__init__(parent)
self.allow_empty = ok
self.empty_val = val
@ -2151,6 +2201,70 @@ class FCInputDialog(QtWidgets.QInputDialog):
pass
class FCInputSpinner(QtWidgets.QDialog):
def __init__(self, parent=None, title=None, text=None, min=None, max=None, decimals=4, step=1, init_val=None):
super().__init__(parent)
self.val = 0.0
self.ok = ''
self.init_value = init_val if init_val else 0.0
self.setWindowTitle(title) if title else self.setWindowTitle('title')
self.text = text if text else 'text'
self.min = min if min else 0
self.max = max if max else 255
self.step = step if step else 1
self.lbl = FCLabel(self.text)
self.wdg = FCDoubleSpinner()
self.wdg.set_value(self.init_value)
self.wdg.set_range(self.min, self.max)
self.wdg.set_step(self.step)
self.wdg.set_precision(decimals)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
self.wdg.setSizePolicy(sizePolicy)
QBtn = QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel
self.buttonBox = QtWidgets.QDialogButtonBox(QBtn)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.lbl)
self.layout.addWidget(self.wdg)
self.layout.addWidget(self.buttonBox)
self.setLayout(self.layout)
def set_title(self, txt):
self.setWindowTitle(txt)
def set_text(self, txt):
self.lbl.set_value(txt)
def set_min(self, val):
self.wdg.spinner.setMinimum(val)
def set_max(self, val):
self.wdg.spinner.setMaximum(val)
def set_range(self, min, max):
self.wdg.spinner.set_range(min, max)
def set_step(self, val):
self.wdg.spinner.set_step(val)
def get_value(self):
if self.exec_() == QtWidgets.QDialog.Accepted:
return [self.wdg.get_value(), True]
else:
return [None, False]
class FCInputDialogSlider(QtWidgets.QDialog):
def __init__(self, parent=None, title=None, text=None, min=None, max=None, step=1, init_val=None):
@ -2209,6 +2323,70 @@ class FCInputDialogSlider(QtWidgets.QDialog):
return None, False
class FCInputDialogSpinnerButton(QtWidgets.QDialog):
def __init__(self, parent=None, title=None, text=None, min=None, max=None, step=1, decimals=4, init_val=None,
button_text='', button_icon=None, callback=None):
super().__init__(parent)
self.val = 0.0
self.init_value = init_val if init_val else 0.0
self.setWindowTitle(title) if title else self.setWindowTitle('title')
self.text = text if text else 'text'
self.min = min if min else 0
self.max = max if max else 255
self.step = step if step else 1
self.decimals = decimals if decimals else 4
self.lbl = FCLabel(self.text)
self.wdg = FCButtonWithDoubleSpinner(min=self.min, max=self.max, step=self.step, decimals=decimals,
button_text=button_text, button_icon=button_icon, callback=callback)
self.wdg.set_value(self.init_value)
QBtn = QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel
self.buttonBox = QtWidgets.QDialogButtonBox(QBtn)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.lbl)
self.layout.addWidget(self.wdg)
self.layout.addWidget(self.buttonBox)
self.setLayout(self.layout)
def set_title(self, txt):
self.setWindowTitle(txt)
def set_text(self, txt):
self.lbl.set_value(txt)
def set_min(self, val):
self.wdg.spinner.setMinimum(val)
def set_max(self, val):
self.wdg.spinner.setMaximum(val)
def set_range(self, min, max):
self.wdg.spinner.set_range(min, max)
def set_step(self, val):
self.wdg.spinner.set_step(val)
def set_value(self, val):
self.wdg.spinner.set_value(val)
def get_results(self):
if self.exec_() == QtWidgets.QDialog.Accepted:
return self.wdg.get_value(), True
else:
return None, False
class FCButton(QtWidgets.QPushButton):
def __init__(self, text=None, checkable=None, click_callback=None, parent=None):
super(FCButton, self).__init__(text, parent)

View File

@ -1122,13 +1122,6 @@ class GeometryObjectUI(ObjectUI):
grid2 = QtWidgets.QGridLayout()
self.geo_table_box.addLayout(grid2)
self.copytool_btn = QtWidgets.QPushButton(_('Copy'))
self.copytool_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/copy16.png'))
self.copytool_btn.setToolTip(
_("Copy a selection of tools in the Tool Table\n"
"by first selecting a row in the Tool Table.")
)
self.deltool_btn = QtWidgets.QPushButton(_('Delete'))
self.deltool_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/trash16.png'))
self.deltool_btn.setToolTip(
@ -1136,15 +1129,11 @@ class GeometryObjectUI(ObjectUI):
"by first selecting a row in the Tool Table.")
)
grid2.addWidget(self.copytool_btn, 0, 0)
grid2.addWidget(self.deltool_btn, 0, 1)
self.geo_table_box.addWidget(QtWidgets.QLabel(''))
grid2.addWidget(self.deltool_btn, 0, 0, 1, 2)
# ###########################################################
# ############# Create CNC Job ##############################
# ###########################################################
self.geo_param_frame = QtWidgets.QFrame()
self.geo_param_frame.setContentsMargins(0, 0, 0, 0)
self.geo_tools_box.addWidget(self.geo_param_frame)
@ -1659,6 +1648,21 @@ class GeometryObjectUI(ObjectUI):
self.grid4.addWidget(self.polish_dia_lbl, 16, 0)
self.grid4.addWidget(self.polish_dia_entry, 16, 1)
# Polish Travel Z
self.polish_travelz_lbl = QtWidgets.QLabel('%s:' % _('Travel Z'))
self.polish_travelz_lbl.setToolTip(
_("Height of the tool when\n"
"moving without cutting.")
)
self.polish_travelz_entry = FCDoubleSpinner(callback=self.confirmation_message)
self.polish_travelz_entry.set_precision(self.decimals)
self.polish_travelz_entry.set_range(0.00000, 10000.00000)
self.polish_travelz_entry.setSingleStep(0.1)
self.polish_travelz_entry.setObjectName("g_polish_travelz")
self.grid4.addWidget(self.polish_travelz_lbl, 17, 0)
self.grid4.addWidget(self.polish_travelz_entry, 17, 1)
# Polish Pressure
self.polish_pressure_lbl = QtWidgets.QLabel('%s:' % _('Pressure'))
self.polish_pressure_lbl.setToolTip(
@ -1670,8 +1674,21 @@ class GeometryObjectUI(ObjectUI):
self.polish_pressure_entry.set_range(-9999.9999, 9999.9999)
self.polish_pressure_entry.setObjectName("g_polish_pressure")
self.grid4.addWidget(self.polish_pressure_lbl, 17, 0)
self.grid4.addWidget(self.polish_pressure_entry, 17, 1)
self.grid4.addWidget(self.polish_pressure_lbl, 18, 0)
self.grid4.addWidget(self.polish_pressure_entry, 18, 1)
# Polish Margin
self.polish_margin_lbl = FCLabel('%s:' % _('Margin'))
self.polish_margin_lbl.setToolTip(
_("Bounding box margin.")
)
self.polish_margin_entry = FCDoubleSpinner(callback=self.confirmation_message)
self.polish_margin_entry.set_precision(self.decimals)
self.polish_margin_entry.set_range(-9999.9999, 9999.9999)
self.polish_margin_entry.setObjectName("g_polish_margin")
self.grid4.addWidget(self.polish_margin_lbl, 20, 0)
self.grid4.addWidget(self.polish_margin_entry, 20, 1)
# Polish Overlap
self.polish_over_lbl = QtWidgets.QLabel('%s:' % _('Overlap'))
@ -1685,8 +1702,8 @@ class GeometryObjectUI(ObjectUI):
self.polish_over_entry.setSingleStep(0.1)
self.polish_over_entry.setObjectName("g_polish_overlap")
self.grid4.addWidget(self.polish_over_lbl, 18, 0)
self.grid4.addWidget(self.polish_over_entry, 18, 1)
self.grid4.addWidget(self.polish_over_lbl, 22, 0)
self.grid4.addWidget(self.polish_over_entry, 22, 1)
# Polish Method
self.polish_method_lbl = QtWidgets.QLabel('%s:' % _('Method'))
@ -1703,13 +1720,17 @@ class GeometryObjectUI(ObjectUI):
)
self.polish_method_combo.setObjectName('g_polish_method')
self.grid4.addWidget(self.polish_method_lbl, 20, 0)
self.grid4.addWidget(self.polish_method_combo, 20, 1)
self.grid4.addWidget(self.polish_method_lbl, 24, 0)
self.grid4.addWidget(self.polish_method_combo, 24, 1)
self.polish_dia_lbl.hide()
self.polish_dia_entry.hide()
self.polish_pressure_lbl.hide()
self.polish_pressure_entry.hide()
self.polish_travelz_lbl.hide()
self.polish_travelz_entry.hide()
self.polish_margin_lbl.hide()
self.polish_margin_entry.hide()
self.polish_over_lbl.hide()
self.polish_over_entry.hide()
self.polish_method_lbl.hide()
@ -1722,6 +1743,10 @@ class GeometryObjectUI(ObjectUI):
self.polish_dia_entry,
self.polish_pressure_lbl,
self.polish_pressure_entry,
self.polish_travelz_lbl,
self.polish_travelz_entry,
self.polish_margin_lbl,
self.polish_margin_entry,
self.polish_over_lbl,
self.polish_over_entry,
self.polish_method_lbl,
@ -1732,7 +1757,7 @@ class GeometryObjectUI(ObjectUI):
separator_line2 = QtWidgets.QFrame()
separator_line2.setFrameShape(QtWidgets.QFrame.HLine)
separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.grid4.addWidget(separator_line2, 22, 0, 1, 2)
self.grid4.addWidget(separator_line2, 26, 0, 1, 2)
# Button
self.generate_cnc_button = QtWidgets.QPushButton(_('Generate CNCJob object'))
@ -1750,9 +1775,9 @@ class GeometryObjectUI(ObjectUI):
font-weight: bold;
}
""")
self.grid4.addWidget(self.generate_cnc_button, 24, 0, 1, 2)
self.grid4.addWidget(self.generate_cnc_button, 28, 0, 1, 2)
self.grid4.addWidget(QtWidgets.QLabel(''), 26, 0, 1, 2)
self.grid4.addWidget(QtWidgets.QLabel(''), 30, 0, 1, 2)
# ##############
# Paint area ##
@ -1761,7 +1786,7 @@ class GeometryObjectUI(ObjectUI):
self.tools_label.setToolTip(
_("Launch Paint Tool in Tools Tab.")
)
self.grid4.addWidget(self.tools_label, 28, 0, 1, 2)
self.grid4.addWidget(self.tools_label, 32, 0, 1, 2)
# Milling Tool - will create GCode for slot holes
self.milling_button = QtWidgets.QPushButton(_('Milling Tool'))
@ -1775,7 +1800,7 @@ class GeometryObjectUI(ObjectUI):
font-weight: bold;
}
""")
self.grid4.addWidget(self.milling_button, 30, 0, 1, 2)
self.grid4.addWidget(self.milling_button, 34, 0, 1, 2)
# FIXME: until the Milling Tool is ready, this get disabled
self.milling_button.setDisabled(True)
@ -1793,7 +1818,7 @@ class GeometryObjectUI(ObjectUI):
# font-weight: bold;
# }
# """)
self.grid4.addWidget(self.paint_tool_button, 32, 0, 1, 2)
self.grid4.addWidget(self.paint_tool_button, 36, 0, 1, 2)
# NCC Tool
self.generate_ncc_button = QtWidgets.QPushButton(_('NCC Tool'))
@ -1808,7 +1833,7 @@ class GeometryObjectUI(ObjectUI):
# font-weight: bold;
# }
# """)
self.grid4.addWidget(self.generate_ncc_button, 34, 0, 1, 2)
self.grid4.addWidget(self.generate_ncc_button, 38, 0, 1, 2)
class CNCObjectUI(ObjectUI):

View File

@ -282,6 +282,14 @@ class PreferencesUIManager:
"geometry_area_shape": self.ui.geometry_defaults_form.geometry_adv_opt_group.area_shape_radio,
"geometry_area_strategy": self.ui.geometry_defaults_form.geometry_adv_opt_group.strategy_radio,
"geometry_area_overz": self.ui.geometry_defaults_form.geometry_adv_opt_group.over_z_entry,
# Polish
"geometry_polish": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_cb,
"geometry_polish_dia": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_dia_entry,
"geometry_polish_pressure": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_pressure_entry,
"geometry_polish_travelz": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_travelz_entry,
"geometry_polish_margin": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_margin_entry,
"geometry_polish_overlap": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_over_entry,
"geometry_polish_method": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_method_combo,
# Geometry Editor
"geometry_editor_sel_limit": self.ui.geometry_defaults_form.geometry_editor_group.sel_limit_entry,

View File

@ -2,7 +2,7 @@ from PyQt5 import QtWidgets
from PyQt5.QtCore import QSettings
from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCLabel, NumericalEvalTupleEntry, \
NumericalEvalEntry
NumericalEvalEntry, FCComboBox
from appGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
@ -31,7 +31,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
# ------------------------------
# ## Advanced Options
# ------------------------------
self.geo_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
self.geo_label = FCLabel('<b>%s:</b>' % _('Advanced Options'))
self.geo_label.setToolTip(
_("A list of Geometry advanced parameters.\n"
"Those parameters are available only for\n"
@ -43,7 +43,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
self.layout.addLayout(grid1)
# Toolchange X,Y
toolchange_xy_label = QtWidgets.QLabel('%s:' % _('Toolchange X-Y'))
toolchange_xy_label = FCLabel('%s:' % _('Toolchange X-Y'))
toolchange_xy_label.setToolTip(
_("Toolchange X,Y position.")
)
@ -53,7 +53,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(self.toolchangexy_entry, 1, 1)
# Start move Z
startzlabel = QtWidgets.QLabel('%s:' % _('Start Z'))
startzlabel = FCLabel('%s:' % _('Start Z'))
startzlabel.setToolTip(
_("Height of the tool just after starting the work.\n"
"Delete the value if you don't need this feature.")
@ -64,7 +64,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(self.gstartz_entry, 2, 1)
# Feedrate rapids
fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feedrate Rapids'))
fr_rapid_label = FCLabel('%s:' % _('Feedrate Rapids'))
fr_rapid_label.setToolTip(
_("Cutting speed in the XY plane\n"
"(in units per minute).\n"
@ -105,7 +105,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(self.e_cut_entry, 5, 1)
# Probe depth
self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth"))
self.pdepth_label = FCLabel('%s:' % _("Probe Z depth"))
self.pdepth_label.setToolTip(
_("The maximum depth that the probe is allowed\n"
"to probe. Negative value, in current units.")
@ -120,7 +120,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(self.pdepth_entry, 6, 1)
# Probe feedrate
self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe"))
self.feedrate_probe_label = FCLabel('%s:' % _("Feedrate Probe"))
self.feedrate_probe_label.setToolTip(
_("The feedrate used while the probe is probing.")
)
@ -134,7 +134,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(self.feedrate_probe_entry, 7, 1)
# Spindle direction
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle direction'))
spindle_dir_label = FCLabel('%s:' % _('Spindle direction'))
spindle_dir_label.setToolTip(
_("This sets the direction that the spindle is rotating.\n"
"It can be either:\n"
@ -158,7 +158,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(self.fplunge_cb, 9, 0, 1, 2)
# Size of trace segment on X axis
segx_label = QtWidgets.QLabel('%s:' % _("Segment X size"))
segx_label = FCLabel('%s:' % _("Segment X size"))
segx_label.setToolTip(
_("The size of the trace segment on the X axis.\n"
"Useful for auto-leveling.\n"
@ -174,7 +174,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(self.segx_entry, 10, 1)
# Size of trace segment on Y axis
segy_label = QtWidgets.QLabel('%s:' % _("Segment Y size"))
segy_label = FCLabel('%s:' % _("Segment Y size"))
segy_label.setToolTip(
_("The size of the trace segment on the Y axis.\n"
"Useful for auto-leveling.\n"
@ -197,7 +197,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
# -----------------------------
# --- Area Exclusion ----------
# -----------------------------
self.area_exc_label = QtWidgets.QLabel('<b>%s:</b>' % _('Area Exclusion'))
self.area_exc_label = FCLabel('<b>%s:</b>' % _('Area Exclusion'))
self.area_exc_label.setToolTip(
_("Area exclusion parameters.")
)
@ -215,7 +215,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(self.exclusion_cb, 14, 0, 1, 2)
# Area Selection shape
self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape"))
self.area_shape_label = FCLabel('%s:' % _("Shape"))
self.area_shape_label.setToolTip(
_("The kind of selection shape used for area selection.")
)
@ -248,5 +248,102 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
grid1.addWidget(self.over_z_label, 18, 0)
grid1.addWidget(self.over_z_entry, 18, 1)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid1.addWidget(separator_line, 20, 0, 1, 2)
# -----------------------------
# --- Area POLISH ----------
# -----------------------------
# Add Polish
self.polish_cb = FCCheckBox(label=_('Add Polish'))
self.polish_cb.setToolTip(_(
"Will add a Paint section at the end of the GCode.\n"
"A metallic brush will clean the material after milling."))
grid1.addWidget(self.polish_cb, 22, 0, 1, 2)
# Polish Tool Diameter
self.polish_dia_lbl = FCLabel('%s:' % _('Tool Dia'))
self.polish_dia_lbl.setToolTip(
_("Diameter for the polishing tool.")
)
self.polish_dia_entry = FCDoubleSpinner()
self.polish_dia_entry.set_precision(self.decimals)
self.polish_dia_entry.set_range(0.000, 9999.9999)
grid1.addWidget(self.polish_dia_lbl, 24, 0)
grid1.addWidget(self.polish_dia_entry, 24, 1)
# Polish Travel Z
self.polish_travelz_lbl = FCLabel('%s:' % _('Travel Z'))
self.polish_travelz_lbl.setToolTip(
_("Height of the tool when\n"
"moving without cutting.")
)
self.polish_travelz_entry = FCDoubleSpinner()
self.polish_travelz_entry.set_precision(self.decimals)
self.polish_travelz_entry.set_range(0.00000, 10000.00000)
self.polish_travelz_entry.setSingleStep(0.1)
grid1.addWidget(self.polish_travelz_lbl, 26, 0)
grid1.addWidget(self.polish_travelz_entry, 26, 1)
# Polish Pressure
self.polish_pressure_lbl = FCLabel('%s:' % _('Pressure'))
self.polish_pressure_lbl.setToolTip(
_("Negative value. The higher the absolute value\n"
"the stronger the pressure of the brush on the material.")
)
self.polish_pressure_entry = FCDoubleSpinner()
self.polish_pressure_entry.set_precision(self.decimals)
self.polish_pressure_entry.set_range(-9999.9999, 9999.9999)
grid1.addWidget(self.polish_pressure_lbl, 28, 0)
grid1.addWidget(self.polish_pressure_entry, 28, 1)
# Polish Margin
self.polish_margin_lbl = FCLabel('%s:' % _('Margin'))
self.polish_margin_lbl.setToolTip(
_("Bounding box margin.")
)
self.polish_margin_entry = FCDoubleSpinner()
self.polish_margin_entry.set_precision(self.decimals)
self.polish_margin_entry.set_range(-9999.9999, 9999.9999)
grid1.addWidget(self.polish_margin_lbl, 30, 0)
grid1.addWidget(self.polish_margin_entry, 30, 1)
# Polish Overlap
self.polish_over_lbl = FCLabel('%s:' % _('Overlap'))
self.polish_over_lbl.setToolTip(
_("How much (percentage) of the tool width to overlap each tool pass.")
)
self.polish_over_entry = FCDoubleSpinner(suffix='%')
self.polish_over_entry.set_precision(self.decimals)
self.polish_over_entry.setWrapping(True)
self.polish_over_entry.set_range(0.0000, 99.9999)
self.polish_over_entry.setSingleStep(0.1)
grid1.addWidget(self.polish_over_lbl, 32, 0)
grid1.addWidget(self.polish_over_entry, 32, 1)
# Polish Method
self.polish_method_lbl = FCLabel('%s:' % _('Method'))
self.polish_method_lbl.setToolTip(
_("Algorithm for polishing:\n"
"- Standard: Fixed step inwards.\n"
"- Seed-based: Outwards from seed.\n"
"- Line-based: Parallel lines.")
)
self.polish_method_combo = FCComboBox()
self.polish_method_combo.addItems(
[_("Standard"), _("Seed"), _("Lines")]
)
grid1.addWidget(self.polish_method_lbl, 34, 0)
grid1.addWidget(self.polish_method_combo, 34, 1)
self.layout.addStretch()

View File

@ -10,10 +10,10 @@
# File modified by: Marius Stanciu #
# ##########################################################
from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString, LinearRing
from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString, LinearRing, box
import shapely.affinity as affinity
from camlib import Geometry
from camlib import Geometry, grace
from appObjects.FlatCAMObj import *
@ -41,6 +41,7 @@ class GeometryObject(FlatCAMObj, Geometry):
"""
optionChanged = QtCore.pyqtSignal(str)
builduiSig = QtCore.pyqtSignal()
launch_job = QtCore.pyqtSignal()
ui_type = GeometryObjectUI
@ -442,6 +443,8 @@ class GeometryObject(FlatCAMObj, Geometry):
"polish": self.ui.polish_cb,
"polish_dia": self.ui.polish_dia_entry,
"polish_pressure": self.ui.polish_pressure_entry,
"polish_travelz": self.ui.polish_travelz_entry,
"polish_margin": self.ui.polish_margin_entry,
"polish_overlap": self.ui.polish_over_entry,
"polish_method": self.ui.polish_method_combo,
})
@ -514,7 +517,7 @@ class GeometryObject(FlatCAMObj, Geometry):
new_data = deepcopy(self.default_data)
self.tools.update({
self.tooluid: {
'tooldia': float('%.*f' % (self.decimals, float(toold))),
'tooldia': self.app.dec_format(float(toold), self.decimals),
'offset': 'Path',
'offset_value': 0.0,
'type': _('Rough'),
@ -552,14 +555,14 @@ class GeometryObject(FlatCAMObj, Geometry):
self.ui.geo_tools_table.setupContextMenu()
self.ui.geo_tools_table.addContextMenu(
_("Add from Tool DB"), self.on_tool_add_from_db_clicked,
_("Pick from DB"), self.on_tool_add_from_db_clicked,
icon=QtGui.QIcon(self.app.resource_location + "/plus16.png"))
self.ui.geo_tools_table.addContextMenu(
_("Copy"), self.on_tool_copy,
icon=QtGui.QIcon(self.app.resource_location + "/copy16.png"))
self.ui.geo_tools_table.addContextMenu(
_("Delete"), lambda: self.on_tool_delete(all_tools=None),
icon=QtGui.QIcon(self.app.resource_location + "/delete32.png"))
icon=QtGui.QIcon(self.app.resource_location + "/trash16.png"))
# Show/Hide Advanced Options
if self.app.defaults["global_app_level"] == 'b':
@ -625,6 +628,8 @@ class GeometryObject(FlatCAMObj, Geometry):
self.ui.geo_tools_table.drag_drop_sig.connect(self.rebuild_ui)
self.launch_job.connect(self.mtool_gen_cncjob)
def on_properties(self, state):
if state:
self.ui.properties_frame.show()
@ -732,7 +737,6 @@ class GeometryObject(FlatCAMObj, Geometry):
# I use lambda's because the connected functions have parameters that could be used in certain scenarios
self.ui.addtool_btn.clicked.connect(lambda: self.on_tool_add())
self.ui.copytool_btn.clicked.connect(lambda: self.on_tool_copy())
self.ui.deltool_btn.clicked.connect(lambda: self.on_tool_delete())
self.ui.geo_tools_table.clicked.connect(self.on_row_selection_change)
@ -797,11 +801,6 @@ class GeometryObject(FlatCAMObj, Geometry):
except (TypeError, AttributeError):
pass
try:
self.ui.copytool_btn.clicked.disconnect()
except (TypeError, AttributeError):
pass
try:
self.ui.deltool_btn.clicked.disconnect()
except (TypeError, AttributeError):
@ -1833,7 +1832,7 @@ class GeometryObject(FlatCAMObj, Geometry):
except AttributeError:
pass
def on_generatecnc_button_click(self, *args):
def on_generatecnc_button_click(self):
log.debug("Generating CNCJob from Geometry ...")
self.app.defaults.report_usage("geometry_on_generatecnc_button")
@ -1862,7 +1861,11 @@ class GeometryObject(FlatCAMObj, Geometry):
self.sel_tools.update({
tooluid: deepcopy(tooluid_value)
})
self.mtool_gen_cncjob()
if self.ui.polish_cb.get_value():
self.on_polish()
else:
self.mtool_gen_cncjob()
self.ui.geo_tools_table.clearSelection()
elif self.ui.geo_tools_table.rowCount() == 1:
@ -1873,9 +1876,11 @@ class GeometryObject(FlatCAMObj, Geometry):
self.sel_tools.update({
tooluid: deepcopy(tooluid_value)
})
self.mtool_gen_cncjob()
if self.ui.polish_cb.get_value():
self.on_polish()
else:
self.mtool_gen_cncjob()
self.ui.geo_tools_table.clearSelection()
else:
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed. No tool selected in the tool table ..."))
@ -1955,7 +1960,7 @@ class GeometryObject(FlatCAMObj, Geometry):
tool_cnt += 1
dia_cnc_dict = deepcopy(tools_dict[tooluid_key])
tooldia_val = float('%.*f' % (self.decimals, float(tools_dict[tooluid_key]['tooldia'])))
tooldia_val = app_obj.dec_format(float(tools_dict[tooluid_key]['tooldia']), self.decimals)
dia_cnc_dict.update({
'tooldia': tooldia_val
})
@ -1972,12 +1977,12 @@ class GeometryObject(FlatCAMObj, Geometry):
try:
offset_value = float(self.ui.tool_offset_entry.get_value().replace(',', '.'))
except ValueError:
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number."))
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number."))
return
if offset_value:
tool_offset = float(offset_value)
else:
self.app.inform.emit(
app_obj.inform.emit(
'[WARNING] %s' % _("Tool Offset is selected in Tool Table but no value is provided.\n"
"Add a Tool Offset or change the Offset Type.")
)
@ -2048,17 +2053,16 @@ class GeometryObject(FlatCAMObj, Geometry):
self.app.inform.emit('[success] %s' % _("G-Code parsing in progress..."))
dia_cnc_dict['gcode_parsed'] = job_obj.gcode_parse()
self.app.inform.emit('[success] %s' % _("G-Code parsing finished..."))
app_obj.inform.emit('[success] %s' % _("G-Code parsing finished..."))
# TODO this serve for bounding box creation only; should be optimized
# commented this; there is no need for the actual GCode geometry - the original one will serve as well
# for bounding box values
# dia_cnc_dict['solid_geometry'] = unary_union([geo['geom'] for geo in dia_cnc_dict['gcode_parsed']])
try:
dia_cnc_dict['solid_geometry'] = tool_solid_geometry
self.app.inform.emit('[success] %s...' % _("Finished G-Code processing"))
app_obj.inform.emit('[success] %s...' % _("Finished G-Code processing"))
except Exception as er:
self.app.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(er)))
app_obj.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(er)))
job_obj.cnc_tools.update({
tooluid_key: deepcopy(dia_cnc_dict)
@ -2102,15 +2106,14 @@ class GeometryObject(FlatCAMObj, Geometry):
if self.tools[tooluid_key]['solid_geometry'] is None:
a += 1
if a == len(self.tools):
self.app.inform.emit('[ERROR_NOTCL] %s...' % _('Cancelled. Empty file, it has no geometry'))
app_obj.inform.emit('[ERROR_NOTCL] %s...' % _('Cancelled. Empty file, it has no geometry'))
return 'fail'
total_gcode = ''
for tooluid_key in list(tools_dict.keys()):
tool_cnt += 1
dia_cnc_dict = deepcopy(tools_dict[tooluid_key])
tooldia_val = float('%.*f' % (self.decimals, float(tools_dict[tooluid_key]['tooldia'])))
tooldia_val = app_obj.dec_format(float(tools_dict[tooluid_key]['tooldia']), self.decimals)
dia_cnc_dict.update({
'tooldia': tooldia_val
})
@ -2144,27 +2147,27 @@ class GeometryObject(FlatCAMObj, Geometry):
'offset_value': tool_offset
})
z_cut = tools_dict[tooluid_key]['data']["cutz"]
z_move = tools_dict[tooluid_key]['data']["travelz"]
feedrate = tools_dict[tooluid_key]['data']["feedrate"]
feedrate_z = tools_dict[tooluid_key]['data']["feedrate_z"]
feedrate_rapid = tools_dict[tooluid_key]['data']["feedrate_rapid"]
multidepth = tools_dict[tooluid_key]['data']["multidepth"]
extracut = tools_dict[tooluid_key]['data']["extracut"]
extracut_length = tools_dict[tooluid_key]['data']["extracut_length"]
depthpercut = tools_dict[tooluid_key]['data']["depthperpass"]
toolchange = tools_dict[tooluid_key]['data']["toolchange"]
toolchangez = tools_dict[tooluid_key]['data']["toolchangez"]
toolchangexy = tools_dict[tooluid_key]['data']["toolchangexy"]
startz = tools_dict[tooluid_key]['data']["startz"]
endz = tools_dict[tooluid_key]['data']["endz"]
endxy = self.options["endxy"]
spindlespeed = tools_dict[tooluid_key]['data']["spindlespeed"]
dwell = tools_dict[tooluid_key]['data']["dwell"]
dwelltime = tools_dict[tooluid_key]['data']["dwelltime"]
pp_geometry_name = tools_dict[tooluid_key]['data']["ppname_g"]
spindledir = self.app.defaults['geometry_spindledir']
# z_cut = tools_dict[tooluid_key]['data']["cutz"]
# z_move = tools_dict[tooluid_key]['data']["travelz"]
# feedrate = tools_dict[tooluid_key]['data']["feedrate"]
# feedrate_z = tools_dict[tooluid_key]['data']["feedrate_z"]
# feedrate_rapid = tools_dict[tooluid_key]['data']["feedrate_rapid"]
# multidepth = tools_dict[tooluid_key]['data']["multidepth"]
# extracut = tools_dict[tooluid_key]['data']["extracut"]
# extracut_length = tools_dict[tooluid_key]['data']["extracut_length"]
# depthpercut = tools_dict[tooluid_key]['data']["depthperpass"]
# toolchange = tools_dict[tooluid_key]['data']["toolchange"]
# toolchangez = tools_dict[tooluid_key]['data']["toolchangez"]
# toolchangexy = tools_dict[tooluid_key]['data']["toolchangexy"]
# startz = tools_dict[tooluid_key]['data']["startz"]
# endz = tools_dict[tooluid_key]['data']["endz"]
# endxy = self.options["endxy"]
# spindlespeed = tools_dict[tooluid_key]['data']["spindlespeed"]
# dwell = tools_dict[tooluid_key]['data']["dwell"]
# dwelltime = tools_dict[tooluid_key]['data']["dwelltime"]
# pp_geometry_name = tools_dict[tooluid_key]['data']["ppname_g"]
#
# spindledir = self.app.defaults['geometry_spindledir']
tool_solid_geometry = self.tools[tooluid_key]['solid_geometry']
job_obj.coords_decimals = self.app.defaults["cncjob_coords_decimals"]
@ -2196,11 +2199,10 @@ class GeometryObject(FlatCAMObj, Geometry):
if start_gcode != '':
job_obj.gc_start = start_gcode
self.app.inform.emit('[success] %s' % _("G-Code parsing in progress..."))
app_obj.inform.emit('[success] %s' % _("G-Code parsing in progress..."))
dia_cnc_dict['gcode_parsed'] = job_obj.gcode_parse()
self.app.inform.emit('[success] %s' % _("G-Code parsing finished..."))
app_obj.inform.emit('[success] %s' % _("G-Code parsing finished..."))
# TODO this serve for bounding box creation only; should be optimized
# commented this; there is no need for the actual GCode geometry - the original one will serve as well
# for bounding box values
# geo_for_bound_values = unary_union([
@ -2208,9 +2210,9 @@ class GeometryObject(FlatCAMObj, Geometry):
# ])
try:
dia_cnc_dict['solid_geometry'] = deepcopy(tool_solid_geometry)
self.app.inform.emit('[success] %s' % _("Finished G-Code processing..."))
app_obj.inform.emit('[success] %s' % _("Finished G-Code processing..."))
except Exception as ee:
self.app.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(ee)))
app_obj.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(ee)))
# tell gcode_parse from which point to start drawing the lines depending on what kind of
# object is the source of gcode
@ -2228,11 +2230,13 @@ class GeometryObject(FlatCAMObj, Geometry):
def job_thread(a_obj):
if self.multigeo is False:
with self.app.proc_container.new(_("Generating CNC Code")):
if a_obj.app_obj.new_object("cncjob", outname, job_init_single_geometry, plot=plot) != 'fail':
ret_val = a_obj.app_obj.new_object("cncjob", outname, job_init_single_geometry, plot=plot)
if ret_val != 'fail':
a_obj.inform.emit('[success] %s: %s' % (_("CNCjob created"), outname))
else:
with self.app.proc_container.new(_("Generating CNC Code")):
if a_obj.app_obj.new_object("cncjob", outname, job_init_multi_geometry) != 'fail':
ret_val = a_obj.app_obj.new_object("cncjob", outname, job_init_multi_geometry, plot=plot)
if ret_val != 'fail':
a_obj.inform.emit('[success] %s: %s' % (_("CNCjob created"), outname))
# Create a promise with the name
@ -2378,7 +2382,7 @@ class GeometryObject(FlatCAMObj, Geometry):
# source of gcode
job_obj.toolchange_xy_type = "geometry"
job_obj.gcode_parse()
self.app.inform.emit('[success] %s' % _("Finished G-Code processing..."))
app_obj.inform.emit('[success] %s' % _("Finished G-Code processing..."))
if use_thread:
# To be run in separate thread
@ -2394,10 +2398,100 @@ class GeometryObject(FlatCAMObj, Geometry):
else:
self.app.app_obj.new_object("cncjob", outname, job_init, plot=plot)
# def on_plot_cb_click(self, *args):
# if self.muted_ui:
# return
# self.read_form_item('plot')
def on_polish(self):
def job_thread(obj):
with obj.app.proc_container.new(_("Working...")):
tooldia = obj.ui.polish_dia_entry.get_value()
depth = obj.ui.polish_pressure_entry.get_value()
travelz = obj.ui.polish_travelz_entry.get_value()
margin = obj.ui.polish_margin_entry.get_value()
overlap = obj.ui.polish_over_entry.get_value() / 100
paint_method = obj.ui.polish_method_combo.get_value()
# calculate the max uid form the keys of the self.tools
max_uid = max(list(obj.tools.keys()))
new_uid = max_uid + 1
# add a new key in the dict
new_data = deepcopy(obj.default_data)
new_data["travelz"] = travelz
new_data["cutz"] = depth
new_dict = {
new_uid: {
'tooldia': obj.app.dec_format(float(tooldia), obj.decimals),
'offset': 'Path',
'offset_value': 0.0,
'type': _('Polish'),
'tool_type': 'C1',
'data': new_data,
'solid_geometry': []
}
}
obj.tools.update(new_dict)
obj.sel_tools.update(new_dict)
# make a box polygon out of the bounds of the current object
# apply the margin
xmin, ymin, xmax, ymax = obj.bounds()
bbox = box(xmin-margin, ymin-margin, xmax+margin, ymax+margin)
# paint the box
try:
# provide the app with a way to process the GUI events when in a blocking loop
QtWidgets.QApplication.processEvents()
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
# Type(cpoly) == FlatCAMRTreeStorage | None
cpoly = None
if paint_method == _("Standard"):
cpoly = self.clear_polygon(bbox,
tooldia=tooldia,
steps_per_circle=obj.circle_steps,
overlap=overlap,
contour=True,
connect=True,
prog_plot=False)
elif paint_method == _("Seed"):
cpoly = self.clear_polygon2(bbox,
tooldia=tooldia,
steps_per_circle=obj.circle_steps,
overlap=overlap,
contour=True,
connect=True,
prog_plot=False)
elif paint_method == _("Lines"):
cpoly = self.clear_polygon3(bbox,
tooldia=tooldia,
steps_per_circle=obj.circle_steps,
overlap=overlap,
contour=True,
connect=True,
prog_plot=False)
if not cpoly or not cpoly.objects:
obj.app.inform.emit('[ERROR_NOTCL] %s' % _('Geometry could not be painted completely'))
return
paint_geo = [g for g in cpoly.get_objects() if g and not g.is_empty]
except grace:
return "fail"
except Exception as e:
log.debug("Could not Paint the polygons. %s" % str(e))
mssg = '[ERROR] %s\n%s' % (_("Could not do Paint. Try a different combination of parameters. "
"Or a different strategy of paint"), str(e))
self.app.inform.emit(mssg)
return
obj.sel_tools[new_uid]['solid_geometry'] = paint_geo
# and now create the CNCJob
obj.launch_job.emit()
# Send to worker
self.app.worker_task.emit({'fcn': job_thread, 'params': [self]})
def scale(self, xfactor, yfactor=None, point=None):
"""
@ -2874,7 +2968,7 @@ class GeometryObject(FlatCAMObj, Geometry):
except (ObjectDeleted, AttributeError):
self.shapes.clear(update=True)
def on_plot_cb_click(self, *args):
def on_plot_cb_click(self):
if self.muted_ui:
return
self.read_form_item('plot')
@ -2933,7 +3027,7 @@ class GeometryObject(FlatCAMObj, Geometry):
self.ui.plot_cb.setChecked(True)
self.ui_connect()
def on_multicolored_cb_click(self, *args):
def on_multicolored_cb_click(self):
if self.muted_ui:
return
self.read_form_item('multicolored')

View File

@ -9,7 +9,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui
from appTool import AppTool
from appGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton, \
FCComboBox, OptionalInputSection, FCSpinner, FCLabel
FCComboBox, OptionalInputSection, FCSpinner, FCLabel, FCInputDialogSpinnerButton
from appParsers.ParseGerber import Gerber
from camlib import grace
@ -58,7 +58,8 @@ class ToolIsolation(AppTool, Gerber):
# #############################################################################
self.ui.tools_table.setupContextMenu()
self.ui.tools_table.addContextMenu(
_("Search and Add"), self.on_add_tool_by_key,
_("Search and Add"),
self.on_add_tool_by_key,
icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")
)
self.ui.tools_table.addContextMenu(
@ -779,20 +780,34 @@ class ToolIsolation(AppTool, Gerber):
self.blockSignals(False)
def on_add_tool_by_key(self):
tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
text='%s:' % _('Enter a Tool Diameter'),
min=0.0001, max=9999.9999, decimals=self.decimals)
# tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
# text='%s:' % _('Enter a Tool Diameter'),
# min=0.0001, max=9999.9999, decimals=self.decimals)
btn_icon = QtGui.QIcon(self.app.resource_location + '/open_excellon32.png')
tool_add_popup = FCInputDialogSpinnerButton(title='%s...' % _("New Tool"),
text='%s:' % _('Enter a Tool Diameter'),
min=0.0001, max=9999.9999, decimals=self.decimals,
button_icon=btn_icon,
callback=self.on_find_optimal_tooldia)
tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
val, ok = tool_add_popup.get_value()
def find_optimal(val):
tool_add_popup.set_value(float(val))
self.optimal_found_sig.connect(find_optimal)
val, ok = tool_add_popup.get_results()
if ok:
if float(val) == 0:
self.app.inform.emit('[WARNING_NOTCL] %s' %
_("Please enter a tool diameter with non-zero value, in Float format."))
self.optimal_found_sig.disconnect(find_optimal)
return
self.on_tool_add(custom_dia=float(val))
else:
self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled"))
self.optimal_found_sig.disconnect(find_optimal)
def on_reference_combo_changed(self):
obj_type = self.ui.reference_combo_type.currentIndex()
@ -913,7 +928,7 @@ class ToolIsolation(AppTool, Gerber):
return
def job_thread(app_obj, is_display):
with self.app.proc_container.new(_("Working...")) as proc:
with self.app.proc_container.new(_("Working...")):
try:
old_disp_number = 0
pol_nr = 0

View File

@ -9,7 +9,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui
from appTool import AppTool
from appGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton,\
FCComboBox, OptionalInputSection, FCLabel
FCComboBox, OptionalInputSection, FCLabel, FCInputDialogSpinnerButton
from appParsers.ParseGerber import Gerber
from camlib import grace
@ -451,20 +451,34 @@ class NonCopperClear(AppTool, Gerber):
self.blockSignals(False)
def on_add_tool_by_key(self):
tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
text='%s:' % _('Enter a Tool Diameter'),
min=0.0001, max=9999.9999, decimals=self.decimals)
# tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
# text='%s:' % _('Enter a Tool Diameter'),
# min=0.0001, max=9999.9999, decimals=self.decimals)
btn_icon = QtGui.QIcon(self.app.resource_location + '/open_excellon32.png')
tool_add_popup = FCInputDialogSpinnerButton(title='%s...' % _("New Tool"),
text='%s:' % _('Enter a Tool Diameter'),
min=0.0001, max=9999.9999, decimals=self.decimals,
button_icon=btn_icon,
callback=self.on_find_optimal_tooldia)
tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
val, ok = tool_add_popup.get_value()
def find_optimal(val):
tool_add_popup.set_value(float(val))
self.optimal_found_sig.connect(find_optimal)
val, ok = tool_add_popup.get_results()
if ok:
if float(val) == 0:
self.app.inform.emit('[WARNING_NOTCL] %s' %
_("Please enter a tool diameter with non-zero value, in Float format."))
self.optimal_found_sig.disconnect(find_optimal)
return
self.on_tool_add(custom_dia=float(val))
else:
self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled"))
self.optimal_found_sig.disconnect(find_optimal)
def set_tool_ui(self):
self.units = self.app.defaults['units'].upper()

View File

@ -8,7 +8,7 @@
from appTool import AppTool
from appCommon.Common import LoudDict
from appGUI.GUIElements import FCComboBox, FCEntry, FCTable, \
FCInputDialog, FCDoubleSpinner, FCSpinner, FCFileSaveDialog
FCInputDialog, FCDoubleSpinner, FCSpinner, FCFileSaveDialog, FCInputSpinner
from app_Main import log
from camlib import distance
from appEditors.AppTextEditor import AppTextEditor
@ -119,9 +119,9 @@ class SolderPaste(AppTool):
AppTool.install(self, icon, separator, shortcut='Alt+K', **kwargs)
def on_add_tool_by_key(self):
tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
text='%s:' % _('Enter a Tool Diameter'),
min=0.0000, max=99.9999, decimals=4)
tool_add_popup = FCInputSpinner(title='%s...' % _("New Tool"),
text='%s:' % _('Enter a Tool Diameter'),
min=0.0000, max=100.0000, decimals=self.decimals, step=0.1)
tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
val, ok = tool_add_popup.get_value()

View File

@ -4419,9 +4419,9 @@ class App(QtCore.QObject):
if self.collection.get_active().kind == 'geometry':
# Tool add works for Geometry only if Advanced is True in Preferences
if self.defaults["global_app_level"] == 'a':
tool_add_popup = FCInputDialog(title="New Tool ...",
text='Enter a Tool Diameter:',
min=0.0000, max=99.9999, decimals=4)
tool_add_popup = FCInputSpinner(title='%s...' % _("New Tool"),
text='%s:' % _('Enter a Tool Diameter'),
min=0.0000, max=100.0000, decimals=self.decimals, step=0.1)
tool_add_popup.setWindowIcon(QtGui.QIcon(self.resource_location + '/letter_t_32.png'))
val, ok = tool_add_popup.get_value()
@ -4448,7 +4448,10 @@ class App(QtCore.QObject):
# work only if the notebook tab on focus is the Tools_Tab
if notebook_widget_name == 'tool_tab':
tool_widget = self.ui.tool_scroll_area.widget().objectName()
try:
tool_widget = self.ui.tool_scroll_area.widget().objectName()
except AttributeError:
return
# and only if the tool is NCC Tool
if tool_widget == self.ncclear_tool.toolName:
@ -4462,6 +4465,10 @@ class App(QtCore.QObject):
elif tool_widget == self.paste_tool.toolName:
self.paste_tool.on_add_tool_by_key()
# and only if the tool is Isolation Tool
elif tool_widget == self.isolation_tool.toolName:
self.isolation_tool.on_add_tool_by_key()
# It's meant to delete tools in tool tables via a 'Delete' shortcut key but only if certain conditions are met
# See description below.
def on_delete_keypress(self):
@ -4469,7 +4476,7 @@ class App(QtCore.QObject):
# work only if the notebook tab on focus is the properties_tab and only if the object is Geometry
if notebook_widget_name == 'properties_tab':
if str(type(self.collection.get_active())) == "<class 'FlatCAMObj.GeometryObject'>":
if self.collection.get_active().kind == 'geometry':
self.collection.get_active().on_tool_delete()
# work only if the notebook tab on focus is the Tools_Tab

View File

@ -345,7 +345,9 @@ class FlatCAMDefaults:
"geometry_polish": False,
"geometry_polish_dia": 10.0,
"geometry_polish_pressure": -1.0,
"geometry_polish_overlap": 1.0,
"geometry_polish_travelz": 2.0,
"geometry_polish_margin": 0.0,
"geometry_polish_overlap": 5,
"geometry_polish_method": _("Standard"),
# Geometry Editor