diff --git a/configs/probe_basic/user_tabs/template_sidebar/template_sidebar.py b/configs/probe_basic/user_tabs/template_sidebar/template_sidebar.py index b44efb7..7112b6a 100644 --- a/configs/probe_basic/user_tabs/template_sidebar/template_sidebar.py +++ b/configs/probe_basic/user_tabs/template_sidebar/template_sidebar.py @@ -6,7 +6,7 @@ from qtpy import uic from qtpy.QtCore import Qt from qtpy.QtWidgets import QWidget, QPushButton -from qtpyvcp.actions import machine, machine_actions +from qtpyvcp.actions import machine_actions from qtpyvcp.plugins import getPlugin from qtpyvcp.utilities import logger from widgets.conversational.float_line_edit import FloatLineEdit @@ -19,158 +19,133 @@ TOOL_TABLE = getPlugin('tooltable') INI_FILE = linuxcnc.ini(os.getenv('INI_FILE_NAME')) CMD = linuxcnc.command() + class MoveMode(Enum): + """Defines the available movement modes (absolute, work coordinate system, relative).""" ABS = 1 WCS = 2 REL = 3 + class UserTab(QWidget): + """A sidebar widget for controlling machine axis movements.""" + def __init__(self, parent=None): super(UserTab, self).__init__(parent) ui_file = os.path.splitext(os.path.basename(__file__))[0] + ".ui" uic.loadUi(os.path.join(os.path.dirname(__file__), ui_file), self) - STATUS.on.notify(self._update_controls) - STATUS.all_axes_homed.notify(self._update_controls) + self.position_inputs: list[FloatLineEdit] = self.findChildren(FloatLineEdit) + self.move_buttons: list[QPushButton] = self.findChildren(QPushButton) - STATUS.g5x_index.notify(self.update_wcs_label) + self._connect_signals() self.update_wcs_label() - - self.edits: list[FloatLineEdit] = self.findChildren(FloatLineEdit) - for fle in self.edits: - fle.setEnabled(False) - fle.editingFinished.connect(self.format_float) + def _connect_signals(self): + """Connects widget signals to corresponding slots.""" + STATUS.on.notify(self._update_control_states) + STATUS.all_axes_homed.notify(self._update_control_states) + STATUS.g5x_index.notify(self.update_wcs_label) - self.buttons: list[QPushButton] = self.findChildren(QPushButton) + for line_edit in self.position_inputs: + line_edit.setEnabled(False) + line_edit.editingFinished.connect(self._format_sender_float_value) - for btn in self.buttons: - btn.setEnabled(False) - btn.clicked.connect(self.move_axis) + for button in self.move_buttons: + button.setEnabled(False) + button.clicked.connect(self._on_move_button_clicked) - - def format_float(self): - if not isinstance(self.sender(), FloatLineEdit): + def _format_sender_float_value(self): + """Formats the text of the sending FloatLineEdit to its specified format.""" + sender_widget = self.sender() + if not isinstance(sender_widget, FloatLineEdit): return - - w: FloatLineEdit = self.sender() - if w is None: - LOG.debug(f"fn _format_float, sender None") + + LOG.debug(f"Formatting float for {sender_widget.objectName()}") + value = sender_widget.value() + formatted_value = sender_widget.format_string.format(value) + sender_widget.setText(formatted_value) + + def update_wcs_label(self, *args): + """Updates the WCS status label with the current coordinate system.""" + wcs_index = STATUS.g5x_index + self.wcs_status_label.setText(f"WCS {wcs_index}") + + def _on_move_button_clicked(self): + """Handles clicks on any of the move buttons.""" + sender = self.sender() + if not isinstance(sender, QPushButton): return - LOG.debug(f"fn: _format_float, sender name: {w.objectName()}") - value = w.value() - fmt = w.format_string - val_fmt = fmt.format(value) - w.setText(val_fmt) + button_name = sender.objectName() + LOG.debug(f"Move button clicked: {button_name}") - - - def update_wcs_label(self): - idx = STATUS.g5x_index - self.statuslabel_wcs.setText(f"WCS {idx}") - # 'G54' if ch[0] == 1 else 'G55' if ch[0] == 2 else 'G56' if ch[0] == 3 else 'none' - - def move_relative(self): - # machine_actions.jog.axis(axis='x', direction=1, distance=0.5) - machine_actions.issue_mdi(f"G91 G0 X{self.fle_rel_x.value()}; G90") - LOG.debug(f"fn: move_x. fle_wcs_x:{self.fle_rel_x.value()}") - - - def move_axis(self): - if not isinstance(self.sender(), QPushButton): + try: + _, mode_str, axes_str = button_name.replace('_button', '').split('_') + except ValueError: + LOG.error(f"Could not parse button name: {button_name}") return - - sender: QPushButton = self.sender() - btn_name = sender.objectName() - LOG.debug(f"fn: move_axis. sender:{btn_name}") - if "abs" in btn_name: - dest_x = self.fle_abs_x.value() - dest_y = self.fle_abs_y.value() - dest_z = self.fle_abs_z.value() - if "x" == btn_name[-1]: - self.move_wcs(MoveMode.ABS, x=dest_x) - return - if "y" == btn_name[-1]: - self.move_wcs(MoveMode.ABS, y=dest_y) - return - if "z" == btn_name[-1]: - self.move_wcs(MoveMode.ABS, z=dest_z) - return - self.move_wcs(MoveMode.ABS, dest_x, dest_y, dest_z) - LOG.debug(f"fn: move_wcs[ABS] x:{dest_x}, y:{dest_y}, z:{dest_z}") + move_configs = { + 'abs': (MoveMode.ABS, self.abs_x_input, self.abs_y_input, self.abs_z_input), + 'wcs': (MoveMode.WCS, self.wcs_x_input, self.wcs_y_input, self.wcs_z_input), + 'rel': (MoveMode.REL, self.rel_x_input, self.rel_y_input, self.rel_z_input) + } - if "wcs" in btn_name: - dest_x = self.fle_wcs_x.value() - dest_y = self.fle_wcs_y.value() - dest_z = self.fle_wcs_z.value() - if "x" == btn_name[-1]: - self.move_wcs(MoveMode.WCS, x=dest_x) - return - if "y" == btn_name[-1]: - self.move_wcs(MoveMode.WCS, y=dest_y) - return - if "z" == btn_name[-1]: - self.move_wcs(MoveMode.WCS, z=dest_z) - return - - self.move_wcs(MoveMode.WCS, dest_x, dest_y, dest_z) - LOG.debug(f"fn: move_wcs[WCS] x:{dest_x}, y:{dest_y}, z:{dest_z}") - - if "rel" in btn_name: - dest_x = self.fle_rel_x.value() - dest_y = self.fle_rel_y.value() - dest_z = self.fle_rel_z.value() - if "x" == btn_name[-1]: - self.move_wcs(MoveMode.REL, x=dest_x) - return - if "y" == btn_name[-1]: - self.move_wcs(MoveMode.REL, y=dest_y) - return - if "z" == btn_name[-1]: - self.move_wcs(MoveMode.REL, z=dest_z) - return - - self.move_wcs(MoveMode.REL, dest_x, dest_y, dest_z) - LOG.debug(f"fn: move_wcs[REL] x:{dest_x}, y:{dest_y}, z:{dest_z}") + if mode_str not in move_configs: + LOG.error(f"Unknown move mode '{mode_str}' in button name: {button_name}") + return + mode, x_input, y_input, z_input = move_configs[mode_str] - - def move_wcs(self, mode:MoveMode, x=None, y=None, z=None): + x, y, z = None, None, None + if 'x' in axes_str or 'all' in axes_str: + x = x_input.value() + if 'y' in axes_str or 'all' in axes_str: + y = y_input.value() + if 'z' in axes_str or 'all' in axes_str: + z = z_input.value() + + self._execute_move_command(mode, x, y, z) + LOG.debug(f"Executed move: {mode.name}, X={x}, Y={y}, Z={z}") + + def _execute_move_command(self, mode: MoveMode, x=None, y=None, z=None): + """Builds and sends an MDI command for the specified movement.""" + mdi_command = "" match mode: - case MoveMode.ABS: mdi_cmd = "G53 G0" - case MoveMode.WCS: mdi_cmd = "G0" - case MoveMode.REL: mdi_cmd = "G91 G0" + case MoveMode.ABS: + mdi_command = "G53 G0" + case MoveMode.WCS: + mdi_command = "G0" + case MoveMode.REL: + mdi_command = "G91 G0" if x is not None: - mdi_cmd += f" X{x}" + mdi_command += f" X{x}" if y is not None: - mdi_cmd += f" Y{y}" + mdi_command += f" Y{y}" if z is not None: - mdi_cmd += f" Z{z}" + mdi_command += f" Z{z}" if mode == MoveMode.REL: - mdi_cmd += " ;G90" - - LOG.debug(f"fn: move_wcs. MDI:{mdi_cmd}") - machine_actions.issue_mdi(mdi_cmd) + mdi_command += " ;G90" - def _machine_ready(self) -> bool: - LOG.debug(f"fn: machine_ready, on:{STATUS.on()}") - LOG.debug(f"fn: machine_ready, all_axes_homed:{STATUS.all_axes_homed()}") - return ( - STATUS.on() - and STATUS.all_axes_homed() - ) + LOG.debug(f"Sending MDI command: {mdi_command}") + machine_actions.issue_mdi(mdi_command) - def _update_controls(self, *args): - ready = self._machine_ready() - LOG.debug(f"Machine ready: {ready}") + def _is_machine_ready(self) -> bool: + """Checks if the machine is on and all axes are homed.""" + is_ready = STATUS.on() and STATUS.all_axes_homed() + LOG.debug(f"Machine ready check: on={STATUS.on()}, homed={STATUS.all_axes_homed()} -> {is_ready}") + return is_ready - for btn in self.buttons: - btn.setEnabled(ready) + def _update_control_states(self, *args): + """Enables or disables UI controls based on the machine's ready state.""" + is_ready = self._is_machine_ready() + LOG.debug(f"Updating control states. Machine ready: {is_ready}") - for fle in self.edits: - fle.setEnabled(ready) + for button in self.move_buttons: + button.setEnabled(is_ready) + for line_edit in self.position_inputs: + line_edit.setEnabled(is_ready) \ No newline at end of file diff --git a/configs/probe_basic/user_tabs/template_sidebar/template_sidebar.ui b/configs/probe_basic/user_tabs/template_sidebar/template_sidebar.ui index 4e5c564..fd7a3dd 100644 --- a/configs/probe_basic/user_tabs/template_sidebar/template_sidebar.ui +++ b/configs/probe_basic/user_tabs/template_sidebar/template_sidebar.ui @@ -1,7 +1,7 @@ - USER - + Move + 0 @@ -41,9 +41,9 @@ - + - 1.1234 + 0.0000 Qt::AlignCenter @@ -57,7 +57,7 @@ - + 50 @@ -83,7 +83,7 @@ - + 0.0000 @@ -96,7 +96,7 @@ - + 50 @@ -122,7 +122,7 @@ - + 0.0000 @@ -135,7 +135,7 @@ - + 0 @@ -165,7 +165,7 @@ - + GO XYZ @@ -192,7 +192,7 @@ - + QLabel{ color: rgb(238, 238, 236); @@ -207,7 +207,7 @@ - + 0.0000 @@ -223,7 +223,7 @@ - + 50 @@ -246,7 +246,7 @@ - + 0.0000 @@ -259,7 +259,7 @@ - + 50 @@ -282,7 +282,7 @@ - + 0.0000 @@ -295,7 +295,7 @@ - + 0 @@ -322,7 +322,7 @@ - + GO XYZ @@ -364,7 +364,7 @@ - + 0.0000 @@ -380,7 +380,7 @@ - + 50 @@ -403,7 +403,7 @@ - + 0.0000 @@ -416,7 +416,7 @@ - + 50 @@ -439,7 +439,7 @@ - + 0.0000 @@ -452,7 +452,7 @@ - + 0 @@ -479,7 +479,7 @@ - + GO XYZ