From 33f764efb50109baaa4fc887e011e42478b35ab7 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 10 Dec 2019 15:26:51 +0200 Subject: [PATCH] - in CNCJob UI, now the CNCJob objects made out of Excellon objects will display their CNC tools (drill bits) --- FlatCAMCommon.py | 10 +++ FlatCAMObj.py | 120 ++++++++++++++++++++++++++++---- README.md | 3 +- flatcamGUI/ObjectUI.py | 29 +++++++- flatcamGUI/PlotCanvas.py | 2 +- flatcamTools/ToolSolderPaste.py | 6 +- 6 files changed, 150 insertions(+), 20 deletions(-) diff --git a/FlatCAMCommon.py b/FlatCAMCommon.py index fee20344..547e4fef 100644 --- a/FlatCAMCommon.py +++ b/FlatCAMCommon.py @@ -848,6 +848,16 @@ class ToolsDB(QtWidgets.QWidget): multidepth_item.set_value(data['multidepth']) widget.setCellWidget(row, 8, multidepth_item) + # to make the checkbox centered but it can no longer have it's value accessed - needs a fix using findchild() + # multidepth_item = QtWidgets.QWidget() + # cb = FCCheckBox() + # cb.set_value(data['multidepth']) + # qhboxlayout = QtWidgets.QHBoxLayout(multidepth_item) + # qhboxlayout.addWidget(cb) + # qhboxlayout.setAlignment(QtCore.Qt.AlignCenter) + # qhboxlayout.setContentsMargins(0, 0, 0, 0) + # widget.setCellWidget(row, 8, multidepth_item) + depth_per_pass_item = FCDoubleSpinner() depth_per_pass_item.set_precision(self.decimals) depth_per_pass_item.setSingleStep(0.1) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 8d9d8abc..d017bab2 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -6039,15 +6039,22 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.ui_disconnect() FlatCAMObj.build_ui(self) - - # if the FlatCAM object is Excellon don't build the CNC Tools Table but hide it - if self.cnc_tools: - self.ui.cnc_tools_table.show() - else: - self.ui.cnc_tools_table.hide() - self.units = self.app.defaults['units'].upper() + # if the FlatCAM object is Excellon don't build the CNC Tools Table but hide it + self.ui.cnc_tools_table.hide() + if self.cnc_tools: + self.ui.cnc_tools_table.show() + self.build_cnc_tools_table() + + self.ui.exc_cnc_tools_table.hide() + if self.exc_cnc_tools: + self.ui.exc_cnc_tools_table.show() + self.build_excellon_cnc_tools() + # + self.ui_connect() + + def build_cnc_tools_table(self): offset = 0 tool_idx = 0 @@ -6146,7 +6153,86 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.ui.cnc_tools_table.setMinimumHeight(self.ui.cnc_tools_table.getHeight()) self.ui.cnc_tools_table.setMaximumHeight(self.ui.cnc_tools_table.getHeight()) - self.ui_connect() + def build_excellon_cnc_tools(self): + tool_idx = 0 + + n = len(self.exc_cnc_tools) + self.ui.exc_cnc_tools_table.setRowCount(n) + + for tooldia_key, dia_value in self.exc_cnc_tools.items(): + + tool_idx += 1 + row_no = tool_idx - 1 + + id = QtWidgets.QTableWidgetItem('%d' % int(tool_idx)) + dia_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, float(tooldia_key))) + nr_drills_item = QtWidgets.QTableWidgetItem('%d' % int(dia_value['nr_drills'])) + nr_slots_item = QtWidgets.QTableWidgetItem('%d' % int(dia_value['nr_slots'])) + + id.setFlags(QtCore.Qt.ItemIsEnabled) + dia_item.setFlags(QtCore.Qt.ItemIsEnabled) + nr_drills_item.setFlags(QtCore.Qt.ItemIsEnabled) + nr_slots_item.setFlags(QtCore.Qt.ItemIsEnabled) + + # hack so the checkbox stay centered in the table cell + # used this: + # https://stackoverflow.com/questions/32458111/pyqt-allign-checkbox-and-put-it-in-every-row + # plot_item = QtWidgets.QWidget() + # checkbox = FCCheckBox() + # checkbox.setCheckState(QtCore.Qt.Checked) + # qhboxlayout = QtWidgets.QHBoxLayout(plot_item) + # qhboxlayout.addWidget(checkbox) + # qhboxlayout.setAlignment(QtCore.Qt.AlignCenter) + # qhboxlayout.setContentsMargins(0, 0, 0, 0) + + plot_item = FCCheckBox() + plot_item.setLayoutDirection(QtCore.Qt.RightToLeft) + tool_uid_item = QtWidgets.QTableWidgetItem(str(dia_value['tool'])) + if self.ui.plot_cb.isChecked(): + plot_item.setChecked(True) + + # TODO until the feature of individual plot for an Excellon tool is implemented + plot_item.setDisabled(True) + + self.ui.exc_cnc_tools_table.setItem(row_no, 0, id) # Tool name/id + self.ui.exc_cnc_tools_table.setItem(row_no, 1, dia_item) # Diameter + self.ui.exc_cnc_tools_table.setItem(row_no, 2, nr_drills_item) # Nr of drills + self.ui.exc_cnc_tools_table.setItem(row_no, 3, nr_slots_item) # Nr of slots + + # ## REMEMBER: THIS COLUMN IS HIDDEN IN OBJECTUI.PY # ## + self.ui.exc_cnc_tools_table.setItem(row_no, 4, tool_uid_item) # Tool unique ID) + self.ui.exc_cnc_tools_table.setCellWidget(row_no, 5, plot_item) + + for row in range(tool_idx): + self.ui.exc_cnc_tools_table.item(row, 0).setFlags( + self.ui.exc_cnc_tools_table.item(row, 0).flags() ^ QtCore.Qt.ItemIsSelectable) + + self.ui.exc_cnc_tools_table.resizeColumnsToContents() + self.ui.exc_cnc_tools_table.resizeRowsToContents() + + vertical_header = self.ui.exc_cnc_tools_table.verticalHeader() + vertical_header.hide() + self.ui.exc_cnc_tools_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + + horizontal_header = self.ui.exc_cnc_tools_table.horizontalHeader() + horizontal_header.setMinimumSectionSize(10) + horizontal_header.setDefaultSectionSize(70) + horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.Fixed) + horizontal_header.resizeSection(0, 20) + horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch) + horizontal_header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) + horizontal_header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents) + + horizontal_header.setSectionResizeMode(5, QtWidgets.QHeaderView.Fixed) + + # horizontal_header.setStretchLastSection(True) + self.ui.exc_cnc_tools_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + + self.ui.exc_cnc_tools_table.setColumnWidth(0, 20) + self.ui.exc_cnc_tools_table.setColumnWidth(5, 17) + + self.ui.exc_cnc_tools_table.setMinimumHeight(self.ui.exc_cnc_tools_table.getHeight()) + self.ui.exc_cnc_tools_table.setMaximumHeight(self.ui.exc_cnc_tools_table.getHeight()) def set_ui(self, ui): FlatCAMObj.set_ui(self, ui) @@ -6733,10 +6819,20 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.plot2(dia_plot, obj=self, visible=visible, kind=kind) else: # multiple tools usage - for tooluid_key in self.cnc_tools: - tooldia = float('%.*f' % (self.decimals, float(self.cnc_tools[tooluid_key]['tooldia']))) - gcode_parsed = self.cnc_tools[tooluid_key]['gcode_parsed'] - self.plot2(tooldia=tooldia, obj=self, visible=visible, gcode_parsed=gcode_parsed, kind=kind) + if self.cnc_tools: + for tooluid_key in self.cnc_tools: + tooldia = float('%.*f' % (self.decimals, float(self.cnc_tools[tooluid_key]['tooldia']))) + gcode_parsed = self.cnc_tools[tooluid_key]['gcode_parsed'] + self.plot2(tooldia=tooldia, obj=self, visible=visible, gcode_parsed=gcode_parsed, kind=kind) + + # TODO: until the gcode parsed will be stored on each Excellon tool this will not get executed + if self.exc_cnc_tools: + for tooldia_key in self.exc_cnc_tools: + tooldia = float('%.*f' % (self.decimals, float(tooldia_key))) + # gcode_parsed = self.cnc_tools[tooldia_key]['gcode_parsed'] + gcode_parsed = self.gcode_parsed + self.plot2(tooldia=tooldia, obj=self, visible=visible, gcode_parsed=gcode_parsed, kind=kind) + self.shapes.redraw() except (ObjectDeleted, AttributeError): self.shapes.clear(update=True) diff --git a/README.md b/README.md index c9022369..ca19410c 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ CAD program, and create G-Code for Isolation routing. - small changes in the Geometry UI - now extracut option in the Geometry Object will recut as many points as many they are within the specified re-cut length - if extracut_length is zero then the extracut will cut up until the first point in path no matter what the distance is -- in Gerber isolation when selection mode is checked now area selection works too +- in Gerber isolation, when selection mode is checked, now area selection works too +- in CNCJob UI, now the CNCJob objects made out of Excellon objects will display their CNC tools (drill bits) 9.12.2019 diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 62aa4526..ee49b74e 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -1030,6 +1030,12 @@ class ExcellonObjectUI(ObjectUI): self.generate_cnc_button.setToolTip( _("Generate the CNC Job.") ) + self.generate_cnc_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) grid2.addWidget(self.generate_cnc_button, 2, 0, 1, 3) # ### Milling Holes Drills #### @@ -1055,6 +1061,12 @@ class ExcellonObjectUI(ObjectUI): _("Create the Geometry Object\n" "for milling DRILLS toolpaths.") ) + self.generate_milling_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) grid2.addWidget(self.tdlabel, 4, 0) grid2.addWidget(self.tooldia_entry, 4, 1) @@ -1076,6 +1088,12 @@ class ExcellonObjectUI(ObjectUI): _("Create the Geometry Object\n" "for milling SLOTS toolpaths.") ) + self.generate_milling_slots_button.setStyleSheet(""" + QPushButton + { + font-weight: bold; + } + """) grid2.addWidget(self.stdlabel, 5, 0) grid2.addWidget(self.slot_tooldia_entry, 5, 1) @@ -1827,12 +1845,19 @@ class CNCObjectUI(ObjectUI): self.cnc_tools_table.setColumnCount(7) self.cnc_tools_table.setColumnWidth(0, 20) - self.cnc_tools_table.setHorizontalHeaderLabels(['#', _('Dia'), _('Offset'), _('Type'), _('TT'), '', - _('P')]) + self.cnc_tools_table.setHorizontalHeaderLabels(['#', _('Dia'), _('Offset'), _('Type'), _('TT'), '', _('P')]) self.cnc_tools_table.setColumnHidden(5, True) # stylesheet = "::section{Background-color:rgb(239,239,245)}" # self.cnc_tools_table.horizontalHeader().setStyleSheet(stylesheet) + self.exc_cnc_tools_table = FCTable() + self.custom_box.addWidget(self.exc_cnc_tools_table) + + self.exc_cnc_tools_table.setColumnCount(6) + self.exc_cnc_tools_table.setColumnWidth(0, 20) + self.exc_cnc_tools_table.setHorizontalHeaderLabels(['#', _('Dia'), _('Drills'), _('Slots'), '', _('P')]) + self.exc_cnc_tools_table.setColumnHidden(4, True) + self.tooldia_entry = FCDoubleSpinner() self.tooldia_entry.set_range(0, 9999.9999) self.tooldia_entry.set_precision(self.decimals) diff --git a/flatcamGUI/PlotCanvas.py b/flatcamGUI/PlotCanvas.py index 174617e0..15495dab 100644 --- a/flatcamGUI/PlotCanvas.py +++ b/flatcamGUI/PlotCanvas.py @@ -303,7 +303,7 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas): p2 = np.array(curr_pos)[:2] self.view.camera.pan(p2 - p1) - if self.fcapp.grid_status() == True: + if self.fcapp.grid_status(): pos_canvas = self.translate_coords(curr_pos) pos = self.fcapp.geo_editor.snap(pos_canvas[0], pos_canvas[1]) diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py index 25c50b0d..518236ca 100644 --- a/flatcamTools/ToolSolderPaste.py +++ b/flatcamTools/ToolSolderPaste.py @@ -1283,8 +1283,7 @@ class SolderPaste(FlatCAMTool): obj = self.app.collection.get_by_name(name) if name == '': - self.app.inform.emit('[WARNING_NOTCL] %s' % - _("There is no Geometry object available.")) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Geometry object available.")) return 'fail' if obj.special_group != 'solder_paste_tool': @@ -1298,8 +1297,7 @@ class SolderPaste(FlatCAMTool): if obj.tools[tooluid_key]['solid_geometry'] is None: a += 1 if a == len(obj.tools): - self.app.inform.emit('[ERROR_NOTCL] %s...' % - _('Cancelled. Empty file, it has no geometry')) + self.app.inform.emit('[ERROR_NOTCL] %s...' % _('Cancelled. Empty file, it has no geometry')) return 'fail' # use the name of the first tool selected in self.geo_tools_table which has the diameter passed as tool_dia