From d9e1a009cbab34486f37e80d6c4b6d7ea0ac15a5 Mon Sep 17 00:00:00 2001 From: Roberto Martins Date: Mon, 6 Apr 2026 08:48:47 +0100 Subject: [PATCH 01/13] ADD: added save variables emit --- BlocksScreen/lib/printer.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/BlocksScreen/lib/printer.py b/BlocksScreen/lib/printer.py index c6c76fbc..fd63e182 100644 --- a/BlocksScreen/lib/printer.py +++ b/BlocksScreen/lib/printer.py @@ -30,6 +30,8 @@ class Printer(QtCore.QObject): [str, float], [str, str], name="idle_timeout_update" ) + save_variables_update = QtCore.pyqtSignal(dict, name="save_variables_update") + gcode_move_update = QtCore.pyqtSignal( [str, list], [str, float], [str, bool], name="gcode_move_update" ) @@ -328,6 +330,11 @@ def _webhooks_object_updated(self, value: dict, name: str = "webhooks") -> None: e, ) + def _save_variables_object_updated( + self, value: dict, name: str = "saved_variables" + ) -> None: + self.save_variables_update.emit(value) + def _gcode_move_object_updated(self, value: dict, name: str = "gcode_move") -> None: if "speed_factor" in value.keys(): self.gcode_move_update[str, float].emit( From 691550ea7e26e9a44b7d9a37952367887de07fa7 Mon Sep 17 00:00:00 2001 From: Roberto Martins Date: Mon, 6 Apr 2026 09:25:31 +0100 Subject: [PATCH 02/13] Rev: removed filament name space --- BlocksScreen/lib/ui/filamentStackedWidget.ui | 119 ------------------ .../lib/ui/filamentStackedWidget_ui.py | 55 ++------ 2 files changed, 12 insertions(+), 162 deletions(-) diff --git a/BlocksScreen/lib/ui/filamentStackedWidget.ui b/BlocksScreen/lib/ui/filamentStackedWidget.ui index e9d359a6..710447d8 100644 --- a/BlocksScreen/lib/ui/filamentStackedWidget.ui +++ b/BlocksScreen/lib/ui/filamentStackedWidget.ui @@ -137,125 +137,6 @@ - - - - - 0 - 0 - - - - - 600 - 80 - - - - - 600 - 80 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 20 - 20 - 201 - 41 - - - - - 0 - 0 - - - - - 280 - 60 - - - - - 15 - - - - background: transparent; color:white ; - - - Filament Name - - - Qt::AlignCenter - - - Qt::NoTextInteraction - - - - - - 260 - 10 - 321 - 60 - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - color:white - - - ... - - - Qt::AlignCenter - - - - - - 240 - 10 - 3 - 61 - - - - color:white - - - Qt::Vertical - - - - diff --git a/BlocksScreen/lib/ui/filamentStackedWidget_ui.py b/BlocksScreen/lib/ui/filamentStackedWidget_ui.py index bd545139..1e90b0b3 100644 --- a/BlocksScreen/lib/ui/filamentStackedWidget_ui.py +++ b/BlocksScreen/lib/ui/filamentStackedWidget_ui.py @@ -1,6 +1,6 @@ -# Form implementation generated from reading ui file '/home/levi/main/Blocks_Screen/BlocksScreen/lib/ui/filamentStackedWidget.ui' +# Form implementation generated from reading ui file 'BlocksScreen/lib/ui/filamentStackedWidget.ui' # -# Created by: PyQt6 UI code generator 6.7.1 +# Created by: PyQt6 UI code generator 6.10.0 # # WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. @@ -60,45 +60,6 @@ def setupUi(self, filamentStackedWidget): self.verticalLayout_4.setObjectName("verticalLayout_4") self.verticalLayout_3 = QtWidgets.QVBoxLayout() self.verticalLayout_3.setObjectName("verticalLayout_3") - self.frame_8 = BlocksCustomFrame(parent=self.filament_control_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.frame_8.sizePolicy().hasHeightForWidth()) - self.frame_8.setSizePolicy(sizePolicy) - self.frame_8.setMinimumSize(QtCore.QSize(600, 80)) - self.frame_8.setMaximumSize(QtCore.QSize(600, 80)) - self.frame_8.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) - self.frame_8.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) - self.frame_8.setObjectName("frame_8") - self.filament_page_info_content_6 = QtWidgets.QLabel(parent=self.frame_8) - self.filament_page_info_content_6.setGeometry(QtCore.QRect(20, 20, 201, 41)) - self.filament_page_info_content_6.setMinimumSize(QtCore.QSize(0, 0)) - self.filament_page_info_content_6.setMaximumSize(QtCore.QSize(280, 60)) - font = QtGui.QFont() - font.setPointSize(15) - self.filament_page_info_content_6.setFont(font) - self.filament_page_info_content_6.setStyleSheet("background: transparent; color:white ;") - self.filament_page_info_content_6.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.filament_page_info_content_6.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.NoTextInteraction) - self.filament_page_info_content_6.setObjectName("filament_page_info_content_6") - self.label = QtWidgets.QLabel(parent=self.frame_8) - self.label.setGeometry(QtCore.QRect(260, 10, 321, 60)) - self.label.setMinimumSize(QtCore.QSize(0, 60)) - self.label.setMaximumSize(QtCore.QSize(16777215, 60)) - font = QtGui.QFont() - font.setPointSize(13) - self.label.setFont(font) - self.label.setStyleSheet("color:white") - self.label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.label.setObjectName("label") - self.line = QtWidgets.QFrame(parent=self.frame_8) - self.line.setGeometry(QtCore.QRect(240, 10, 3, 61)) - self.line.setStyleSheet("color:white") - self.line.setFrameShape(QtWidgets.QFrame.Shape.VLine) - self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) - self.line.setObjectName("line") - self.verticalLayout_3.addWidget(self.frame_8, 0, QtCore.Qt.AlignmentFlag.AlignHCenter) spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) self.verticalLayout_3.addItem(spacerItem2) self.frame_7 = BlocksCustomFrame(parent=self.filament_control_page) @@ -587,8 +548,6 @@ def retranslateUi(self, filamentStackedWidget): filamentStackedWidget.setWindowTitle(_translate("filamentStackedWidget", "StackedWidget")) self.filament_page_header_title.setText(_translate("filamentStackedWidget", "Filament Control")) self.filament_page_header_title.setProperty("class", _translate("filamentStackedWidget", "title_text")) - self.filament_page_info_content_6.setText(_translate("filamentStackedWidget", "Filament Name")) - self.label.setText(_translate("filamentStackedWidget", "...")) self.filament_page_info_title_6.setText(_translate("filamentStackedWidget", "Loaded Filament Type")) self.label_2.setText(_translate("filamentStackedWidget", "...")) self.filament_page_load_btn.setText(_translate("filamentStackedWidget", "Load")) @@ -638,3 +597,13 @@ def retranslateUi(self, filamentStackedWidget): from lib.utils.blocks_button import BlocksCustomButton from lib.utils.blocks_frame import BlocksCustomFrame from lib.utils.icon_button import IconButton + + +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + filamentStackedWidget = QtWidgets.QStackedWidget() + ui = Ui_filamentStackedWidget() + ui.setupUi(filamentStackedWidget) + filamentStackedWidget.show() + sys.exit(app.exec()) From 73751f3a81a9577caa8773bede37dc9aac86ef19 Mon Sep 17 00:00:00 2001 From: Roberto Martins Date: Mon, 6 Apr 2026 11:16:01 +0100 Subject: [PATCH 03/13] ADD: write/read filament type --- BlocksScreen/lib/panels/filamentTab.py | 65 +++++++++++++++++++------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index 04fc5ef4..2bb877f3 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -10,6 +10,16 @@ from PyQt6 import QtCore, QtGui, QtWidgets +class FilamentTypes(enum.Enum): + PLA = Filament(name="PLA", temperature=220) + PETG = Filament(name="PETG", temperature=240) + ABS = Filament(name="ABS", temperature=250) + HIPS = Filament(name="HIPS", temperature=250) + NYLON = Filament(name="NYLON", temperature=270) + TPU = Filament(name="TPU", temperature=230) + UNKNOWN = Filament(name="UNKNOWN", temperature=250) + + class FilamentTab(QtWidgets.QStackedWidget): request_filament_change_page = QtCore.pyqtSignal(name="filament_change_page") request_filament_load = QtCore.pyqtSignal(name="filament_load_t1") @@ -19,9 +29,6 @@ class FilamentTab(QtWidgets.QStackedWidget): run_gcode = QtCore.pyqtSignal(str, name="run_gcode") call_load_panel = QtCore.pyqtSignal(bool, str, name="call-load-panel") - class FilamentTypes(enum.Enum): - PLA = Filament(name="PLA", temperature=220) - class FilamentStates(enum.Enum): LOADED = enum.auto() UNLOADED = enum.auto() @@ -44,7 +51,7 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self.has_load_unload_objects = None self._filament_state = self.FilamentStates.UNKNOWN self._sensor_states = {} - self.filament_type: Filament | None = None + self.filament_type = FilamentTypes.UNKNOWN self.panel.filament_page_load_btn.clicked.connect( partial(self.change_page, self.indexOf(self.panel.load_page)) ) @@ -52,22 +59,22 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self.panel.load_custom_btn.hide() self.panel.load_header_back_button.clicked.connect(self.back_button) self.panel.load_pla_btn.clicked.connect( - partial(self.load_filament, toolhead=0, temp=220) + partial(self.load_filament, toolhead=0, filament=FilamentTypes.PLA) ) self.panel.load_petg_btn.clicked.connect( - partial(self.load_filament, toolhead=0, temp=240) + partial(self.load_filament, toolhead=0, filament=FilamentTypes.PETG) ) self.panel.load_abs_btn.clicked.connect( - partial(self.load_filament, toolhead=0, temp=250) + partial(self.load_filament, toolhead=0, filament=FilamentTypes.ABS) ) self.panel.load_hips_btn.clicked.connect( - partial(self.load_filament, toolhead=0, temp=250) + partial(self.load_filament, toolhead=0, filament=FilamentTypes.HIPS) ) self.panel.load_nylon_btn.clicked.connect( - partial(self.load_filament, toolhead=0, temp=270) + partial(self.load_filament, toolhead=0, filament=FilamentTypes.NYLON) ) self.panel.load_tpu_btn.clicked.connect( - partial(self.load_filament, toolhead=0, temp=230) + partial(self.load_filament, toolhead=0, filament=FilamentTypes.TPU) ) self.panel.filament_page_unload_btn.clicked.connect( lambda: self.unload_filament(toolhead=0, temp=250) @@ -87,6 +94,18 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self.loadignore = True self.unloadignore = True + self.printer.save_variables_update.connect(self.on_save_variables_update) + + def on_save_variables_update(self, save_variables: dict): + """Handle query response""" + for i in FilamentTypes: + if i.value.name in save_variables["variables"]["filament_type"]: + self.filament_type = i + break + else: + self.filament_type = FilamentTypes.UNKNOWN + self.panel.label_2.setText(self.filament_type.value.name) + @QtCore.pyqtSlot(str, dict, name="on_print_stats_update") @QtCore.pyqtSlot(str, float, name="on_print_stats_update") @QtCore.pyqtSlot(str, str, name="on_print_stats_update") @@ -177,7 +196,9 @@ def on_unload_filament(self, status: bool): self.handle_filament_state() @QtCore.pyqtSlot(int, int, name="load_filament") - def load_filament(self, toolhead: int = 0, temp: int = 220) -> None: + def load_filament( + self, toolhead: int = 0, filament: FilamentTypes = FilamentTypes.UNKNOWN + ) -> None: """Handle load filament buttons clicked""" if not self.isVisible: return @@ -196,7 +217,12 @@ def load_filament(self, toolhead: int = 0, temp: int = 220) -> None: return self.loadignore = False self.call_load_panel.emit(True, "Loading Filament") - self.run_gcode.emit(f"LOAD_FILAMENT TOOLHEAD=load_toolhead TEMPERATURE={temp}") + self.run_gcode.emit( + f"""SAVE_VARIABLE VARIABLE=filament_type VALUE='"{filament.value.name}"'""" + ) + self.run_gcode.emit( + f"LOAD_FILAMENT TOOLHEAD=load_toolhead TEMPERATURE={filament.value.temperature}" + ) @QtCore.pyqtSlot(str, int, name="unload_filament") def unload_filament(self, toolhead: int = 0, temp: int = 220) -> None: @@ -220,19 +246,22 @@ def unload_filament(self, toolhead: int = 0, temp: int = 220) -> None: self.find_routine_objects() self.unloadignore = False self.call_load_panel.emit(True, "Unloading Filament") + self.run_gcode.emit( + f"""SAVE_VARIABLE VARIABLE=filament_type VALUE='"{FilamentTypes.UNKNOWN.value.name}"'""" + ) self.run_gcode.emit(f"UNLOAD_FILAMENT TEMPERATURE={temp}") def handle_filament_state(self): """Handle ui changes on filament states""" if self._filament_state == self.FilamentStates.LOADED: - self.panel.filament_page_load_btn.setDisabled(True) - self.panel.filament_page_load_btn.setDisabled(False) + self.panel.filament_page_unload_btn.setEnabled(True) + self.panel.filament_page_load_btn.setEnabled(False) elif self._filament_state == self.FilamentStates.UNLOADED: - self.panel.filament_page_unload_btn.setDisabled(True) - self.panel.filament_page_unload_btn.setDisabled(False) + self.panel.filament_page_unload_btn.setEnabled(False) + self.panel.filament_page_load_btn.setEnabled(True) else: - self.panel.filament_page_load_btn.setDisabled(False) - self.panel.filament_page_unload_btn.setDisabled(False) + self.panel.filament_page_load_btn.setEnabled(True) + self.panel.filament_page_unload_btn.setEnabled(True) @property def filament_state(self): From 68ff23f87a20c7a724fceb72b2b88c47b1f01664 Mon Sep 17 00:00:00 2001 From: Roberto Martins Date: Tue, 7 Apr 2026 17:32:09 +0100 Subject: [PATCH 04/13] ADD: being able to change to filament tab --- BlocksScreen/lib/panels/filamentTab.py | 7 ++ BlocksScreen/lib/panels/mainWindow.py | 18 ++-- BlocksScreen/lib/panels/printTab.py | 7 +- BlocksScreen/lib/ui/filamentStackedWidget.ui | 83 ++++++++++++++++++- .../lib/ui/filamentStackedWidget_ui.py | 67 ++++++++++----- 5 files changed, 148 insertions(+), 34 deletions(-) diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index 2bb877f3..34da421a 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -79,6 +79,7 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self.panel.filament_page_unload_btn.clicked.connect( lambda: self.unload_filament(toolhead=0, temp=250) ) + self.panel.load_header_back_button_2.clicked.connect(self.back_button) self.run_gcode.connect(self.ws.api.run_gcode) self.printer.extruder_update.connect(self.on_extruder_update) self.printer.unload_filament_update.connect(self.on_unload_filament) @@ -113,9 +114,15 @@ def on_print_stats_update(self, field: str, value: dict | float | str) -> None: """Handle print stats object update""" if isinstance(value, str): if "state" in field: + if value in ("printing", "pausing", "paused", "resuming"): + self.panel.load_header_back_button_2.show() + self.panel.spacerItem1.changeSize(60, 0, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) if value in ("standby"): self.loadignore = True self.unloadignore = True + self.panel.load_header_back_button_2.hide() + self.panel.spacerItem1.changeSize(0, 0, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) + @QtCore.pyqtSlot(str, str, bool, name="on_filament_sensor_update") def on_filament_sensor_update(self, sensor_name: str, parameter: str, value: bool): diff --git a/BlocksScreen/lib/panels/mainWindow.py b/BlocksScreen/lib/panels/mainWindow.py index 12fbc628..9e8ef59d 100644 --- a/BlocksScreen/lib/panels/mainWindow.py +++ b/BlocksScreen/lib/panels/mainWindow.py @@ -268,6 +268,8 @@ def __init__(self): self.file_data.fileinfo.connect(self.cancelpage._show_screen_thumbnail) self.printPanel.call_cancel_panel.connect(self.handle_cancel_print) + self.print_status = "idle" + if self.config.has_section("server"): self.bo_ws_startup.emit() self.reset_tab_indexes() @@ -366,9 +368,6 @@ def enable_tab_bar(self) -> bool: bool: True if the TabBar was disabled """ - self.ui.main_content_widget.setTabEnabled( - self.ui.main_content_widget.indexOf(self.ui.filamentTab), True - ) self.ui.main_content_widget.setTabEnabled( self.ui.main_content_widget.indexOf(self.ui.controlTab), True ) @@ -378,9 +377,6 @@ def enable_tab_bar(self) -> bool: self.ui.header_main_layout.setEnabled(True) return all( [ - not self.ui.main_content_widget.isTabEnabled( - self.ui.main_content_widget.indexOf(self.ui.filamentTab) - ), not self.ui.main_content_widget.isTabEnabled( self.ui.main_content_widget.indexOf(self.ui.controlTab) ), @@ -402,9 +398,6 @@ def disable_tab_bar(self) -> bool: Returns: boolean: True if the TabBar was disabled """ - self.ui.main_content_widget.setTabEnabled( - self.ui.main_content_widget.indexOf(self.ui.filamentTab), False - ) self.ui.main_content_widget.setTabEnabled( self.ui.main_content_widget.indexOf(self.ui.controlTab), False ) @@ -414,9 +407,6 @@ def disable_tab_bar(self) -> bool: self.ui.header_main_layout.setEnabled(False) return all( [ - not self.ui.main_content_widget.isTabEnabled( - self.ui.main_content_widget.indexOf(self.ui.filamentTab) - ), not self.ui.main_content_widget.isTabEnabled( self.ui.main_content_widget.indexOf(self.ui.controlTab) ), @@ -437,6 +427,8 @@ def reset_tab_indexes(self): Used to grantee all tabs reset to their first page once the user leaves the tab """ + if self.print_status == "printing": + return self.update_page.hide() self.printPanel.setCurrentIndex(0) self.filamentPanel.setCurrentIndex(0) @@ -825,6 +817,7 @@ def event(self, event: QtCore.QEvent) -> bool: return True return False if event.type() == events.PrintStart.type(): + self.print_status = "printing" self.disable_tab_bar() self.ui.extruder_temp_display.clicked.disconnect() self.ui.bed_temp_display.clicked.disconnect() @@ -849,6 +842,7 @@ def event(self, event: QtCore.QEvent) -> bool: events.PrintComplete.type(), events.PrintCancelled.type(), ): + self.print_status = "idle" if event.type() == events.PrintCancelled.type(): self.handle_cancel_print() self.enable_tab_bar() diff --git a/BlocksScreen/lib/panels/printTab.py b/BlocksScreen/lib/panels/printTab.py index 3f53c91a..edb732a5 100644 --- a/BlocksScreen/lib/panels/printTab.py +++ b/BlocksScreen/lib/panels/printTab.py @@ -201,6 +201,9 @@ def __init__( self.addWidget(self.babystepPage) self.tune_page = TuneWidget(self) self.addWidget(self.tune_page) + self.tune_page.tune_change_filament_btn.clicked.connect( + lambda: self.change_page(0,1) + ) self.jobStatusPage_widget.tune_clicked.connect( lambda: self.change_page(self.indexOf(self.tune_page)) ) @@ -404,13 +407,13 @@ def handle_cancel_print(self) -> None: self.ws.api.cancel_print() self.call_load_panel.emit(True, "Cancelling print...\nPlease wait") - def change_page(self, index: int) -> None: + def change_page(self, index: int , tab: int = 0) -> None: """Requests a page change page to the global manager Args: index (int): page index """ - self.request_change_page.emit(0, index) + self.request_change_page.emit(tab, index) @QtCore.pyqtSlot(name="request-back") def back_button(self) -> None: diff --git a/BlocksScreen/lib/ui/filamentStackedWidget.ui b/BlocksScreen/lib/ui/filamentStackedWidget.ui index 710447d8..b5afc5bc 100644 --- a/BlocksScreen/lib/ui/filamentStackedWidget.ui +++ b/BlocksScreen/lib/ui/filamentStackedWidget.ui @@ -75,10 +75,26 @@ + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 60 + 0 + + + + - + 0 0 @@ -118,6 +134,69 @@ + + + + + 0 + 0 + + + + + 60 + 60 + + + + + 60 + 60 + + + + + Momcake + 20 + false + PreferAntialias + + + + false + + + true + + + Qt::NoContextMenu + + + Qt::LeftToRight + + + + + + Back + + + false + + + true + + + menu_btn + + + icon + + + :/ui/media/btn_icons/back.svg + + + @@ -1505,6 +1584,8 @@ Filament + + diff --git a/BlocksScreen/lib/ui/filamentStackedWidget_ui.py b/BlocksScreen/lib/ui/filamentStackedWidget_ui.py index 1e90b0b3..4cecb934 100644 --- a/BlocksScreen/lib/ui/filamentStackedWidget_ui.py +++ b/BlocksScreen/lib/ui/filamentStackedWidget_ui.py @@ -1,4 +1,4 @@ -# Form implementation generated from reading ui file 'BlocksScreen/lib/ui/filamentStackedWidget.ui' +# Form implementation generated from reading ui file 'filamentStackedWidget.ui' # # Created by: PyQt6 UI code generator 6.10.0 # @@ -36,8 +36,10 @@ def setupUi(self, filamentStackedWidget): self.verticalLayout.addItem(spacerItem) self.filament_page_header_layout = QtWidgets.QHBoxLayout() self.filament_page_header_layout.setObjectName("filament_page_header_layout") + self.spacerItem1 = QtWidgets.QSpacerItem(60, 0, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) + self.filament_page_header_layout.addItem(self.spacerItem1) self.filament_page_header_title = QtWidgets.QLabel(parent=self.filament_control_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.filament_page_header_title.sizePolicy().hasHeightForWidth()) @@ -53,15 +55,39 @@ def setupUi(self, filamentStackedWidget): self.filament_page_header_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.filament_page_header_title.setObjectName("filament_page_header_title") self.filament_page_header_layout.addWidget(self.filament_page_header_title, 0, QtCore.Qt.AlignmentFlag.AlignHCenter|QtCore.Qt.AlignmentFlag.AlignVCenter) + self.load_header_back_button_2 = IconButton(parent=self.filament_control_page) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.load_header_back_button_2.sizePolicy().hasHeightForWidth()) + self.load_header_back_button_2.setSizePolicy(sizePolicy) + self.load_header_back_button_2.setMinimumSize(QtCore.QSize(60, 60)) + self.load_header_back_button_2.setMaximumSize(QtCore.QSize(60, 60)) + font = QtGui.QFont() + font.setFamily("Momcake") + font.setPointSize(20) + font.setItalic(False) + font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) + self.load_header_back_button_2.setFont(font) + self.load_header_back_button_2.setMouseTracking(False) + self.load_header_back_button_2.setTabletTracking(True) + self.load_header_back_button_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.load_header_back_button_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.load_header_back_button_2.setStyleSheet("") + self.load_header_back_button_2.setAutoDefault(False) + self.load_header_back_button_2.setFlat(True) + self.load_header_back_button_2.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) + self.load_header_back_button_2.setObjectName("load_header_back_button_2") + self.filament_page_header_layout.addWidget(self.load_header_back_button_2) self.verticalLayout.addLayout(self.filament_page_header_layout) - spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout.addItem(spacerItem1) + spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout.addItem(spacerItem2) self.verticalLayout_4 = QtWidgets.QVBoxLayout() self.verticalLayout_4.setObjectName("verticalLayout_4") self.verticalLayout_3 = QtWidgets.QVBoxLayout() self.verticalLayout_3.setObjectName("verticalLayout_3") - spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout_3.addItem(spacerItem2) + spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_3.addItem(spacerItem3) self.frame_7 = BlocksCustomFrame(parent=self.filament_control_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(0) @@ -99,8 +125,8 @@ def setupUi(self, filamentStackedWidget): self.line_2.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) self.line_2.setObjectName("line_2") self.verticalLayout_3.addWidget(self.frame_7, 0, QtCore.Qt.AlignmentFlag.AlignHCenter) - spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout_3.addItem(spacerItem3) + spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_3.addItem(spacerItem4) self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.filament_page_load_btn = BlocksCustomButton(parent=self.filament_control_page) @@ -154,10 +180,10 @@ def setupUi(self, filamentStackedWidget): self.verticalLayout_3.addLayout(self.horizontalLayout) self.verticalLayout_4.addLayout(self.verticalLayout_3) self.verticalLayout.addLayout(self.verticalLayout_4) - spacerItem4 = QtWidgets.QSpacerItem(20, 26, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout.addItem(spacerItem4) - spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + spacerItem5 = QtWidgets.QSpacerItem(20, 26, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) self.verticalLayout.addItem(spacerItem5) + spacerItem6 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout.addItem(spacerItem6) filamentStackedWidget.addWidget(self.filament_control_page) self.load_page = QtWidgets.QWidget() sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) @@ -171,12 +197,12 @@ def setupUi(self, filamentStackedWidget): self.load_page.setObjectName("load_page") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.load_page) self.verticalLayout_2.setObjectName("verticalLayout_2") - spacerItem6 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_2.addItem(spacerItem6) + spacerItem7 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) + self.verticalLayout_2.addItem(spacerItem7) self.load_page_header_layout = QtWidgets.QHBoxLayout() self.load_page_header_layout.setObjectName("load_page_header_layout") - spacerItem7 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Maximum, QtWidgets.QSizePolicy.Policy.Minimum) - self.load_page_header_layout.addItem(spacerItem7) + spacerItem8 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Maximum, QtWidgets.QSizePolicy.Policy.Minimum) + self.load_page_header_layout.addItem(spacerItem8) self.load_header_page_title = QtWidgets.QLabel(parent=self.load_page) self.load_header_page_title.setMinimumSize(QtCore.QSize(0, 60)) font = QtGui.QFont() @@ -212,8 +238,8 @@ def setupUi(self, filamentStackedWidget): self.load_header_back_button.setObjectName("load_header_back_button") self.load_page_header_layout.addWidget(self.load_header_back_button) self.verticalLayout_2.addLayout(self.load_page_header_layout) - spacerItem8 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout_2.addItem(spacerItem8) + spacerItem9 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem9) self.load_page_content_layout = QtWidgets.QGridLayout() self.load_page_content_layout.setContentsMargins(5, 5, 5, 5) self.load_page_content_layout.setHorizontalSpacing(6) @@ -389,8 +415,8 @@ def setupUi(self, filamentStackedWidget): self.load_custom_btn.setObjectName("load_custom_btn") self.load_page_footer_layout.addWidget(self.load_custom_btn) self.verticalLayout_2.addLayout(self.load_page_footer_layout) - spacerItem9 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.verticalLayout_2.addItem(spacerItem9) + spacerItem10 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout_2.addItem(spacerItem10) filamentStackedWidget.addWidget(self.load_page) self.custom_filament_page = QtWidgets.QWidget() self.custom_filament_page.setMinimumSize(QtCore.QSize(710, 400)) @@ -548,6 +574,9 @@ def retranslateUi(self, filamentStackedWidget): filamentStackedWidget.setWindowTitle(_translate("filamentStackedWidget", "StackedWidget")) self.filament_page_header_title.setText(_translate("filamentStackedWidget", "Filament Control")) self.filament_page_header_title.setProperty("class", _translate("filamentStackedWidget", "title_text")) + self.load_header_back_button_2.setText(_translate("filamentStackedWidget", "Back")) + self.load_header_back_button_2.setProperty("class", _translate("filamentStackedWidget", "menu_btn")) + self.load_header_back_button_2.setProperty("button_type", _translate("filamentStackedWidget", "icon")) self.filament_page_info_title_6.setText(_translate("filamentStackedWidget", "Loaded Filament Type")) self.label_2.setText(_translate("filamentStackedWidget", "...")) self.filament_page_load_btn.setText(_translate("filamentStackedWidget", "Load")) From 892d2e5ed2311ac6bfadeaf0939e74f92e674cec Mon Sep 17 00:00:00 2001 From: Roberto Martins Date: Thu, 9 Apr 2026 16:54:18 +0100 Subject: [PATCH 05/13] bugfix: changing page mid print --- BlocksScreen/lib/panels/filamentTab.py | 24 +++++++++--- BlocksScreen/lib/panels/mainWindow.py | 19 ++++++++++ BlocksScreen/lib/panels/printTab.py | 10 +++-- BlocksScreen/lib/ui/filamentStackedWidget.ui | 2 +- .../lib/ui/filamentStackedWidget_ui.py | 38 +++++++++---------- 5 files changed, 64 insertions(+), 29 deletions(-) diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index 34da421a..76e2c235 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -25,6 +25,7 @@ class FilamentTab(QtWidgets.QStackedWidget): request_filament_load = QtCore.pyqtSignal(name="filament_load_t1") request_back = QtCore.pyqtSignal(name="request_back") request_change_page = QtCore.pyqtSignal(int, int, name="request_change_page") + request_change_tab = QtCore.pyqtSignal(int, name="request_change_tab") request_toolhead_count = QtCore.pyqtSignal(int, name="toolhead_number_received") run_gcode = QtCore.pyqtSignal(str, name="run_gcode") call_load_panel = QtCore.pyqtSignal(bool, str, name="call-load-panel") @@ -79,7 +80,9 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self.panel.filament_page_unload_btn.clicked.connect( lambda: self.unload_filament(toolhead=0, temp=250) ) - self.panel.load_header_back_button_2.clicked.connect(self.back_button) + self.panel.main_back_button.clicked.connect( + lambda: self.request_change_tab.emit(0) + ) self.run_gcode.connect(self.ws.api.run_gcode) self.printer.extruder_update.connect(self.on_extruder_update) self.printer.unload_filament_update.connect(self.on_unload_filament) @@ -115,14 +118,23 @@ def on_print_stats_update(self, field: str, value: dict | float | str) -> None: if isinstance(value, str): if "state" in field: if value in ("printing", "pausing", "paused", "resuming"): - self.panel.load_header_back_button_2.show() - self.panel.spacerItem1.changeSize(60, 0, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) + self.panel.main_back_button.show() + self.panel.spacerItem1.changeSize( + 60, + 0, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) if value in ("standby"): self.loadignore = True self.unloadignore = True - self.panel.load_header_back_button_2.hide() - self.panel.spacerItem1.changeSize(0, 0, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - + self.panel.main_back_button.hide() + self.panel.spacerItem1.changeSize( + 0, + 0, + QtWidgets.QSizePolicy.Policy.Minimum, + QtWidgets.QSizePolicy.Policy.Minimum, + ) @QtCore.pyqtSlot(str, str, bool, name="on_filament_sensor_update") def on_filament_sensor_update(self, sensor_name: str, parameter: str, value: bool): diff --git a/BlocksScreen/lib/panels/mainWindow.py b/BlocksScreen/lib/panels/mainWindow.py index 9e8ef59d..c76ac90d 100644 --- a/BlocksScreen/lib/panels/mainWindow.py +++ b/BlocksScreen/lib/panels/mainWindow.py @@ -247,6 +247,9 @@ def __init__(self): self.utilitiesPanel.call_load_panel.connect(self.show_LoadScreen) self.conn_window.call_load_panel.connect(self.show_LoadScreen) + self.filamentPanel.request_change_tab.connect(self.global_change_tab) + self.printPanel.request_change_tab.connect(self.global_change_tab) + self.loadscreen = BasePopup(self, floating=False, dialog=False) self.loadwidget = LoadingOverlayWidget( self, LoadingOverlayWidget.AnimationGIF.DEFAULT @@ -511,6 +514,22 @@ def global_change_page(self, tab_index: int, panel_index: int) -> None: f"Requested page change -> Tab index : {requested_page[0]} | panel index : {requested_page[1]}", ) + def global_change_tab(self, tab_index: int) -> None: + """Changes the current tab while keeping the current panel page index if possible + + Args: + tab_index (int): The index of the tab to change to + """ + if not isinstance(tab_index, int): + _logger.debug( + "Tab index argument expected type int, got %s", str(type(tab_index)) + ) + return + self.ui.main_content_widget.setCurrentIndex(tab_index) + _logger.debug( + f"Requested tab change -> Tab index : {tab_index}", + ) + @QtCore.pyqtSlot(name="request-back") def global_back(self) -> None: """Requests to go back a page globally""" diff --git a/BlocksScreen/lib/panels/printTab.py b/BlocksScreen/lib/panels/printTab.py index edb732a5..90b7ee09 100644 --- a/BlocksScreen/lib/panels/printTab.py +++ b/BlocksScreen/lib/panels/printTab.py @@ -56,6 +56,10 @@ class PrintTab(QtWidgets.QStackedWidget): int, int, name="request_change_page" ) + request_change_tab: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + int, name="request_change_tab" + ) + run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( str, name="run_gcode" ) @@ -202,7 +206,7 @@ def __init__( self.tune_page = TuneWidget(self) self.addWidget(self.tune_page) self.tune_page.tune_change_filament_btn.clicked.connect( - lambda: self.change_page(0,1) + lambda: self.request_change_tab.emit(1) ) self.jobStatusPage_widget.tune_clicked.connect( lambda: self.change_page(self.indexOf(self.tune_page)) @@ -407,13 +411,13 @@ def handle_cancel_print(self) -> None: self.ws.api.cancel_print() self.call_load_panel.emit(True, "Cancelling print...\nPlease wait") - def change_page(self, index: int , tab: int = 0) -> None: + def change_page(self, index: int) -> None: """Requests a page change page to the global manager Args: index (int): page index """ - self.request_change_page.emit(tab, index) + self.request_change_page.emit(0, index) @QtCore.pyqtSlot(name="request-back") def back_button(self) -> None: diff --git a/BlocksScreen/lib/ui/filamentStackedWidget.ui b/BlocksScreen/lib/ui/filamentStackedWidget.ui index b5afc5bc..c418ca80 100644 --- a/BlocksScreen/lib/ui/filamentStackedWidget.ui +++ b/BlocksScreen/lib/ui/filamentStackedWidget.ui @@ -135,7 +135,7 @@ - + 0 diff --git a/BlocksScreen/lib/ui/filamentStackedWidget_ui.py b/BlocksScreen/lib/ui/filamentStackedWidget_ui.py index 4cecb934..8ec597b2 100644 --- a/BlocksScreen/lib/ui/filamentStackedWidget_ui.py +++ b/BlocksScreen/lib/ui/filamentStackedWidget_ui.py @@ -55,30 +55,30 @@ def setupUi(self, filamentStackedWidget): self.filament_page_header_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.filament_page_header_title.setObjectName("filament_page_header_title") self.filament_page_header_layout.addWidget(self.filament_page_header_title, 0, QtCore.Qt.AlignmentFlag.AlignHCenter|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.load_header_back_button_2 = IconButton(parent=self.filament_control_page) + self.main_back_button = IconButton(parent=self.filament_control_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.load_header_back_button_2.sizePolicy().hasHeightForWidth()) - self.load_header_back_button_2.setSizePolicy(sizePolicy) - self.load_header_back_button_2.setMinimumSize(QtCore.QSize(60, 60)) - self.load_header_back_button_2.setMaximumSize(QtCore.QSize(60, 60)) + sizePolicy.setHeightForWidth(self.main_back_button.sizePolicy().hasHeightForWidth()) + self.main_back_button.setSizePolicy(sizePolicy) + self.main_back_button.setMinimumSize(QtCore.QSize(60, 60)) + self.main_back_button.setMaximumSize(QtCore.QSize(60, 60)) font = QtGui.QFont() font.setFamily("Momcake") font.setPointSize(20) font.setItalic(False) font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.load_header_back_button_2.setFont(font) - self.load_header_back_button_2.setMouseTracking(False) - self.load_header_back_button_2.setTabletTracking(True) - self.load_header_back_button_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.load_header_back_button_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.load_header_back_button_2.setStyleSheet("") - self.load_header_back_button_2.setAutoDefault(False) - self.load_header_back_button_2.setFlat(True) - self.load_header_back_button_2.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) - self.load_header_back_button_2.setObjectName("load_header_back_button_2") - self.filament_page_header_layout.addWidget(self.load_header_back_button_2) + self.main_back_button.setFont(font) + self.main_back_button.setMouseTracking(False) + self.main_back_button.setTabletTracking(True) + self.main_back_button.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.main_back_button.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.main_back_button.setStyleSheet("") + self.main_back_button.setAutoDefault(False) + self.main_back_button.setFlat(True) + self.main_back_button.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) + self.main_back_button.setObjectName("main_back_button") + self.filament_page_header_layout.addWidget(self.main_back_button) self.verticalLayout.addLayout(self.filament_page_header_layout) spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) self.verticalLayout.addItem(spacerItem2) @@ -574,9 +574,9 @@ def retranslateUi(self, filamentStackedWidget): filamentStackedWidget.setWindowTitle(_translate("filamentStackedWidget", "StackedWidget")) self.filament_page_header_title.setText(_translate("filamentStackedWidget", "Filament Control")) self.filament_page_header_title.setProperty("class", _translate("filamentStackedWidget", "title_text")) - self.load_header_back_button_2.setText(_translate("filamentStackedWidget", "Back")) - self.load_header_back_button_2.setProperty("class", _translate("filamentStackedWidget", "menu_btn")) - self.load_header_back_button_2.setProperty("button_type", _translate("filamentStackedWidget", "icon")) + self.main_back_button.setText(_translate("filamentStackedWidget", "Back")) + self.main_back_button.setProperty("class", _translate("filamentStackedWidget", "menu_btn")) + self.main_back_button.setProperty("button_type", _translate("filamentStackedWidget", "icon")) self.filament_page_info_title_6.setText(_translate("filamentStackedWidget", "Loaded Filament Type")) self.label_2.setText(_translate("filamentStackedWidget", "...")) self.filament_page_load_btn.setText(_translate("filamentStackedWidget", "Load")) From 61988f75c818cf54bc567ec10d34a5f4637b6fb8 Mon Sep 17 00:00:00 2001 From: Roberto Martins Date: Fri, 10 Apr 2026 10:12:13 +0100 Subject: [PATCH 06/13] bugfix: wrong filament state --- BlocksScreen.cfg | 4 ++++ BlocksScreen/lib/panels/filamentTab.py | 31 +++++++++++++++----------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/BlocksScreen.cfg b/BlocksScreen.cfg index 42ab150b..065a900b 100644 --- a/BlocksScreen.cfg +++ b/BlocksScreen.cfg @@ -7,3 +7,7 @@ timeout: 5000 [usb_manager] gcodes_dir: ~/printer_data/gcodes/ + +[filament_presence] +object: cutter_sensor +name: extruder_cutter \ No newline at end of file diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index 76e2c235..96920ef6 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -1,14 +1,16 @@ import enum from functools import partial - +import logging from lib.printer import Printer from lib.filament import Filament from lib.ui.filamentStackedWidget_ui import Ui_filamentStackedWidget - +from configfile import get_configparser from lib.panels.widgets.popupDialogWidget import Popup from PyQt6 import QtCore, QtGui, QtWidgets +logger = logging.getLogger(__name__) + class FilamentTypes(enum.Enum): PLA = Filament(name="PLA", temperature=220) @@ -51,8 +53,14 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self.popup = Popup(self) self.has_load_unload_objects = None self._filament_state = self.FilamentStates.UNKNOWN - self._sensor_states = {} self.filament_type = FilamentTypes.UNKNOWN + + cfg = get_configparser() + if cfg.has_section("filament_presence"): + i = cfg.get_section("filament_presence", None) + self.filament_sensor = i.get("name", str, None) + else: + self.filament_sensor = None self.panel.filament_page_load_btn.clicked.connect( partial(self.change_page, self.indexOf(self.panel.load_page)) ) @@ -144,16 +152,13 @@ def on_filament_sensor_update(self, sensor_name: str, parameter: str, value: boo self._filament_state = self.FilamentStates.UNKNOWN self.handle_filament_state() return - self._sensor_states[sensor_name] = value - if not self._sensor_states: - new_state = self.FilamentStates.UNKNOWN - elif all(self._sensor_states.values()): - new_state = self.FilamentStates.LOADED - else: - new_state = self.FilamentStates.UNLOADED - if self._filament_state != new_state: - self._filament_state = new_state - self.handle_filament_state() + if sensor_name == self.filament_sensor: + if value: + self._filament_state = self.FilamentStates.LOADED + else: + self._filament_state = self.FilamentStates.UNLOADED + return + self.handle_filament_state() @QtCore.pyqtSlot(str, str, float, name="on_extruder_update") def on_extruder_update( From df8b7e6453cfc9626c18d6d4060ee695b3b372f0 Mon Sep 17 00:00:00 2001 From: Roberto Martins Date: Tue, 14 Apr 2026 10:05:22 +0100 Subject: [PATCH 07/13] add: added more features --- BlocksScreen/lib/panels/filamentTab.py | 81 +++++++------------------- BlocksScreen/lib/panels/mainWindow.py | 23 +++----- BlocksScreen/lib/printer.py | 10 ++-- 3 files changed, 33 insertions(+), 81 deletions(-) diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index 96920ef6..6f5b1775 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -92,7 +92,6 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: lambda: self.request_change_tab.emit(0) ) self.run_gcode.connect(self.ws.api.run_gcode) - self.printer.extruder_update.connect(self.on_extruder_update) self.printer.unload_filament_update.connect(self.on_unload_filament) self.printer.load_filament_update.connect(self.on_load_filament) self.printer.filament_switch_sensor_update.connect( @@ -103,10 +102,9 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self.printer.print_stats_update[str, dict].connect(self.on_print_stats_update) self.printer.print_stats_update[str, float].connect(self.on_print_stats_update) - self.loadignore = True - self.unloadignore = True self.printer.save_variables_update.connect(self.on_save_variables_update) + self.state = "standby" def on_save_variables_update(self, save_variables: dict): """Handle query response""" @@ -125,6 +123,7 @@ def on_print_stats_update(self, field: str, value: dict | float | str) -> None: """Handle print stats object update""" if isinstance(value, str): if "state" in field: + self.state = value if value in ("printing", "pausing", "paused", "resuming"): self.panel.main_back_button.show() self.panel.spacerItem1.changeSize( @@ -134,8 +133,6 @@ def on_print_stats_update(self, field: str, value: dict | float | str) -> None: QtWidgets.QSizePolicy.Policy.Minimum, ) if value in ("standby"): - self.loadignore = True - self.unloadignore = True self.panel.main_back_button.hide() self.panel.spacerItem1.changeSize( 0, @@ -160,63 +157,29 @@ def on_filament_sensor_update(self, sensor_name: str, parameter: str, value: boo return self.handle_filament_state() - @QtCore.pyqtSlot(str, str, float, name="on_extruder_update") - def on_extruder_update( - self, extruder_name: str, field: str, new_value: float - ) -> None: - """Handle extruder update""" - if not self.isVisible: - return - if not self.loadignore or not self.unloadignore: - if self.target_temp != 0: - if self.current_temp == self.target_temp: - if self.isVisible: - self.call_load_panel.emit( - True, "Extruder heated up \n Please wait" - ) - return - if field == "temperature": - self.current_temp = round(new_value, 0) - if self.isVisible: - self.call_load_panel.emit( - True, - f"Heating up ({new_value}/{self.target_temp}) \n Please wait", - ) - if field == "target": - self.target_temp = round(new_value, 0) - if self.isVisible: - self.call_load_panel.emit(True, "Heating up \n Please wait") - - @QtCore.pyqtSlot(bool, name="on_load_filament") - def on_load_filament(self, status: bool): + + @QtCore.pyqtSlot(dict, name="on_load_filament") + def on_load_filament(self, status: dict): """Handle load filament object updated""" - if not self.isVisible: - return - if self.loadignore: - return - if status: - self.call_load_panel.emit(True, "Loading Filament") - else: - self.loadignore = True - self.target_temp = 0 - self.call_load_panel.emit(False, "") - self._filament_state = self.FilamentStates.LOADED + if "state" in status.keys(): + if not status["state"]: + self.target_temp = 0 + self.call_load_panel.emit(False, "") + if self.state == "printing": + self.request_change_tab.emit(0) + return + self.call_load_panel.emit(True, f"Loading Filament\n{status['step'].capitalize()}") self.handle_filament_state() - @QtCore.pyqtSlot(bool, name="on_unload_filament") - def on_unload_filament(self, status: bool): + @QtCore.pyqtSlot(dict, name="on_unload_filament") + def on_unload_filament(self, status: dict): """Handle unload filament object updated""" - if not self.isVisible: - return - if self.unloadignore: - return - if status: - self.call_load_panel.emit(True, "Unloading Filament") - else: - self.unloadignore = True - self.call_load_panel.emit(False, "") - self.target_temp = 0 - self._filament_state = self.FilamentStates.UNLOADED + if "state" in status.keys(): + if not status["state"]: + self.target_temp = 0 + self.call_load_panel.emit(False, "") + return + self.call_load_panel.emit(True, f"Unloading Filament\n{status['step'].capitalize()}") self.handle_filament_state() @QtCore.pyqtSlot(int, int, name="load_filament") @@ -239,7 +202,6 @@ def load_filament( message="Filament is already loaded.", ) return - self.loadignore = False self.call_load_panel.emit(True, "Loading Filament") self.run_gcode.emit( f"""SAVE_VARIABLE VARIABLE=filament_type VALUE='"{filament.value.name}"'""" @@ -268,7 +230,6 @@ def unload_filament(self, toolhead: int = 0, temp: int = 220) -> None: return self.find_routine_objects() - self.unloadignore = False self.call_load_panel.emit(True, "Unloading Filament") self.run_gcode.emit( f"""SAVE_VARIABLE VARIABLE=filament_type VALUE='"{FilamentTypes.UNKNOWN.value.name}"'""" diff --git a/BlocksScreen/lib/panels/mainWindow.py b/BlocksScreen/lib/panels/mainWindow.py index c76ac90d..5bc68a55 100644 --- a/BlocksScreen/lib/panels/mainWindow.py +++ b/BlocksScreen/lib/panels/mainWindow.py @@ -175,7 +175,7 @@ def __init__(self): self.ui.filament_type_icon.clicked.connect( lambda: self.global_change_page( self.ui.main_content_widget.indexOf(self.ui.filamentTab), - self.filamentPanel.indexOf(self.filamentPanel.panel.load_page), + self.filamentPanel.indexOf(self.filamentPanel), ) ) self.ui.filament_type_icon.setText("PLA") @@ -294,10 +294,6 @@ def handle_cancel_print(self, show: bool = True): def show_LoadScreen(self, show: bool = True, msg: str = ""): """Show or hide the loading overlay, guarded by the calling panel's visibility.""" _sender = self.sender() - - if _sender == self.filamentPanel: - if not self.filamentPanel.isVisible(): - return if _sender == self.controlPanel: if not self.controlPanel.isVisible(): return @@ -307,7 +303,6 @@ def show_LoadScreen(self, show: bool = True, msg: str = ""): if _sender == self.utilitiesPanel: if not self.utilitiesPanel.isVisible(): return - self.loadwidget.set_status_message(msg) if show: self.loadscreen.show() @@ -341,8 +336,6 @@ def on_cancel_print(self): self.enable_tab_bar() self.ui.extruder_temp_display.clicked.disconnect() self.ui.bed_temp_display.clicked.disconnect() - self.ui.filament_type_icon.setDisabled(False) - self.ui.nozzle_size_icon.setDisabled(False) self.ui.extruder_temp_display.clicked.connect( lambda: self.global_change_page( self.ui.main_content_widget.indexOf(self.ui.controlTab), @@ -430,14 +423,18 @@ def reset_tab_indexes(self): Used to grantee all tabs reset to their first page once the user leaves the tab """ + self.filamentPanel.setCurrentIndex(0) + if self.print_status == "printing": + self.printPanel.setCurrentIndex(self.printPanel.indexOf(self.printPanel.jobStatusPage_widget)) return - self.update_page.hide() self.printPanel.setCurrentIndex(0) - self.filamentPanel.setCurrentIndex(0) self.controlPanel.setCurrentIndex(0) self.utilitiesPanel.setCurrentIndex(0) - self.networkPanel.setCurrentIndex(0) + self.networkPanel.setCurrentIndex(0) + self.update_page.hide() + + def current_panel_index(self) -> int: """Helper function to get the index of the current page in the current tab @@ -840,8 +837,6 @@ def event(self, event: QtCore.QEvent) -> bool: self.disable_tab_bar() self.ui.extruder_temp_display.clicked.disconnect() self.ui.bed_temp_display.clicked.disconnect() - self.ui.filament_type_icon.setDisabled(True) - self.ui.nozzle_size_icon.setDisabled(True) self.ui.extruder_temp_display.clicked.connect( lambda: self.global_change_page( self.ui.main_content_widget.indexOf(self.ui.printTab), @@ -867,8 +862,6 @@ def event(self, event: QtCore.QEvent) -> bool: self.enable_tab_bar() self.ui.extruder_temp_display.clicked.disconnect() self.ui.bed_temp_display.clicked.disconnect() - self.ui.filament_type_icon.setDisabled(False) - self.ui.nozzle_size_icon.setDisabled(False) self.ui.extruder_temp_display.clicked.connect( lambda: self.global_change_page( self.ui.main_content_widget.indexOf(self.ui.controlTab), diff --git a/BlocksScreen/lib/printer.py b/BlocksScreen/lib/printer.py index fd63e182..67aecb55 100644 --- a/BlocksScreen/lib/printer.py +++ b/BlocksScreen/lib/printer.py @@ -64,8 +64,8 @@ class Printer(QtCore.QObject): gcode_macro_update = QtCore.pyqtSignal(str, dict, name="gcode_macro_update") webhooks_update = QtCore.pyqtSignal(str, str, name="webhooks_update") - load_filament_update = QtCore.pyqtSignal(bool, name="load_filament_update") - unload_filament_update = QtCore.pyqtSignal(bool, name="unload_filament_update") + load_filament_update = QtCore.pyqtSignal(dict, name="load_filament_update") + unload_filament_update = QtCore.pyqtSignal(dict, name="unload_filament_update") query_printer_object = QtCore.pyqtSignal(dict, name="query_printer_object") save_config_pending: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( @@ -741,9 +741,7 @@ def _temperature_probe_object_updated(self, values: dict, name: str) -> None: # TODO: testing needed here idk if does work def _unload_filament_object_updated(self, values: dict, name: str) -> None: - if "state" in values.keys(): - self.unload_filament_update[bool].emit(values["state"]) + self.unload_filament_update[dict].emit(values) def _load_filament_object_updated(self, values: dict, name: str) -> None: - if "state" in values.keys(): - self.load_filament_update[bool].emit(values["state"]) + self.load_filament_update[dict].emit(values) From 9b7167a179fa4b3ab9ceca9783ecd6b5c1b31121 Mon Sep 17 00:00:00 2001 From: Roberto Martins Date: Tue, 14 Apr 2026 10:06:14 +0100 Subject: [PATCH 08/13] refactor: ran ruff formatter --- BlocksScreen/lib/panels/filamentTab.py | 10 ++++++---- BlocksScreen/lib/panels/mainWindow.py | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index 6f5b1775..e3c33898 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -102,7 +102,6 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self.printer.print_stats_update[str, dict].connect(self.on_print_stats_update) self.printer.print_stats_update[str, float].connect(self.on_print_stats_update) - self.printer.save_variables_update.connect(self.on_save_variables_update) self.state = "standby" @@ -157,7 +156,6 @@ def on_filament_sensor_update(self, sensor_name: str, parameter: str, value: boo return self.handle_filament_state() - @QtCore.pyqtSlot(dict, name="on_load_filament") def on_load_filament(self, status: dict): """Handle load filament object updated""" @@ -168,7 +166,9 @@ def on_load_filament(self, status: dict): if self.state == "printing": self.request_change_tab.emit(0) return - self.call_load_panel.emit(True, f"Loading Filament\n{status['step'].capitalize()}") + self.call_load_panel.emit( + True, f"Loading Filament\n{status['step'].capitalize()}" + ) self.handle_filament_state() @QtCore.pyqtSlot(dict, name="on_unload_filament") @@ -179,7 +179,9 @@ def on_unload_filament(self, status: dict): self.target_temp = 0 self.call_load_panel.emit(False, "") return - self.call_load_panel.emit(True, f"Unloading Filament\n{status['step'].capitalize()}") + self.call_load_panel.emit( + True, f"Unloading Filament\n{status['step'].capitalize()}" + ) self.handle_filament_state() @QtCore.pyqtSlot(int, int, name="load_filament") diff --git a/BlocksScreen/lib/panels/mainWindow.py b/BlocksScreen/lib/panels/mainWindow.py index 5bc68a55..7e334e54 100644 --- a/BlocksScreen/lib/panels/mainWindow.py +++ b/BlocksScreen/lib/panels/mainWindow.py @@ -426,15 +426,15 @@ def reset_tab_indexes(self): self.filamentPanel.setCurrentIndex(0) if self.print_status == "printing": - self.printPanel.setCurrentIndex(self.printPanel.indexOf(self.printPanel.jobStatusPage_widget)) + self.printPanel.setCurrentIndex( + self.printPanel.indexOf(self.printPanel.jobStatusPage_widget) + ) return self.printPanel.setCurrentIndex(0) self.controlPanel.setCurrentIndex(0) self.utilitiesPanel.setCurrentIndex(0) - self.networkPanel.setCurrentIndex(0) + self.networkPanel.setCurrentIndex(0) self.update_page.hide() - - def current_panel_index(self) -> int: """Helper function to get the index of the current page in the current tab From 13a125b062a9743978953558160e41661106b45a Mon Sep 17 00:00:00 2001 From: Roberto Martins Date: Tue, 14 Apr 2026 15:51:34 +0100 Subject: [PATCH 09/13] bugfix: fixed wrong state --- BlocksScreen/lib/panels/filamentTab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index e3c33898..c94ef8ca 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -163,7 +163,7 @@ def on_load_filament(self, status: dict): if not status["state"]: self.target_temp = 0 self.call_load_panel.emit(False, "") - if self.state == "printing": + if self.state == "paused": self.request_change_tab.emit(0) return self.call_load_panel.emit( From 892974a4aa00ff3f5e4271653d91a0e5e17dd4c2 Mon Sep 17 00:00:00 2001 From: HugoCLSC Date: Tue, 14 Apr 2026 17:18:32 +0100 Subject: [PATCH 10/13] Fetch app config file from parent --- BlocksScreen/lib/panels/filamentTab.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index c94ef8ca..0594cc11 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -5,7 +5,6 @@ from lib.printer import Printer from lib.filament import Filament from lib.ui.filamentStackedWidget_ui import Ui_filamentStackedWidget -from configfile import get_configparser from lib.panels.widgets.popupDialogWidget import Popup from PyQt6 import QtCore, QtGui, QtWidgets @@ -55,7 +54,7 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self._filament_state = self.FilamentStates.UNKNOWN self.filament_type = FilamentTypes.UNKNOWN - cfg = get_configparser() + cfg = parent.config if cfg.has_section("filament_presence"): i = cfg.get_section("filament_presence", None) self.filament_sensor = i.get("name", str, None) From 8149b78600bcf7c7d9df1ea441a7e22d8b420237 Mon Sep 17 00:00:00 2001 From: HugoCLSC Date: Tue, 14 Apr 2026 17:30:59 +0100 Subject: [PATCH 11/13] Update issued gcode command for loading --- BlocksScreen/lib/panels/filamentTab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index 0594cc11..2a425eef 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -208,7 +208,7 @@ def load_filament( f"""SAVE_VARIABLE VARIABLE=filament_type VALUE='"{filament.value.name}"'""" ) self.run_gcode.emit( - f"LOAD_FILAMENT TOOLHEAD=load_toolhead TEMPERATURE={filament.value.temperature}" + f"LOAD_FILAMENT TEMPERATURE={filament.value.temperature}" ) @QtCore.pyqtSlot(str, int, name="unload_filament") From 386b0ba9e01e4541bee1608839aec91781ce30e6 Mon Sep 17 00:00:00 2001 From: HugoCLSC Date: Tue, 14 Apr 2026 17:34:43 +0100 Subject: [PATCH 12/13] Refactor method name --- BlocksScreen/lib/panels/mainWindow.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/BlocksScreen/lib/panels/mainWindow.py b/BlocksScreen/lib/panels/mainWindow.py index 7e334e54..01d3b8c6 100644 --- a/BlocksScreen/lib/panels/mainWindow.py +++ b/BlocksScreen/lib/panels/mainWindow.py @@ -241,11 +241,11 @@ def __init__(self): self.ui.extruder_temp_display.display_format = "upper_downer" self.ui.bed_temp_display.display_format = "upper_downer" - self.controlPanel.call_load_panel.connect(self.show_LoadScreen) - self.filamentPanel.call_load_panel.connect(self.show_LoadScreen) - self.printPanel.call_load_panel.connect(self.show_LoadScreen) - self.utilitiesPanel.call_load_panel.connect(self.show_LoadScreen) - self.conn_window.call_load_panel.connect(self.show_LoadScreen) + self.controlPanel.call_load_panel.connect(self.show_loadscreen) + self.filamentPanel.call_load_panel.connect(self.show_loadscreen) + self.printPanel.call_load_panel.connect(self.show_loadscreen) + self.utilitiesPanel.call_load_panel.connect(self.show_loadscreen) + self.conn_window.call_load_panel.connect(self.show_loadscreen) self.filamentPanel.request_change_tab.connect(self.global_change_tab) self.printPanel.request_change_tab.connect(self.global_change_tab) @@ -291,7 +291,7 @@ def handle_cancel_print(self, show: bool = True): self.cancelpage.show() @QtCore.pyqtSlot(bool, str, name="show-load-page") - def show_LoadScreen(self, show: bool = True, msg: str = ""): + def show_loadscreen(self, show: bool = True, msg: str = ""): """Show or hide the loading overlay, guarded by the calling panel's visibility.""" _sender = self.sender() if _sender == self.controlPanel: @@ -495,7 +495,7 @@ def global_change_page(self, tab_index: int, panel_index: int) -> None: "Panel page index expected type int, %s", str(type(panel_index)) ) - self.show_LoadScreen(False) + self.show_loadscreen(False) current_page = [ self.ui.main_content_widget.currentIndex(), self.current_panel_index(), From 9d0a19f56dc042589268e00ff92bbbc043801f62 Mon Sep 17 00:00:00 2001 From: HugoCLSC Date: Tue, 14 Apr 2026 18:18:21 +0100 Subject: [PATCH 13/13] Formatting --- BlocksScreen/lib/panels/filamentTab.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index 2a425eef..3a7ed42e 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -207,9 +207,7 @@ def load_filament( self.run_gcode.emit( f"""SAVE_VARIABLE VARIABLE=filament_type VALUE='"{filament.value.name}"'""" ) - self.run_gcode.emit( - f"LOAD_FILAMENT TEMPERATURE={filament.value.temperature}" - ) + self.run_gcode.emit(f"LOAD_FILAMENT TEMPERATURE={filament.value.temperature}") @QtCore.pyqtSlot(str, int, name="unload_filament") def unload_filament(self, toolhead: int = 0, temp: int = 220) -> None: