From 255c99d90ef75ab137d64d9f0dee5b275ef0316f Mon Sep 17 00:00:00 2001 From: Roberto Date: Thu, 11 Dec 2025 16:45:27 +0000 Subject: [PATCH 1/7] ADD: added input shaper page --- .../lib/panels/widgets/inputshaperPage.py | 461 ++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 BlocksScreen/lib/panels/widgets/inputshaperPage.py diff --git a/BlocksScreen/lib/panels/widgets/inputshaperPage.py b/BlocksScreen/lib/panels/widgets/inputshaperPage.py new file mode 100644 index 0000000..4538352 --- /dev/null +++ b/BlocksScreen/lib/panels/widgets/inputshaperPage.py @@ -0,0 +1,461 @@ +from lib.panels.widgets.loadPage import LoadScreen +from lib.utils.blocks_button import BlocksCustomButton +from lib.utils.blocks_frame import BlocksCustomFrame +from lib.utils.icon_button import IconButton +from lib.utils.list_model import EntryDelegate, EntryListModel, ListItem +from PyQt6 import QtCore, QtGui, QtWidgets + +import typing + +class InputShaperPage(QtWidgets.QWidget): + """Update GUI Page, + retrieves from moonraker available clients and adds functionality + for updating or recovering them + """ + run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( + str, name="run-gcode" + ) + + def __init__(self, parent=None) -> None: + if parent: + super().__init__(parent) + else: + super().__init__() + self._setupUI() + self.selected_item: ListItem | None = None + self.ongoing_update: bool = False + self.type_dict: dict = {} + + self.load_popup: LoadScreen = LoadScreen(self) + self.repeated_request_status = QtCore.QTimer() + self.repeated_request_status.setInterval(2000) # every 2 seconds + self.model = EntryListModel() + self.model.setParent(self.update_buttons_list_widget) + self.entry_delegate = EntryDelegate() + self.update_buttons_list_widget.setModel(self.model) + self.update_buttons_list_widget.setItemDelegate(self.entry_delegate) + self.entry_delegate.item_selected.connect(self.on_item_clicked) + self.update_back_btn.clicked.connect(self.reset_view_model) + + self.action_btn.clicked.connect(self.handle_ism_confirm) + + + + + def handle_update_end(self) -> None: + """Handles update end signal + (closes loading page, returns to normal operation) + """ + if self.load_popup.isVisible(): + self.load_popup.close() + self.repeated_request_status.stop() + self.build_model_list() + + def handle_ongoing_update(self) -> None: + """Handled ongoing update signal, + calls loading page (blocks user interaction) + """ + self.load_popup.set_status_message("Updating...") + self.load_popup.show() + self.repeated_request_status.start(2000) + + def reset_view_model(self) -> None: + """Clears items from ListView + (Resets `QAbstractListModel` by clearing entries) + """ + self.model.clear() + self.entry_delegate.clear() + + def deleteLater(self) -> None: + """Schedule the object for deletion, resets the list model first""" + self.reset_view_model() + return super().deleteLater() + + def showEvent(self, a0: QtGui.QShowEvent | None) -> None: + """Re-add clients to update list""" + return super().showEvent(a0) + + def build_model_list(self) -> None: + """Builds the model list (`self.model`) containing updatable clients""" + self.update_buttons_list_widget.blockSignals(True) + self.model.setData( + self.model.index(0), True, EntryListModel.EnableRole + ) + self.on_item_clicked( + self.model.data(self.model.index(0), QtCore.Qt.ItemDataRole.UserRole) + ) + self.update_buttons_list_widget.blockSignals(False) + + + def set_type_dictionary(self, dict) -> None: + """Receives the dictionary of input shaper types from the utilities tab""" + self.type_dict = dict + return + + + @QtCore.pyqtSlot(ListItem, name="on-item-clicked") + def on_item_clicked(self, item: ListItem) -> None: + """Setup information for the currently clicked list item on the info box. + Keeps track of the list item + """ + self.currentItem: ListItem = item + if not item: + return + current_info = self.type_dict.get(self.currentItem.text, {}) + if not current_info: + return + + self.vib_label.setText(str("%.0f" % current_info.get('vibration', 'N/A'))+ "%") + self.sug_accel_label.setText(str("%.0f" % current_info.get('max_accel', 'N/A'))+ "mm/s²") + + self.action_btn.show() + + def handle_ism_confirm(self)-> None: + current_info = self.type_dict.get(self.currentItem.text, {}) + frequency = current_info.get('frequency', 'N/A') + if self.type_dict["Axis"] == "x": + self.run_gcode_signal.emit(f"SET_INPUT_SHAPER SHAPER_TYPE_X={self.currentItem.text} SHAPER_FREQ_X={frequency}") + elif self.type_dict["Axis"] == "y": + self.run_gcode_signal.emit(f"SET_INPUT_SHAPER SHAPER_TYPE_Y={self.currentItem.text} SHAPER_FREQ_Y={frequency}") + + self.run_gcode_signal.emit("SAVE_CONFIG") + self.reset_view_model() + + + + def add_type_entry(self, cli_name: str,recommended:str = "") -> None: + """Adds a new item to the list model""" + item = ListItem( + text=cli_name, + right_text=recommended, + right_icon=QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg"), + selected=False, + _lfontsize=17, + _rfontsize=9, + height=60, + allow_check=True, + notificate=False, + ) + self.model.add_item(item) + + def _setupUI(self) -> None: + """Setup UI for updatePage""" + font_id = QtGui.QFontDatabase.addApplicationFont( + ":/font/media/fonts for text/Momcake-Bold.ttf" + ) + font_family = QtGui.QFontDatabase.applicationFontFamilies(font_id)[0] + sizePolicy = QtWidgets.QSizePolicy( + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + QtWidgets.QSizePolicy.Policy.MinimumExpanding, + ) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(1) + self.setSizePolicy(sizePolicy) + self.setMinimumSize(QtCore.QSize(710, 400)) + self.setMaximumSize(QtCore.QSize(720, 420)) + self.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.update_page_content_layout = QtWidgets.QVBoxLayout() + self.update_page_content_layout.setContentsMargins(15, 15, 2, 2) + + self.header_content_layout = QtWidgets.QHBoxLayout() + self.header_content_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop) + + self.spacer_left = QtWidgets.QLabel(self) + self.spacer_left.setMinimumSize(QtCore.QSize(60, 60)) + self.spacer_left.setMaximumSize(QtCore.QSize(60, 60)) + self.header_content_layout.addWidget(self.spacer_left, 0) + self.header_title = QtWidgets.QLabel(self) + self.header_title.setMinimumSize(QtCore.QSize(100, 60)) + self.header_title.setMaximumSize(QtCore.QSize(16777215, 60)) + font = QtGui.QFont() + font.setFamily(font_family) + font.setPointSize(24) + palette = self.header_title.palette() + palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) + self.header_title.setFont(font) + self.header_title.setPalette(palette) + self.header_title.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft) + self.header_title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.header_title.setObjectName("header-title") + self.header_title.setText("Input Shaper") + self.header_content_layout.addWidget(self.header_title, 0) + self.update_back_btn = IconButton(self) + self.update_back_btn.setMinimumSize(QtCore.QSize(60, 60)) + self.update_back_btn.setMaximumSize(QtCore.QSize(60, 60)) + self.update_back_btn.setFlat(True) + self.update_back_btn.setPixmap(QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) + self.header_content_layout.addWidget(self.update_back_btn, 0) + self.update_page_content_layout.addLayout(self.header_content_layout, 0) + + self.main_content_layout = QtWidgets.QHBoxLayout() + self.main_content_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + + self.update_buttons_frame = BlocksCustomFrame(self) + + self.update_buttons_frame.setMinimumSize(QtCore.QSize(300, 300)) + self.update_buttons_frame.setMaximumSize(QtCore.QSize(350, 500)) + + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Active, + QtGui.QPalette.ColorRole.Button, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.NoBrush) + palette.setBrush( + QtGui.QPalette.ColorGroup.Active, + QtGui.QPalette.ColorRole.Base, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Active, + QtGui.QPalette.ColorRole.Window, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 120, 215, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Active, + QtGui.QPalette.ColorRole.Highlight, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 255, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Active, + QtGui.QPalette.ColorRole.Link, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Inactive, + QtGui.QPalette.ColorRole.Button, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.NoBrush) + palette.setBrush( + QtGui.QPalette.ColorGroup.Inactive, + QtGui.QPalette.ColorRole.Base, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Inactive, + QtGui.QPalette.ColorRole.Window, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 120, 215, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Inactive, + QtGui.QPalette.ColorRole.Highlight, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 255, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Inactive, + QtGui.QPalette.ColorRole.Link, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Disabled, + QtGui.QPalette.ColorRole.Button, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.NoBrush) + palette.setBrush( + QtGui.QPalette.ColorGroup.Disabled, + QtGui.QPalette.ColorRole.Base, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Disabled, + QtGui.QPalette.ColorRole.Window, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 120, 215, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Disabled, + QtGui.QPalette.ColorRole.Highlight, + brush, + ) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 255, 0)) + brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern) + palette.setBrush( + QtGui.QPalette.ColorGroup.Disabled, + QtGui.QPalette.ColorRole.Link, + brush, + ) + self.update_buttons_list_widget = QtWidgets.QListView(self.update_buttons_frame) + self.update_buttons_list_widget.setMouseTracking(True) + self.update_buttons_list_widget.setTabletTracking(True) + + self.update_buttons_list_widget.setPalette(palette) + self.update_buttons_list_widget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus) + self.update_buttons_list_widget.setStyleSheet("background-color:transparent") + self.update_buttons_list_widget.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.update_buttons_list_widget.setMinimumSize(self.update_buttons_frame.size()) + self.update_buttons_list_widget.setFrameShape(QtWidgets.QFrame.Shape.NoFrame) + self.update_buttons_list_widget.setVerticalScrollBarPolicy( + QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff + ) + self.update_buttons_list_widget.setHorizontalScrollBarPolicy( + QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff + ) + self.update_buttons_list_widget.setSizeAdjustPolicy( + QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents + ) + self.update_buttons_list_widget.setAutoScroll(False) + self.update_buttons_list_widget.setProperty("showDropIndicator", False) + self.update_buttons_list_widget.setDefaultDropAction( + QtCore.Qt.DropAction.IgnoreAction + ) + self.update_buttons_list_widget.setAlternatingRowColors(False) + self.update_buttons_list_widget.setSelectionMode( + QtWidgets.QAbstractItemView.SelectionMode.NoSelection + ) + self.update_buttons_list_widget.setSelectionBehavior( + QtWidgets.QAbstractItemView.SelectionBehavior.SelectItems + ) + self.update_buttons_list_widget.setVerticalScrollMode( + QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel + ) + self.update_buttons_list_widget.setHorizontalScrollMode( + QtWidgets.QAbstractItemView.ScrollMode.ScrollPerPixel + ) + QtWidgets.QScroller.grabGesture( + self.update_buttons_list_widget, + QtWidgets.QScroller.ScrollerGestureType.TouchGesture, + ) + QtWidgets.QScroller.grabGesture( + self.update_buttons_list_widget, + QtWidgets.QScroller.ScrollerGestureType.LeftMouseButtonGesture, + ) + self.update_buttons_layout = QtWidgets.QVBoxLayout() + self.update_buttons_layout.setContentsMargins(15, 20, 20, 5) + self.update_buttons_layout.addWidget(self.update_buttons_list_widget, 0) + self.update_buttons_frame.setLayout(self.update_buttons_layout) + + self.main_content_layout.addWidget(self.update_buttons_frame, 0) + + self.infobox_frame = BlocksCustomFrame() + self.infobox_frame.setMinimumSize(QtCore.QSize(250, 300)) + + self.info_box_layout = QtWidgets.QVBoxLayout() + self.info_box_layout.setContentsMargins(10, 10, 10, 10) + + font = QtGui.QFont() + font.setFamily(font_family) + font.setPointSize(20) + self.info_box = QtWidgets.QGridLayout() + self.info_box.setContentsMargins(0, 0, 0, 0) + + self.vib_title_label = QtWidgets.QLabel(self) + self.vib_title_label.setText("Vibrations: ") + self.vib_title_label.setMinimumSize(QtCore.QSize(60, 60)) + self.vib_title_label.setMaximumSize( + QtCore.QSize(int(self.infobox_frame.size().width() * 0.40), 9999) + ) + palette = self.vib_title_label.palette() + palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) + self.vib_title_label.setAlignment( + QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter + ) + self.vib_title_label.setFont(font) + self.vib_title_label.setPalette(palette) + self.vib_title_label.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft) + self.vib_label = QtWidgets.QLabel(self) + self.vib_label.setMinimumSize(QtCore.QSize(100, 60)) + self.vib_label.setMaximumSize(QtCore.QSize(16777215, 9999)) + palette = self.vib_label.palette() + palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) + self.vib_label.setFont(font) + self.vib_label.setPalette(palette) + self.vib_label.setLayoutDirection( + QtCore.Qt.LayoutDirection.RightToLeft + ) + self.vib_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.vib_label.setObjectName("version-tracking") + + self.info_box.addWidget(self.vib_title_label, 0, 0) + self.info_box.addWidget(self.vib_label, 0, 1) + + + self.sug_accel_title_label = QtWidgets.QLabel(self) + self.sug_accel_title_label.setText("Sugested Max Acceleration:") + self.sug_accel_title_label.setMinimumSize(QtCore.QSize(60, 60)) + self.sug_accel_title_label.setMaximumSize( + QtCore.QSize(int(self.infobox_frame.size().width() * 0.40), 9999) + ) + palette = self.sug_accel_title_label.palette() + palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) + self.sug_accel_title_label.setAlignment( + QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter + ) + self.sug_accel_title_label.setFont(font) + self.sug_accel_title_label.setPalette(palette) + self.sug_accel_title_label.setLayoutDirection( + QtCore.Qt.LayoutDirection.RightToLeft + ) + + + self.sug_accel_label = QtWidgets.QLabel(self) + self.sug_accel_label.setMinimumSize(QtCore.QSize(100, 60)) + self.sug_accel_label.setMaximumSize( + QtCore.QSize(int(self.infobox_frame.size().width() * 0.60), 9999) + ) + palette = self.sug_accel_label.palette() + palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) + self.sug_accel_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.sug_accel_label.setFont(font) + self.sug_accel_label.setPalette(palette) + + self.info_box.addWidget(self.sug_accel_title_label, 1, 0) + self.info_box.addWidget(self.sug_accel_label, 1, 1) + + self.info_box_layout.addLayout(self.info_box, 1) + + + + self.button_box = QtWidgets.QVBoxLayout() + self.button_box.setContentsMargins(0, 0, 0, 0) + self.button_box.addSpacing(-1) + + self.action_btn = BlocksCustomButton() + self.action_btn.setMinimumSize(QtCore.QSize(200, 60)) + self.action_btn.setMaximumSize(QtCore.QSize(250, 60)) + font.setPointSize(20) + self.action_btn.setFont(font) + self.action_btn.setPalette(palette) + self.action_btn.setSizePolicy(sizePolicy) + self.action_btn.setText("Confirm") + self.action_btn.setPixmap( + QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg") + ) + self.button_box.addWidget( + self.action_btn, 0, QtCore.Qt.AlignmentFlag.AlignRight | QtCore.Qt.AlignmentFlag.AlignBottom + ) + + self.info_box_layout.addLayout( + self.button_box, + 0, + ) + self.infobox_frame.setLayout(self.info_box_layout) + self.main_content_layout.addWidget(self.infobox_frame, 1) + self.update_page_content_layout.addLayout(self.main_content_layout, 1) + self.setLayout(self.update_page_content_layout) From db7d9f9860429ee6964d1b7f07f786ca1b827d39 Mon Sep 17 00:00:00 2001 From: Roberto Date: Mon, 15 Dec 2025 11:45:10 +0000 Subject: [PATCH 2/7] bugfix: button blocking clicks --- BlocksScreen/lib/panels/widgets/optionCardWidget.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BlocksScreen/lib/panels/widgets/optionCardWidget.py b/BlocksScreen/lib/panels/widgets/optionCardWidget.py index 8c79ee6..6fbfe20 100644 --- a/BlocksScreen/lib/panels/widgets/optionCardWidget.py +++ b/BlocksScreen/lib/panels/widgets/optionCardWidget.py @@ -38,6 +38,9 @@ def __init__( self.line_separator.setAttribute( QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents ) + self.continue_button.setAttribute( + QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents + ) self.setMode(False) self.set_card_icon(icon) From 575805cf020bb272d3204c60db97986803e7fa98 Mon Sep 17 00:00:00 2001 From: Roberto Date: Mon, 15 Dec 2025 11:49:11 +0000 Subject: [PATCH 3/7] ADD: added input shapper logic --- BlocksScreen/lib/panels/utilitiesTab.py | 271 +++++++++++++++--------- 1 file changed, 167 insertions(+), 104 deletions(-) diff --git a/BlocksScreen/lib/panels/utilitiesTab.py b/BlocksScreen/lib/panels/utilitiesTab.py index 4797b2f..7997353 100644 --- a/BlocksScreen/lib/panels/utilitiesTab.py +++ b/BlocksScreen/lib/panels/utilitiesTab.py @@ -1,4 +1,3 @@ -import csv import typing from dataclasses import dataclass from enum import Enum, auto @@ -14,6 +13,12 @@ from lib.utils.toggleAnimatedButton import ToggleAnimatedButton from PyQt6 import QtCore, QtGui, QtWidgets +from lib.panels.widgets.optionCardWidget import OptionCard +from lib.panels.widgets.inputshaperPage import InputShaperPage +from lib.panels.widgets.dialogPage import DialogPage + +import re + @dataclass class LedState: @@ -41,8 +46,6 @@ def get_gcode(self, name: str) -> str: class Process(Enum): - """Printer Process""" - FAN = auto() AXIS = auto() BED_HEATER = auto() @@ -113,6 +116,7 @@ def __init__( self.amount: int = 1 self.tb: bool = False self.cg = None + self.aut: bool = False # --- UI Setup --- self.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) @@ -122,16 +126,21 @@ def __init__( self.update_page = UpdatePage(self) self.addWidget(self.update_page) - self.panel.utilities_input_shaper_btn.hide() + self.is_page = InputShaperPage(self) + self.addWidget(self.is_page) + + self.dialog_page = DialogPage(self) + self.addWidget(self.dialog_page) + # --- Back Buttons --- for button in ( - self.panel.is_back_btn, self.panel.leds_back_btn, self.panel.info_back_btn, self.panel.leds_slider_back_btn, self.panel.input_shaper_back_btn, self.panel.routine_check_back_btn, self.update_page.update_back_btn, + self.is_page.update_back_btn, ): button.clicked.connect(self.back_button) @@ -145,7 +154,6 @@ def __init__( self._connect_page_change( self.panel.utilities_routine_check_btn, self.panel.routines_page ) - self._connect_page_change(self.panel.is_confirm_btn, self.panel.utilities_page) self._connect_page_change(self.panel.am_cancel, self.panel.utilities_page) self._connect_page_change(self.panel.axes_back_btn, self.panel.utilities_page) @@ -168,20 +176,6 @@ def __init__( self.panel.axis_y_btn.clicked.connect(partial(self.axis_maintenance, "y")) self.panel.axis_z_btn.clicked.connect(partial(self.axis_maintenance, "z")) - # --- Input Shaper --- - self.panel.is_X_startis_btn.clicked.connect( - partial(self.run_resonance_test, "x") - ) - self.panel.is_Y_startis_btn.clicked.connect( - partial(self.run_resonance_test, "y") - ) - self.panel.am_confirm.clicked.connect(self.apply_input_shaper_selection) - self.panel.isc_btn_group.buttonClicked.connect( - lambda btn: setattr(self, "ammount", int(btn.text())) - ) - self._connect_numpad_request(self.panel.isui_fq, "frequency", "Frequency") - self._connect_numpad_request(self.panel.isui_sm, "smoothing", "Smoothing") - self.panel.toggle_led_button.state = ToggleAnimatedButton.State.ON # --- LEDs --- @@ -193,6 +187,7 @@ def __init__( # --- Websocket/Printer Signals --- self.run_gcode_signal.connect(self.ws.api.run_gcode) + self.is_page.run_gcode_signal.connect(self.ws.api.run_gcode) self.subscribe_config[str, "PyQt_PyObject"].connect( self.printer.on_subscribe_config ) @@ -220,6 +215,7 @@ def __init__( self.update_page.request_refresh_update[str].connect( self.ws.api.refresh_update_status ) + self.printer.gcode_response.connect(self.handle_gcode_response) self.update_page.request_rollback_update.connect(self.ws.api.rollback_update) self.update_page.request_update_client.connect(self.ws.api.update_client) self.update_page.request_update_klipper.connect(self.ws.api.update_klipper) @@ -234,6 +230,156 @@ def __init__( QtGui.QPixmap(":/system/media/btn_icons/update-software-icon.svg") ) + self.automatic_is = OptionCard( + self, + "Automatic\nInput Shaper", + "Automatic Input Shaper", + QtGui.QPixmap(":/input_shaper/media/btn_icons/input_shaper_auto.svg"), + ) # type: ignore + self.automatic_is.setObjectName("Automatic_IS_Card") + self.panel.is_content_layout.addWidget( + self.automatic_is, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter + ) + self.automatic_is.continue_clicked.connect( + lambda: self.handle_is("SHAPER_CALIBRATE") + ) + + self.manuel_is = OptionCard( + self, + "Manuel\nInput Shaper", + "Manual Input Shaper", + QtGui.QPixmap(":/input_shaper/media/btn_icons/input_shaper_manual.svg"), + ) # type: ignore + self.manuel_is.setObjectName("Manual_IS_Card") + self.panel.is_content_layout.addWidget( + self.manuel_is, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter + ) + self.manuel_is.continue_clicked.connect(lambda: self.handle_is("")) + + self.is_types: dict = {} + self.is_aut_types: dict = {} + + self.is_page.action_btn.clicked.connect( + lambda: self.change_page(self.indexOf(self.panel.input_shaper_page)) + ) + + def handle_gcode_response(self, data: list[str]) -> None: + """ + Parses a Klipper Input Shaper console message and updates self.is_types. + """ + + if not isinstance(data, list) or len(data) != 1 or not isinstance(data[0], str): + print( + f"WARNING: Invalid input format. Expected a list with one string. Received: {data}" + ) + return + + message = data[0] + + pattern_fitted = re.compile( + r"Fitted shaper '(?P\w+)' frequency = (?P[\d\.]+) Hz \(vibrations = (?P[\d\.]+)%" + ) + match_fitted = pattern_fitted.search(message) + + if match_fitted: + name = match_fitted.group("name") + freq = float(match_fitted.group("freq")) + vib = float(match_fitted.group("vib")) + current_data = self.is_types.get(name, {}) + current_data.update( + { + "frequency": freq, + "vibration": vib, + "max_accel": current_data.get("max_accel", 0.0), + } + ) + self.is_types[name] = current_data + + return + pattern_accel = re.compile( + r"To avoid too much smoothing with '(?P\w+)', suggested max_accel <= (?P[\d\.]+) mm/sec\^2" + ) + match_accel = pattern_accel.search(message) + + if match_accel: + name = match_accel.group("name") + accel = float(match_accel.group("accel")) + + if name in self.is_types and isinstance(self.is_types[name], dict): + self.is_types[name]["max_accel"] = accel + else: + self.is_types[name] = self.is_types.get(name, {}) + self.is_types[name]["max_accel"] = accel + return + + pattern_recommended = re.compile( + r"Recommended shaper_type_(?P[xy]) = (?P\w+), shaper_freq_(?P=axis) = (?P[\d\.]+) Hz" + ) + match_recommended = pattern_recommended.search(message) + if match_recommended: + axis = match_recommended.group("axis") + recommended_type = match_recommended.group("type") + self.is_types["Axis"] = axis + if self.aut: + self.is_aut_types[axis] = recommended_type + if len(self.is_aut_types) == 2: + self.run_gcode_signal.emit("SAVE_CONFIG") + self.loadPage.hide() + self.aut = False + return + return + + reordered = {recommended_type: self.is_types[recommended_type]} + for key, value in self.is_types.items(): + if key not in ("suggested_type", recommended_type, "Axis"): + reordered[key] = value + + self.is_page.set_type_dictionary(self.is_types) + first_key = next(iter(reordered.keys()), None) + for key in reordered.keys(): + if key == first_key: + self.is_page.add_type_entry(key, "Recommended type") + else: + self.is_page.add_type_entry(key) + + self.is_page.build_model_list() + self.loadPage.hide() + return + + def on_dialog_button_clicked(self, button_name: str) -> None: + print(button_name) + """Handle dialog button clicks""" + if button_name == "Confirm": + self.handle_is("SHAPER_CALIBRATE AXIS=Y") + elif button_name == "Cancel": + self.handle_is("SHAPER_CALIBRATE AXIS=X") + + def handle_is(self, gcode: str) -> None: + if gcode == "SHAPER_CALIBRATE": + self.run_gcode_signal.emit("G28\nM400") + self.aut = True + self.run_gcode_signal.emit(gcode) + if gcode == "": + print("Manuel Input Shaper Selected") + self.dialog_page.confirm_background_color("#dfdfdf") + self.dialog_page.cancel_background_color("#dfdfdf") + self.dialog_page.cancel_font_color("#000000") + self.dialog_page.confirm_font_color("#000000") + self.dialog_page.cancel_button_text("X axis") + self.dialog_page.confirm_button_text("Y axis") + self.dialog_page.set_message( + "Select the axis you want to execute the input shaper on:" + ) + self.dialog_page.show() + return + else: + self.run_gcode_signal.emit("G28\nM400") + self.run_gcode_signal.emit(gcode) + self.change_page(self.indexOf(self.is_page)) + + self.loadPage.set_status_message("Running Input Shaper...") + self.loadPage.show() + @QtCore.pyqtSlot(list, name="on_object_list") def on_object_list(self, object_list: list) -> None: """Handle receiving printer object list""" @@ -287,21 +433,6 @@ def on_gcode_move_update(self, name: str, value: list) -> None: if name == "gcode_position": ... - def _connect_numpad_request(self, button: QtWidgets.QWidget, name: str, title: str): - if isinstance(button, QtWidgets.QPushButton): - button.clicked.connect( - lambda: self.request_numpad_signal.emit( - 3, name, title, self.handle_numpad_change, self - ) - ) - - def handle_numpad_change(self, name: str, new_value: typing.Union[int, float]): - """Handle numpad change""" - if name == "frequency": - self.panel.isui_fq.setText(f"Frequency: {new_value} Hz") - elif name == "smoothing": - self.panel.isui_sm.setText(f"Smoothing: {new_value}") - def run_routine(self, process: Process): """Run check routine for available processes""" self.current_process = process @@ -512,74 +643,6 @@ def save_led_state(self): led_state: LedState = self.objects["leds"][self.current_object] self.run_gcode_signal.emit(led_state.get_gcode(self.current_object)) - def run_resonance_test(self, axis: str) -> None: - """Perform Input Shaper Measure resonances test""" - self.axis_in = axis - path_map = { - "x": "/tmp/resonances_x_axis_data.csv", - "y": "/tmp/resonances_y_axis_data.csv", - } - if not (csv_path := path_map.get(axis)): - return - self.run_gcode_signal.emit(f"SHAPER_CALIBRATE AXIS={axis.upper()}") - self.data = self._parse_shaper_csv(csv_path) - for entry in self.data: - shaper = entry["shaper"] - panel_attr = f"am_{shaper}" - if hasattr(self.panel, panel_attr): - text = ( - f"Shaper: {shaper}, Freq: {entry['frequency']}Hz, Vibrations: {entry['vibrations']}%\n" - f"Smoothing: {entry['smoothing']}, Max Accel: {entry['max_accel']}mm/sec" - ) - getattr(self.panel, panel_attr).setText(text) - self.x_inputshaper[panel_attr] = entry - self.change_page(self.indexOf(self.panel.is_page)) - - def _parse_shaper_csv(self, file_path: str) -> list: - results = [] - try: - with open(file_path, newline="") as csvfile: - reader = csv.DictReader(csvfile) - for row in reader: - if row.get("shaper") and row.get("freq"): - results.append( - { - k: row.get(v, "N/A") - for k, v in { - "shaper": "shaper", - "frequency": "freq", - "vibrations": "vibrations", - "smoothing": "smoothing", - "max_accel": "max_accel", - }.items() - } - ) - except FileNotFoundError: - ... - except csv.Error: - ... - return results - - def apply_input_shaper_selection(self) -> None: - """Apply input shaper results""" - if not (checked_button := self.panel.is_btn_group.checkedButton()): - return - selected_name = checked_button.objectName() - if selected_name == "am_user_input": - self.change_page( - self.indexOf(self.panel.input_shaper_page) - ) # TEST: CHANGED THIS FROM input_shaper_user_input - return - if not (shaper_data := self.x_inputshaper.get(selected_name)): - return - gcode = ( - f"SET_INPUT_SHAPER SHAPER_TYPE={shaper_data['shaper']} " - f"SHAPER_FREQ_{self.axis_in.upper()}={shaper_data['frequency']} " - f"SHAPER_DAMPING_{self.axis_in.upper()}={shaper_data['smoothing']}" - ) - self.run_gcode_signal.emit(gcode) - self.change_page(self.indexOf(self.panel.utilities_page)) - def axis_maintenance(self, axis: str) -> None: """Routine, checks axis movement for printer debugging""" self.current_process = Process.AXIS_MAINTENANCE @@ -617,7 +680,7 @@ def troubleshoot_request(self) -> None: def show_waiting_page(self, page_to_go_to: int, label: str, time_ms: int): """Show placeholder page""" - self.loadPage.label.setText(label) + self.loadPage.set_status_message(label) self.loadPage.show() QtCore.QTimer.singleShot(time_ms, lambda: self.change_page(page_to_go_to)) From 5455b21d014bc2dfe9006ddb755cfd105ec5e634 Mon Sep 17 00:00:00 2001 From: Roberto Date: Mon, 15 Dec 2025 11:51:45 +0000 Subject: [PATCH 4/7] ADD: added input shapper page to .ui --- BlocksScreen/lib/ui/utilitiesStackedWidget.ui | 968 +----------------- .../lib/ui/utilitiesStackedWidget_ui.py | 659 +++--------- 2 files changed, 207 insertions(+), 1420 deletions(-) diff --git a/BlocksScreen/lib/ui/utilitiesStackedWidget.ui b/BlocksScreen/lib/ui/utilitiesStackedWidget.ui index 79a79b8..bcb4a7d 100644 --- a/BlocksScreen/lib/ui/utilitiesStackedWidget.ui +++ b/BlocksScreen/lib/ui/utilitiesStackedWidget.ui @@ -32,7 +32,7 @@ StackedWidget - 9 + 6 @@ -798,6 +798,13 @@ Shaper + + + + Qt::Vertical + + + @@ -862,7 +869,7 @@ Shaper - + 0 0 @@ -1955,569 +1962,15 @@ Shaper - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - Y - - - false - - - true - - - menu_btn - - - :/input_shaper/media/btn_icons/frequency_Y.svg - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - X - - - false - - - true - - - menu_btn - - - :/input_shaper/media/btn_icons/frequency_X.svg - - - - - - - - - - 0 - 0 - - - - - 80 - 80 - - - - - 80 - 80 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - 2 - - - true - - - false - - - true - - - menu_btn - - - :/button_borders/media/buttons/btn_part1.svg - - - :/button_borders/media/buttons/btn_part2.svg - - - :/button_borders/media/buttons/btn_part3.svg - - - normal - - - isc_btn_group - - - - - - - - 0 - 0 - - - - - 80 - 80 - - - - - 80 - 80 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - 3 - - - true - - - false - - - true - - - menu_btn - - - :/button_borders/media/buttons/btn_part1.svg - - - :/button_borders/media/buttons/btn_part2.svg - - - :/button_borders/media/buttons/btn_part3.svg - - - normal - - - isc_btn_group - - - - - - - - 0 - 0 - - - - - 80 - 80 - - - - - 80 - 80 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - 5 - - - true - - - false - - - true - - - menu_btn - - - :/button_borders/media/buttons/btn_part1.svg - - - :/button_borders/media/buttons/btn_part2.svg - - - :/button_borders/media/buttons/btn_part3.svg - - - normal - - - isc_btn_group - - - - - - - - 0 - 0 - - - - - 80 - 80 - - - - - 80 - 80 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - 1 - - - true - - - true - - - false - - - true - - - menu_btn - - - :/button_borders/media/buttons/btn_part1.svg - - - :/button_borders/media/buttons/btn_part2.svg - - - :/button_borders/media/buttons/btn_part3.svg - - - normal - - - isc_btn_group - - - - - - - - 0 - 0 - - - - - 80 - 80 - - - - - 80 - 80 - - - - - Momcake - 20 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - 4 - - - true - - - false - - - true - - - menu_btn - - - :/button_borders/media/buttons/btn_part1.svg - - - :/button_borders/media/buttons/btn_part2.svg - - - :/button_borders/media/buttons/btn_part3.svg - - - normal - - - isc_btn_group - - - - - - - - 11 - - - - color:white - - - Times: - - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 60 - 20 - - - - - + - - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 24 - - - - + + - + @@ -2528,7 +1981,7 @@ Shaper 60 - 0 + 60 @@ -2537,89 +1990,28 @@ Shaper 60 - - Insert Best Text Here - - - Qt::AlignCenter - - - - - - - - - 0 - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - Momcake - 19 - false - PreferAntialias + 20 - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - + color:white - ZV + Input Shaper - - true - - - false - - - true - - - menu_btn - - - + + Qt::AlignCenter - - is_btn_group - - - + + + + + + 0 @@ -2662,7 +2054,7 @@ Shaper - EI + MZV true @@ -2679,13 +2071,10 @@ Shaper - - is_btn_group - - - + + 0 @@ -2728,7 +2117,7 @@ Shaper - MZV + EI true @@ -2745,13 +2134,10 @@ Shaper - - is_btn_group - - + 0 @@ -2811,13 +2197,10 @@ Shaper - - is_btn_group - - - + + 0 @@ -2856,14 +2239,11 @@ Shaper Qt::LeftToRight - - false - - user input + ZV true @@ -2880,13 +2260,10 @@ Shaper - - is_btn_group - - - + + 0 @@ -2946,13 +2323,14 @@ Shaper - - is_btn_group - - - + + + + + + 0 @@ -2995,7 +2373,7 @@ Shaper - Confirm + Cancel false @@ -3007,12 +2385,12 @@ Shaper menu_btn - :/dialog/media/btn_icons/yes.svg + :/dialog/media/btn_icons/no.svg - - + + 0 @@ -3055,7 +2433,7 @@ Shaper - Cancel + Confirm false @@ -3067,7 +2445,7 @@ Shaper menu_btn - :/dialog/media/btn_icons/no.svg + :/dialog/media/btn_icons/yes.svg @@ -3120,255 +2498,23 @@ Shaper - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - Confirm - - - false - - - true - - - menu_btn - - - :/dialog/media/btn_icons/yes.svg - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - Smoothing - - - false - - - true - - - menu_btn - - - display_secondary - - - - - - - - - - - - 0 - 0 - - - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - Frequency - - - false - - - true - - - display_secondary - - - - - - - + + + - + 0 0 - - - 250 - 80 - - - - - 250 - 80 - - - - - Momcake - 19 - false - PreferAntialias - - - - false - - - true - - - Qt::NoContextMenu - - - Qt::LeftToRight - - - - - - Back - - - false - - - true - - - menu_btn + + QFrame::StyledPanel - - :/ui/media/btn_icons/back.svg + + QFrame::Raised - - - @@ -3670,8 +2816,4 @@ Shaper - - - - diff --git a/BlocksScreen/lib/ui/utilitiesStackedWidget_ui.py b/BlocksScreen/lib/ui/utilitiesStackedWidget_ui.py index 987ed2f..061fe70 100644 --- a/BlocksScreen/lib/ui/utilitiesStackedWidget_ui.py +++ b/BlocksScreen/lib/ui/utilitiesStackedWidget_ui.py @@ -1,4 +1,4 @@ -# Form implementation generated from reading ui file '/home/levi/main/Blocks_Screen/BlocksScreen/lib/ui/utilitiesStackedWidget.ui' +# Form implementation generated from reading ui file '/home/levi/BlocksScreen/BlocksScreen/lib/ui/utilitiesStackedWidget.ui' # # Created by: PyQt6 UI code generator 6.7.1 # @@ -325,6 +325,10 @@ def setupUi(self, utilitiesStackedWidget): self.verticalLayout_4.addLayout(self.leds_header_layout) spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) self.verticalLayout_4.addItem(spacerItem4) + self.verticalScrollBar = QtWidgets.QScrollBar(parent=self.leds_page) + self.verticalScrollBar.setOrientation(QtCore.Qt.Orientation.Vertical) + self.verticalScrollBar.setObjectName("verticalScrollBar") + self.verticalLayout_4.addWidget(self.verticalScrollBar) self.leds_content_layout = QtWidgets.QGridLayout() self.leds_content_layout.setObjectName("leds_content_layout") self.leds_widget = QtWidgets.QWidget(parent=self.leds_page) @@ -346,7 +350,7 @@ def setupUi(self, utilitiesStackedWidget): spacerItem7 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) self.routines_header_layout.addItem(spacerItem7) self.routines_page_title = QtWidgets.QLabel(parent=self.routines_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.routines_page_title.sizePolicy().hasHeightForWidth()) @@ -769,391 +773,180 @@ def setupUi(self, utilitiesStackedWidget): self.verticalLayout_13.addLayout(self.is_header_layout) self.is_content_layout = QtWidgets.QHBoxLayout() self.is_content_layout.setObjectName("is_content_layout") - self.is_xy_layout = QtWidgets.QGridLayout() - self.is_xy_layout.setObjectName("is_xy_layout") - self.is_Y_startis_btn = BlocksCustomButton(parent=self.input_shaper_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.is_Y_startis_btn.sizePolicy().hasHeightForWidth()) - self.is_Y_startis_btn.setSizePolicy(sizePolicy) - self.is_Y_startis_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.is_Y_startis_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.is_Y_startis_btn.setFont(font) - self.is_Y_startis_btn.setMouseTracking(False) - self.is_Y_startis_btn.setTabletTracking(True) - self.is_Y_startis_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.is_Y_startis_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.is_Y_startis_btn.setStyleSheet("") - self.is_Y_startis_btn.setAutoDefault(False) - self.is_Y_startis_btn.setFlat(True) - self.is_Y_startis_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/input_shaper/media/btn_icons/frequency_Y.svg")) - self.is_Y_startis_btn.setObjectName("is_Y_startis_btn") - self.is_xy_layout.addWidget(self.is_Y_startis_btn, 1, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.is_X_startis_btn = BlocksCustomButton(parent=self.input_shaper_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.is_X_startis_btn.sizePolicy().hasHeightForWidth()) - self.is_X_startis_btn.setSizePolicy(sizePolicy) - self.is_X_startis_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.is_X_startis_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.is_X_startis_btn.setFont(font) - self.is_X_startis_btn.setMouseTracking(False) - self.is_X_startis_btn.setTabletTracking(True) - self.is_X_startis_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.is_X_startis_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.is_X_startis_btn.setStyleSheet("") - self.is_X_startis_btn.setAutoDefault(False) - self.is_X_startis_btn.setFlat(True) - self.is_X_startis_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/input_shaper/media/btn_icons/frequency_X.svg")) - self.is_X_startis_btn.setObjectName("is_X_startis_btn") - self.is_xy_layout.addWidget(self.is_X_startis_btn, 0, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.gridLayout = QtWidgets.QGridLayout() - self.gridLayout.setObjectName("gridLayout") - self.btn2 = GroupButton(parent=self.input_shaper_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.btn2.sizePolicy().hasHeightForWidth()) - self.btn2.setSizePolicy(sizePolicy) - self.btn2.setMinimumSize(QtCore.QSize(80, 80)) - self.btn2.setMaximumSize(QtCore.QSize(80, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.btn2.setFont(font) - self.btn2.setMouseTracking(False) - self.btn2.setTabletTracking(True) - self.btn2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.btn2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.btn2.setStyleSheet("") - self.btn2.setCheckable(True) - self.btn2.setAutoDefault(False) - self.btn2.setFlat(True) - self.btn2.setProperty("borderLeftPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part1.svg")) - self.btn2.setProperty("borderCenterPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part2.svg")) - self.btn2.setProperty("borderRightPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part3.svg")) - self.btn2.setObjectName("btn2") - self.isc_btn_group = QtWidgets.QButtonGroup(utilitiesStackedWidget) - self.isc_btn_group.setObjectName("isc_btn_group") - self.isc_btn_group.addButton(self.btn2) - self.gridLayout.addWidget(self.btn2, 1, 1, 1, 1) - self.btn3 = GroupButton(parent=self.input_shaper_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.btn3.sizePolicy().hasHeightForWidth()) - self.btn3.setSizePolicy(sizePolicy) - self.btn3.setMinimumSize(QtCore.QSize(80, 80)) - self.btn3.setMaximumSize(QtCore.QSize(80, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.btn3.setFont(font) - self.btn3.setMouseTracking(False) - self.btn3.setTabletTracking(True) - self.btn3.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.btn3.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.btn3.setStyleSheet("") - self.btn3.setCheckable(True) - self.btn3.setAutoDefault(False) - self.btn3.setFlat(True) - self.btn3.setProperty("borderLeftPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part1.svg")) - self.btn3.setProperty("borderCenterPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part2.svg")) - self.btn3.setProperty("borderRightPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part3.svg")) - self.btn3.setObjectName("btn3") - self.isc_btn_group.addButton(self.btn3) - self.gridLayout.addWidget(self.btn3, 2, 0, 1, 1) - self.btn5 = GroupButton(parent=self.input_shaper_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.btn5.sizePolicy().hasHeightForWidth()) - self.btn5.setSizePolicy(sizePolicy) - self.btn5.setMinimumSize(QtCore.QSize(80, 80)) - self.btn5.setMaximumSize(QtCore.QSize(80, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.btn5.setFont(font) - self.btn5.setMouseTracking(False) - self.btn5.setTabletTracking(True) - self.btn5.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.btn5.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.btn5.setStyleSheet("") - self.btn5.setCheckable(True) - self.btn5.setAutoDefault(False) - self.btn5.setFlat(True) - self.btn5.setProperty("borderLeftPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part1.svg")) - self.btn5.setProperty("borderCenterPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part2.svg")) - self.btn5.setProperty("borderRightPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part3.svg")) - self.btn5.setObjectName("btn5") - self.isc_btn_group.addButton(self.btn5) - self.gridLayout.addWidget(self.btn5, 3, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.btn1 = GroupButton(parent=self.input_shaper_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.btn1.sizePolicy().hasHeightForWidth()) - self.btn1.setSizePolicy(sizePolicy) - self.btn1.setMinimumSize(QtCore.QSize(80, 80)) - self.btn1.setMaximumSize(QtCore.QSize(80, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.btn1.setFont(font) - self.btn1.setMouseTracking(False) - self.btn1.setTabletTracking(True) - self.btn1.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.btn1.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.btn1.setStyleSheet("") - self.btn1.setCheckable(True) - self.btn1.setChecked(True) - self.btn1.setAutoDefault(False) - self.btn1.setFlat(True) - self.btn1.setProperty("borderLeftPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part1.svg")) - self.btn1.setProperty("borderCenterPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part2.svg")) - self.btn1.setProperty("borderRightPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part3.svg")) - self.btn1.setObjectName("btn1") - self.isc_btn_group.addButton(self.btn1) - self.gridLayout.addWidget(self.btn1, 1, 0, 1, 1) - self.btn4 = GroupButton(parent=self.input_shaper_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.btn4.sizePolicy().hasHeightForWidth()) - self.btn4.setSizePolicy(sizePolicy) - self.btn4.setMinimumSize(QtCore.QSize(80, 80)) - self.btn4.setMaximumSize(QtCore.QSize(80, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(20) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.btn4.setFont(font) - self.btn4.setMouseTracking(False) - self.btn4.setTabletTracking(True) - self.btn4.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.btn4.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.btn4.setStyleSheet("") - self.btn4.setCheckable(True) - self.btn4.setAutoDefault(False) - self.btn4.setFlat(True) - self.btn4.setProperty("borderLeftPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part1.svg")) - self.btn4.setProperty("borderCenterPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part2.svg")) - self.btn4.setProperty("borderRightPixmap", QtGui.QPixmap(":/button_borders/media/buttons/btn_part3.svg")) - self.btn4.setObjectName("btn4") - self.isc_btn_group.addButton(self.btn4) - self.gridLayout.addWidget(self.btn4, 2, 1, 1, 1) - self.label = QtWidgets.QLabel(parent=self.input_shaper_page) - font = QtGui.QFont() - font.setPointSize(11) - self.label.setFont(font) - self.label.setStyleSheet("color:white") - self.label.setObjectName("label") - self.gridLayout.addWidget(self.label, 0, 0, 1, 2) - self.is_xy_layout.addLayout(self.gridLayout, 0, 2, 2, 1) - self.is_content_layout.addLayout(self.is_xy_layout) - spacerItem18 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.is_content_layout.addItem(spacerItem18) self.verticalLayout_13.addLayout(self.is_content_layout) utilitiesStackedWidget.addWidget(self.input_shaper_page) - self.is_page = QtWidgets.QWidget() - self.is_page.setObjectName("is_page") - self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.is_page) - self.verticalLayout_8.setObjectName("verticalLayout_8") - spacerItem19 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_8.addItem(spacerItem19) + self.manual_is_res_page = QtWidgets.QWidget() + self.manual_is_res_page.setObjectName("manual_is_res_page") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.manual_is_res_page) + self.verticalLayout_3.setObjectName("verticalLayout_3") self.horizontalLayout_4 = QtWidgets.QHBoxLayout() self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.label_3 = QtWidgets.QLabel(parent=self.is_page) + self.label_3 = QtWidgets.QLabel(parent=self.manual_is_res_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth()) self.label_3.setSizePolicy(sizePolicy) - self.label_3.setMinimumSize(QtCore.QSize(60, 0)) + self.label_3.setMinimumSize(QtCore.QSize(60, 60)) self.label_3.setMaximumSize(QtCore.QSize(16777215, 60)) + font = QtGui.QFont() + font.setPointSize(20) + self.label_3.setFont(font) + self.label_3.setStyleSheet("color:white") self.label_3.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.label_3.setObjectName("label_3") - self.horizontalLayout_4.addWidget(self.label_3) - self.verticalLayout_8.addLayout(self.horizontalLayout_4) - self.gridLayout_4 = QtWidgets.QGridLayout() - self.gridLayout_4.setSpacing(0) - self.gridLayout_4.setObjectName("gridLayout_4") - self.am_zv = GroupButton(parent=self.is_page) + self.horizontalLayout_4.addWidget(self.label_3, 0, QtCore.Qt.AlignmentFlag.AlignHCenter|QtCore.Qt.AlignmentFlag.AlignVCenter) + self.verticalLayout_3.addLayout(self.horizontalLayout_4) + self.gridLayout_3 = QtWidgets.QGridLayout() + self.gridLayout_3.setObjectName("gridLayout_3") + self.am_mzv_2 = GroupButton(parent=self.manual_is_res_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_zv.sizePolicy().hasHeightForWidth()) - self.am_zv.setSizePolicy(sizePolicy) - self.am_zv.setMinimumSize(QtCore.QSize(250, 80)) - self.am_zv.setMaximumSize(QtCore.QSize(250, 80)) + sizePolicy.setHeightForWidth(self.am_mzv_2.sizePolicy().hasHeightForWidth()) + self.am_mzv_2.setSizePolicy(sizePolicy) + self.am_mzv_2.setMinimumSize(QtCore.QSize(250, 80)) + self.am_mzv_2.setMaximumSize(QtCore.QSize(250, 80)) font = QtGui.QFont() font.setFamily("Momcake") font.setPointSize(19) font.setItalic(False) font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_zv.setFont(font) - self.am_zv.setMouseTracking(False) - self.am_zv.setTabletTracking(True) - self.am_zv.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_zv.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_zv.setStyleSheet("") - self.am_zv.setCheckable(True) - self.am_zv.setAutoDefault(False) - self.am_zv.setFlat(True) - self.am_zv.setObjectName("am_zv") - self.is_btn_group = QtWidgets.QButtonGroup(utilitiesStackedWidget) - self.is_btn_group.setObjectName("is_btn_group") - self.is_btn_group.addButton(self.am_zv) - self.gridLayout_4.addWidget(self.am_zv, 0, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.am_ei = GroupButton(parent=self.is_page) + self.am_mzv_2.setFont(font) + self.am_mzv_2.setMouseTracking(False) + self.am_mzv_2.setTabletTracking(True) + self.am_mzv_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.am_mzv_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.am_mzv_2.setStyleSheet("") + self.am_mzv_2.setCheckable(True) + self.am_mzv_2.setAutoDefault(False) + self.am_mzv_2.setFlat(True) + self.am_mzv_2.setObjectName("am_mzv_2") + self.gridLayout_3.addWidget(self.am_mzv_2, 0, 1, 1, 1) + self.am_ei_2 = GroupButton(parent=self.manual_is_res_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_ei.sizePolicy().hasHeightForWidth()) - self.am_ei.setSizePolicy(sizePolicy) - self.am_ei.setMinimumSize(QtCore.QSize(250, 80)) - self.am_ei.setMaximumSize(QtCore.QSize(250, 80)) + sizePolicy.setHeightForWidth(self.am_ei_2.sizePolicy().hasHeightForWidth()) + self.am_ei_2.setSizePolicy(sizePolicy) + self.am_ei_2.setMinimumSize(QtCore.QSize(250, 80)) + self.am_ei_2.setMaximumSize(QtCore.QSize(250, 80)) font = QtGui.QFont() font.setFamily("Momcake") font.setPointSize(19) font.setItalic(False) font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_ei.setFont(font) - self.am_ei.setMouseTracking(False) - self.am_ei.setTabletTracking(True) - self.am_ei.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_ei.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_ei.setStyleSheet("") - self.am_ei.setCheckable(True) - self.am_ei.setAutoDefault(False) - self.am_ei.setFlat(True) - self.am_ei.setObjectName("am_ei") - self.is_btn_group.addButton(self.am_ei) - self.gridLayout_4.addWidget(self.am_ei, 0, 2, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.am_mzv = GroupButton(parent=self.is_page) + self.am_ei_2.setFont(font) + self.am_ei_2.setMouseTracking(False) + self.am_ei_2.setTabletTracking(True) + self.am_ei_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.am_ei_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.am_ei_2.setStyleSheet("") + self.am_ei_2.setCheckable(True) + self.am_ei_2.setAutoDefault(False) + self.am_ei_2.setFlat(True) + self.am_ei_2.setObjectName("am_ei_2") + self.gridLayout_3.addWidget(self.am_ei_2, 1, 0, 1, 1) + self.am_3hump_ei_2 = GroupButton(parent=self.manual_is_res_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_mzv.sizePolicy().hasHeightForWidth()) - self.am_mzv.setSizePolicy(sizePolicy) - self.am_mzv.setMinimumSize(QtCore.QSize(250, 80)) - self.am_mzv.setMaximumSize(QtCore.QSize(250, 80)) + sizePolicy.setHeightForWidth(self.am_3hump_ei_2.sizePolicy().hasHeightForWidth()) + self.am_3hump_ei_2.setSizePolicy(sizePolicy) + self.am_3hump_ei_2.setMinimumSize(QtCore.QSize(250, 80)) + self.am_3hump_ei_2.setMaximumSize(QtCore.QSize(250, 80)) font = QtGui.QFont() font.setFamily("Momcake") font.setPointSize(19) font.setItalic(False) font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_mzv.setFont(font) - self.am_mzv.setMouseTracking(False) - self.am_mzv.setTabletTracking(True) - self.am_mzv.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_mzv.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_mzv.setStyleSheet("") - self.am_mzv.setCheckable(True) - self.am_mzv.setAutoDefault(False) - self.am_mzv.setFlat(True) - self.am_mzv.setObjectName("am_mzv") - self.is_btn_group.addButton(self.am_mzv) - self.gridLayout_4.addWidget(self.am_mzv, 1, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.am_3hump_ei = GroupButton(parent=self.is_page) + self.am_3hump_ei_2.setFont(font) + self.am_3hump_ei_2.setMouseTracking(False) + self.am_3hump_ei_2.setTabletTracking(True) + self.am_3hump_ei_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.am_3hump_ei_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.am_3hump_ei_2.setStyleSheet("") + self.am_3hump_ei_2.setCheckable(True) + self.am_3hump_ei_2.setAutoDefault(False) + self.am_3hump_ei_2.setFlat(True) + self.am_3hump_ei_2.setObjectName("am_3hump_ei_2") + self.gridLayout_3.addWidget(self.am_3hump_ei_2, 2, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) + self.am_zv_2 = GroupButton(parent=self.manual_is_res_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_3hump_ei.sizePolicy().hasHeightForWidth()) - self.am_3hump_ei.setSizePolicy(sizePolicy) - self.am_3hump_ei.setMinimumSize(QtCore.QSize(250, 80)) - self.am_3hump_ei.setMaximumSize(QtCore.QSize(250, 80)) + sizePolicy.setHeightForWidth(self.am_zv_2.sizePolicy().hasHeightForWidth()) + self.am_zv_2.setSizePolicy(sizePolicy) + self.am_zv_2.setMinimumSize(QtCore.QSize(250, 80)) + self.am_zv_2.setMaximumSize(QtCore.QSize(250, 80)) font = QtGui.QFont() font.setFamily("Momcake") font.setPointSize(19) font.setItalic(False) font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_3hump_ei.setFont(font) - self.am_3hump_ei.setMouseTracking(False) - self.am_3hump_ei.setTabletTracking(True) - self.am_3hump_ei.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_3hump_ei.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_3hump_ei.setStyleSheet("") - self.am_3hump_ei.setCheckable(True) - self.am_3hump_ei.setAutoDefault(False) - self.am_3hump_ei.setFlat(True) - self.am_3hump_ei.setObjectName("am_3hump_ei") - self.is_btn_group.addButton(self.am_3hump_ei) - self.gridLayout_4.addWidget(self.am_3hump_ei, 2, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.am_user_input = GroupButton(parent=self.is_page) + self.am_zv_2.setFont(font) + self.am_zv_2.setMouseTracking(False) + self.am_zv_2.setTabletTracking(True) + self.am_zv_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.am_zv_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.am_zv_2.setStyleSheet("") + self.am_zv_2.setCheckable(True) + self.am_zv_2.setAutoDefault(False) + self.am_zv_2.setFlat(True) + self.am_zv_2.setObjectName("am_zv_2") + self.gridLayout_3.addWidget(self.am_zv_2, 0, 0, 1, 1) + self.am_2hump_ei_2 = GroupButton(parent=self.manual_is_res_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_user_input.sizePolicy().hasHeightForWidth()) - self.am_user_input.setSizePolicy(sizePolicy) - self.am_user_input.setMinimumSize(QtCore.QSize(250, 80)) - self.am_user_input.setMaximumSize(QtCore.QSize(250, 80)) + sizePolicy.setHeightForWidth(self.am_2hump_ei_2.sizePolicy().hasHeightForWidth()) + self.am_2hump_ei_2.setSizePolicy(sizePolicy) + self.am_2hump_ei_2.setMinimumSize(QtCore.QSize(250, 80)) + self.am_2hump_ei_2.setMaximumSize(QtCore.QSize(250, 80)) font = QtGui.QFont() font.setFamily("Momcake") font.setPointSize(19) font.setItalic(False) font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_user_input.setFont(font) - self.am_user_input.setMouseTracking(False) - self.am_user_input.setTabletTracking(True) - self.am_user_input.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_user_input.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_user_input.setAutoFillBackground(False) - self.am_user_input.setStyleSheet("") - self.am_user_input.setCheckable(True) - self.am_user_input.setAutoDefault(False) - self.am_user_input.setFlat(True) - self.am_user_input.setObjectName("am_user_input") - self.is_btn_group.addButton(self.am_user_input) - self.gridLayout_4.addWidget(self.am_user_input, 2, 2, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.am_2hump_ei = GroupButton(parent=self.is_page) + self.am_2hump_ei_2.setFont(font) + self.am_2hump_ei_2.setMouseTracking(False) + self.am_2hump_ei_2.setTabletTracking(True) + self.am_2hump_ei_2.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.am_2hump_ei_2.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.am_2hump_ei_2.setStyleSheet("") + self.am_2hump_ei_2.setCheckable(True) + self.am_2hump_ei_2.setAutoDefault(False) + self.am_2hump_ei_2.setFlat(True) + self.am_2hump_ei_2.setObjectName("am_2hump_ei_2") + self.gridLayout_3.addWidget(self.am_2hump_ei_2, 1, 1, 1, 1) + self.verticalLayout_3.addLayout(self.gridLayout_3) + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.am_cancel = BlocksCustomButton(parent=self.manual_is_res_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_2hump_ei.sizePolicy().hasHeightForWidth()) - self.am_2hump_ei.setSizePolicy(sizePolicy) - self.am_2hump_ei.setMinimumSize(QtCore.QSize(250, 80)) - self.am_2hump_ei.setMaximumSize(QtCore.QSize(250, 80)) + sizePolicy.setHeightForWidth(self.am_cancel.sizePolicy().hasHeightForWidth()) + self.am_cancel.setSizePolicy(sizePolicy) + self.am_cancel.setMinimumSize(QtCore.QSize(250, 80)) + self.am_cancel.setMaximumSize(QtCore.QSize(250, 80)) font = QtGui.QFont() font.setFamily("Momcake") font.setPointSize(19) font.setItalic(False) font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_2hump_ei.setFont(font) - self.am_2hump_ei.setMouseTracking(False) - self.am_2hump_ei.setTabletTracking(True) - self.am_2hump_ei.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_2hump_ei.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_2hump_ei.setStyleSheet("") - self.am_2hump_ei.setCheckable(True) - self.am_2hump_ei.setAutoDefault(False) - self.am_2hump_ei.setFlat(True) - self.am_2hump_ei.setObjectName("am_2hump_ei") - self.is_btn_group.addButton(self.am_2hump_ei) - self.gridLayout_4.addWidget(self.am_2hump_ei, 1, 2, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.am_confirm = BlocksCustomButton(parent=self.is_page) + self.am_cancel.setFont(font) + self.am_cancel.setMouseTracking(False) + self.am_cancel.setTabletTracking(True) + self.am_cancel.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) + self.am_cancel.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.am_cancel.setStyleSheet("") + self.am_cancel.setAutoDefault(False) + self.am_cancel.setFlat(True) + self.am_cancel.setProperty("icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/no.svg")) + self.am_cancel.setObjectName("am_cancel") + self.horizontalLayout.addWidget(self.am_cancel) + self.am_confirm = BlocksCustomButton(parent=self.manual_is_res_page) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -1176,39 +969,15 @@ def setupUi(self, utilitiesStackedWidget): self.am_confirm.setFlat(True) self.am_confirm.setProperty("icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg")) self.am_confirm.setObjectName("am_confirm") - self.gridLayout_4.addWidget(self.am_confirm, 3, 2, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.am_cancel = BlocksCustomButton(parent=self.is_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.am_cancel.sizePolicy().hasHeightForWidth()) - self.am_cancel.setSizePolicy(sizePolicy) - self.am_cancel.setMinimumSize(QtCore.QSize(250, 80)) - self.am_cancel.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.am_cancel.setFont(font) - self.am_cancel.setMouseTracking(False) - self.am_cancel.setTabletTracking(True) - self.am_cancel.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.am_cancel.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.am_cancel.setStyleSheet("") - self.am_cancel.setAutoDefault(False) - self.am_cancel.setFlat(True) - self.am_cancel.setProperty("icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/no.svg")) - self.am_cancel.setObjectName("am_cancel") - self.gridLayout_4.addWidget(self.am_cancel, 3, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.verticalLayout_8.addLayout(self.gridLayout_4) - utilitiesStackedWidget.addWidget(self.is_page) + self.horizontalLayout.addWidget(self.am_confirm) + self.verticalLayout_3.addLayout(self.horizontalLayout) + utilitiesStackedWidget.addWidget(self.manual_is_res_page) self.user_input_page = QtWidgets.QWidget() self.user_input_page.setObjectName("user_input_page") self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.user_input_page) self.verticalLayout_9.setObjectName("verticalLayout_9") - spacerItem20 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.verticalLayout_9.addItem(spacerItem20) + spacerItem18 = QtWidgets.QSpacerItem(20, 24, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) + self.verticalLayout_9.addItem(spacerItem18) self.horizontalLayout_5 = QtWidgets.QHBoxLayout() self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.label_8 = QtWidgets.QLabel(parent=self.user_input_page) @@ -1222,112 +991,19 @@ def setupUi(self, utilitiesStackedWidget): self.label_8.setObjectName("label_8") self.horizontalLayout_5.addWidget(self.label_8) self.verticalLayout_9.addLayout(self.horizontalLayout_5) - self.gridLayout_5 = QtWidgets.QGridLayout() - self.gridLayout_5.setObjectName("gridLayout_5") - self.is_confirm_btn = BlocksCustomButton(parent=self.user_input_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.is_confirm_btn.sizePolicy().hasHeightForWidth()) - self.is_confirm_btn.setSizePolicy(sizePolicy) - self.is_confirm_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.is_confirm_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.is_confirm_btn.setFont(font) - self.is_confirm_btn.setMouseTracking(False) - self.is_confirm_btn.setTabletTracking(True) - self.is_confirm_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.is_confirm_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.is_confirm_btn.setStyleSheet("") - self.is_confirm_btn.setAutoDefault(False) - self.is_confirm_btn.setFlat(True) - self.is_confirm_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg")) - self.is_confirm_btn.setObjectName("is_confirm_btn") - self.gridLayout_5.addWidget(self.is_confirm_btn, 2, 2, 1, 1, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.horizontalLayout_8 = QtWidgets.QHBoxLayout() - self.horizontalLayout_8.setObjectName("horizontalLayout_8") - self.isui_sm = BlocksCustomButton(parent=self.user_input_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.isui_sm.sizePolicy().hasHeightForWidth()) - self.isui_sm.setSizePolicy(sizePolicy) - self.isui_sm.setMinimumSize(QtCore.QSize(250, 80)) - self.isui_sm.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.isui_sm.setFont(font) - self.isui_sm.setMouseTracking(False) - self.isui_sm.setTabletTracking(True) - self.isui_sm.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.isui_sm.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.isui_sm.setStyleSheet("") - self.isui_sm.setAutoDefault(False) - self.isui_sm.setFlat(True) - self.isui_sm.setObjectName("isui_sm") - self.horizontalLayout_8.addWidget(self.isui_sm, 0, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.gridLayout_5.addLayout(self.horizontalLayout_8, 0, 2, 1, 1) - self.horizontalLayout_9 = QtWidgets.QHBoxLayout() - self.horizontalLayout_9.setObjectName("horizontalLayout_9") - self.isui_fq = BlocksCustomButton(parent=self.user_input_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.isui_fq.sizePolicy().hasHeightForWidth()) - self.isui_fq.setSizePolicy(sizePolicy) - self.isui_fq.setMinimumSize(QtCore.QSize(250, 80)) - self.isui_fq.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.isui_fq.setFont(font) - self.isui_fq.setMouseTracking(False) - self.isui_fq.setTabletTracking(True) - self.isui_fq.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.isui_fq.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.isui_fq.setStyleSheet("") - self.isui_fq.setAutoDefault(False) - self.isui_fq.setFlat(True) - self.isui_fq.setObjectName("isui_fq") - self.horizontalLayout_9.addWidget(self.isui_fq, 0, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.gridLayout_5.addLayout(self.horizontalLayout_9, 1, 2, 1, 1) - self.is_back_btn = BlocksCustomButton(parent=self.user_input_page) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.MinimumExpanding) + self.verticalLayout_10 = QtWidgets.QVBoxLayout() + self.verticalLayout_10.setObjectName("verticalLayout_10") + self.frame_4 = QtWidgets.QFrame(parent=self.user_input_page) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.is_back_btn.sizePolicy().hasHeightForWidth()) - self.is_back_btn.setSizePolicy(sizePolicy) - self.is_back_btn.setMinimumSize(QtCore.QSize(250, 80)) - self.is_back_btn.setMaximumSize(QtCore.QSize(250, 80)) - font = QtGui.QFont() - font.setFamily("Momcake") - font.setPointSize(19) - font.setItalic(False) - font.setStyleStrategy(QtGui.QFont.StyleStrategy.PreferAntialias) - self.is_back_btn.setFont(font) - self.is_back_btn.setMouseTracking(False) - self.is_back_btn.setTabletTracking(True) - self.is_back_btn.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.NoContextMenu) - self.is_back_btn.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.is_back_btn.setStyleSheet("") - self.is_back_btn.setAutoDefault(False) - self.is_back_btn.setFlat(True) - self.is_back_btn.setProperty("icon_pixmap", QtGui.QPixmap(":/ui/media/btn_icons/back.svg")) - self.is_back_btn.setObjectName("is_back_btn") - self.gridLayout_5.addWidget(self.is_back_btn, 2, 0, 1, 2, QtCore.Qt.AlignmentFlag.AlignHCenter) - self.horizontalLayout_6 = QtWidgets.QHBoxLayout() - self.horizontalLayout_6.setObjectName("horizontalLayout_6") - self.gridLayout_5.addLayout(self.horizontalLayout_6, 0, 0, 2, 2) - self.verticalLayout_9.addLayout(self.gridLayout_5) + sizePolicy.setHeightForWidth(self.frame_4.sizePolicy().hasHeightForWidth()) + self.frame_4.setSizePolicy(sizePolicy) + self.frame_4.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.frame_4.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.frame_4.setObjectName("frame_4") + self.verticalLayout_10.addWidget(self.frame_4) + self.verticalLayout_9.addLayout(self.verticalLayout_10) utilitiesStackedWidget.addWidget(self.user_input_page) self.leds_slider_page = QtWidgets.QWidget() self.leds_slider_page.setObjectName("leds_slider_page") @@ -1360,8 +1036,8 @@ def setupUi(self, utilitiesStackedWidget): self.leds_slider_header_layout = QtWidgets.QHBoxLayout(self.layoutWidget) self.leds_slider_header_layout.setContentsMargins(0, 0, 0, 0) self.leds_slider_header_layout.setObjectName("leds_slider_header_layout") - spacerItem21 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) - self.leds_slider_header_layout.addItem(spacerItem21) + spacerItem19 = QtWidgets.QSpacerItem(60, 20, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) + self.leds_slider_header_layout.addItem(spacerItem19) self.leds_slider_tittle_label = QtWidgets.QLabel(parent=self.layoutWidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Preferred) sizePolicy.setHorizontalStretch(0) @@ -1424,7 +1100,7 @@ def setupUi(self, utilitiesStackedWidget): utilitiesStackedWidget.addWidget(self.leds_slider_page) self.retranslateUi(utilitiesStackedWidget) - utilitiesStackedWidget.setCurrentIndex(9) + utilitiesStackedWidget.setCurrentIndex(6) QtCore.QMetaObject.connectSlotsByName(utilitiesStackedWidget) def retranslateUi(self, utilitiesStackedWidget): @@ -1495,53 +1171,22 @@ def retranslateUi(self, utilitiesStackedWidget): self.input_shaper_back_btn.setText(_translate("utilitiesStackedWidget", "Back")) self.input_shaper_back_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) self.input_shaper_back_btn.setProperty("button_type", _translate("utilitiesStackedWidget", "icon")) - self.is_Y_startis_btn.setText(_translate("utilitiesStackedWidget", "Y")) - self.is_Y_startis_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.is_X_startis_btn.setText(_translate("utilitiesStackedWidget", "X")) - self.is_X_startis_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.btn2.setText(_translate("utilitiesStackedWidget", "2")) - self.btn2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.btn2.setProperty("button_type", _translate("utilitiesStackedWidget", "normal")) - self.btn3.setText(_translate("utilitiesStackedWidget", "3")) - self.btn3.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.btn3.setProperty("button_type", _translate("utilitiesStackedWidget", "normal")) - self.btn5.setText(_translate("utilitiesStackedWidget", "5")) - self.btn5.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.btn5.setProperty("button_type", _translate("utilitiesStackedWidget", "normal")) - self.btn1.setText(_translate("utilitiesStackedWidget", "1")) - self.btn1.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.btn1.setProperty("button_type", _translate("utilitiesStackedWidget", "normal")) - self.btn4.setText(_translate("utilitiesStackedWidget", "4")) - self.btn4.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.btn4.setProperty("button_type", _translate("utilitiesStackedWidget", "normal")) - self.label.setText(_translate("utilitiesStackedWidget", "Times:")) - self.label_3.setText(_translate("utilitiesStackedWidget", "Insert Best Text Here")) - self.am_zv.setText(_translate("utilitiesStackedWidget", "ZV")) - self.am_zv.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_ei.setText(_translate("utilitiesStackedWidget", "EI")) - self.am_ei.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_mzv.setText(_translate("utilitiesStackedWidget", "MZV")) - self.am_mzv.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_3hump_ei.setText(_translate("utilitiesStackedWidget", "3hump_ei")) - self.am_3hump_ei.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_user_input.setText(_translate("utilitiesStackedWidget", "user input")) - self.am_user_input.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_2hump_ei.setText(_translate("utilitiesStackedWidget", "2hump_ei")) - self.am_2hump_ei.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.am_confirm.setText(_translate("utilitiesStackedWidget", "Confirm")) - self.am_confirm.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) + self.label_3.setText(_translate("utilitiesStackedWidget", "Input Shaper ")) + self.am_mzv_2.setText(_translate("utilitiesStackedWidget", "MZV")) + self.am_mzv_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) + self.am_ei_2.setText(_translate("utilitiesStackedWidget", "EI")) + self.am_ei_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) + self.am_3hump_ei_2.setText(_translate("utilitiesStackedWidget", "3hump_ei")) + self.am_3hump_ei_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) + self.am_zv_2.setText(_translate("utilitiesStackedWidget", "ZV")) + self.am_zv_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) + self.am_2hump_ei_2.setText(_translate("utilitiesStackedWidget", "2hump_ei")) + self.am_2hump_ei_2.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) self.am_cancel.setText(_translate("utilitiesStackedWidget", "Cancel")) self.am_cancel.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) + self.am_confirm.setText(_translate("utilitiesStackedWidget", "Confirm")) + self.am_confirm.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) self.label_8.setText(_translate("utilitiesStackedWidget", "User Input")) - self.is_confirm_btn.setText(_translate("utilitiesStackedWidget", "Confirm")) - self.is_confirm_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.isui_sm.setText(_translate("utilitiesStackedWidget", "Smoothing")) - self.isui_sm.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) - self.isui_sm.setProperty("button_type", _translate("utilitiesStackedWidget", "display_secondary")) - self.isui_fq.setText(_translate("utilitiesStackedWidget", "Frequency")) - self.isui_fq.setProperty("button_type", _translate("utilitiesStackedWidget", "display_secondary")) - self.is_back_btn.setText(_translate("utilitiesStackedWidget", "Back")) - self.is_back_btn.setProperty("class", _translate("utilitiesStackedWidget", "menu_btn")) self.toggle_led_button.setText(_translate("utilitiesStackedWidget", "PushButton")) self.label_4.setText(_translate("utilitiesStackedWidget", "On")) self.label_5.setText(_translate("utilitiesStackedWidget", "Off")) From bf1f138cb54cbeafe79424663ef4fd59635c8814 Mon Sep 17 00:00:00 2001 From: Roberto Date: Tue, 16 Dec 2025 11:27:28 +0000 Subject: [PATCH 5/7] Add: basepopup.py Refactor: loadwidget to have similar logic to loadpage Removed: dialog page and loadPage --- BlocksScreen/lib/panels/widgets/basePopup.py | 256 ++++++++++++++++++ BlocksScreen/lib/panels/widgets/dialogPage.py | 167 ------------ BlocksScreen/lib/panels/widgets/loadPage.py | 180 ------------ BlocksScreen/lib/panels/widgets/loadWidget.py | 145 +++++++--- 4 files changed, 370 insertions(+), 378 deletions(-) create mode 100644 BlocksScreen/lib/panels/widgets/basePopup.py delete mode 100644 BlocksScreen/lib/panels/widgets/dialogPage.py delete mode 100644 BlocksScreen/lib/panels/widgets/loadPage.py diff --git a/BlocksScreen/lib/panels/widgets/basePopup.py b/BlocksScreen/lib/panels/widgets/basePopup.py new file mode 100644 index 0000000..e9ebe5d --- /dev/null +++ b/BlocksScreen/lib/panels/widgets/basePopup.py @@ -0,0 +1,256 @@ +import typing + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class BasePopup(QtWidgets.QDialog): + """Simple popup with custom message and Confirm/Back buttons + + To assert if the user accepted or rejected the dialog connect to the **accepted()** or **rejected()** signals. + + The `finished()` signal can also be used to get the result of the dialog. This is emitted after + the accepted and rejected signals. + + + """ + + x_offset: float = 0.7 + y_offset: float = 0.7 + border_radius: int = 20 + border_margin: int = 5 + + def __init__( + self, + parent: QtWidgets.QWidget, # Make parent optional for easier testing + floating: bool = False, + dialog: bool = True, + ) -> None: + super().__init__(parent) + + self.setWindowFlags( + QtCore.Qt.WindowType.Popup | QtCore.Qt.WindowType.FramelessWindowHint + ) + self.floating = floating + self.dialog = dialog + + # Color Variables + self.btns_text_color = "#ffffff" + self.cancel_bk_color = "#F44336" + self.confirm_bk_color = "#4CAF50" + self.confirm_ft_color = "#ffffff" + self.cancel_ft_color = "#ffffff" + + self.setupUI() + self.update() + + if floating: + self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True) + else: + self.setStyleSheet( + """ + #MyParent { + background-image: url(:/background/media/1st_background.png); + } + """ + ) + + def _update_button_style(self) -> None: + """Applies the current color variables and adds the central border to the stylesheets.""" + if not self.dialog: + return + + self.confirm_button.clicked.connect(self.accept) + self.cancel_button.clicked.connect(self.reject) + + if not self.floating: + self.confirm_button.setStyleSheet( + f""" + background-color: {self.confirm_bk_color}; + color: {self.confirm_ft_color}; + border: none; + padding: 10px; + """ + ) + + self.cancel_button.setStyleSheet( + f""" + background-color: {self.cancel_bk_color}; + color: {self.cancel_ft_color}; + border: none; + padding: 10px; + """ + ) + else: + self.confirm_button.setStyleSheet( + f""" + background-color: {self.confirm_bk_color}; + color: {self.confirm_ft_color}; + border-top: none; + border-left: 2px solid #80807e;; + border-bottom: 2px solid #80807e; + border-right: 1px solid #80807e; + border-bottom-left-radius: 16px; + padding: 10px; + """ + ) + + self.cancel_button.setStyleSheet( + f""" + background-color: {self.cancel_bk_color}; + color: {self.cancel_ft_color}; + border-left: 1px solid #80807e;; + border-bottom: 2px solid #80807e; + border-right: 2px solid #80807e; + border-bottom-right-radius: 16px; + padding: 10px; + """ + ) + + def set_message(self, message: str) -> None: + self.label.setText(message) + + def cancel_button_text(self, text: str) -> None: + if not self.dialog: + return + self.cancel_button.setText(text) + + def confirm_button_text(self, text: str) -> None: + if not self.dialog: + return + self.confirm_button.setText(text) + + def cancel_background_color(self, color: str) -> None: + if not self.dialog: + return + self.cancel_bk_color = color + self._update_button_style() + + def confirm_background_color(self, color: str) -> None: + if not self.dialog: + return + self.confirm_bk_color = color + self._update_button_style() + + def cancel_font_color(self, color: str) -> None: + if not self.dialog: + return + self.cancel_ft_color = color + self._update_button_style() + + def confirm_font_color(self, color: str) -> None: + if not self.dialog: + return + self.confirm_ft_color = color + self._update_button_style() + + def add_widget(self, widget: QtWidgets.QWidget) -> None: + """Replace the label with a custom widget in the layout""" + + layout = self.vlayout + index = layout.indexOf(self.label) + self.label.setParent(None) + self.label.hide() + layout.insertWidget(index, widget) + widget.show() + + def _get_mainWindow_widget(self) -> typing.Optional[QtWidgets.QMainWindow]: + """Get the main application window""" + app_instance = QtWidgets.QApplication.instance() + if not app_instance: + return None + main_window = app_instance.activeWindow() + if main_window is None: + for widget in app_instance.allWidgets(): + if isinstance(widget, QtWidgets.QMainWindow): + main_window = widget + break + return main_window if isinstance(main_window, QtWidgets.QMainWindow) else None + + def _geometry_calc(self) -> None: + """Calculate dialog widget position relative to the window""" + main_window = self._get_mainWindow_widget() + if main_window is None: + return + + if self.floating: + width = int(main_window.width() * self.x_offset) + height = int(main_window.height() * self.y_offset) + x = int(main_window.geometry().x() + (main_window.width() - width) / 2) + y = int(main_window.geometry().y() + (main_window.height() - height) / 2) + else: + x = main_window.geometry().x() + y = main_window.geometry().y() + width = main_window.width() + height = main_window.height() + + self.setGeometry(x, y, width, height) + + def sizeHint(self) -> QtCore.QSize: + """Re-implemented method, widget size hint""" + popup_width = int(self.geometry().width()) + popup_height = int(self.geometry().height()) + popup_x = self.x() + popup_y = self.y() + (self.height() - popup_height) // 2 + self.move(popup_x, popup_y) + self.setFixedSize(popup_width, popup_height) + self.setMinimumSize(popup_width, popup_height) + return super().sizeHint() + + def open(self): + """Re-implemented method, open widget""" + self._geometry_calc() + return super().open() + + def show(self) -> None: + self._geometry_calc() + return super().show() + + def paintEvent(self, a0: QtGui.QPaintEvent | None) -> None: + """Re-implemented method, paint widget""" + if not self.floating: + return + + self._geometry_calc() + painter = QtGui.QPainter(self) + painter.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing, True) + rect = self.rect() + painter.setBrush(QtGui.QBrush(QtGui.QColor(63, 63, 63))) + border_color = QtGui.QColor(128, 128, 128) + pen = QtGui.QPen() + pen.setCapStyle(QtCore.Qt.PenCapStyle.RoundCap) + painter.setPen(QtGui.QPen(border_color, self.border_margin)) + painter.drawRoundedRect(rect, self.border_radius, self.border_radius) + painter.end() + + def setupUI(self) -> None: + self.vlayout = QtWidgets.QVBoxLayout(self) + self.setObjectName("MyParent") + self.label = QtWidgets.QLabel("Test Message", self) + font = QtGui.QFont() + font.setPointSize(25) + self.label.setFont(font) + self.label.setStyleSheet("color: #ffffff; background: transparent;") + self.label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.label.setWordWrap(True) + self.vlayout.addWidget(self.label) + if self.dialog: + self.hlauyout = QtWidgets.QHBoxLayout() + self.hlauyout.setContentsMargins(0, 0, 0, 0) + self.hlauyout.setSpacing(0) + self.vlayout.addLayout(self.hlauyout) + self.vlayout.setContentsMargins(0, 0, 0, 0) + self.confirm_button = QtWidgets.QPushButton("Confirm", self) + self.cancel_button = QtWidgets.QPushButton("Back", self) + + button_font = QtGui.QFont() + button_font.setPointSize(14) + self.confirm_button.setFont(button_font) + self.confirm_button.setMinimumHeight(60) + self.cancel_button.setFont(button_font) + self.cancel_button.setMinimumHeight(60) + self.confirm_button.setStyleSheet("background: transparent;") + self.cancel_button.setStyleSheet("background: transparent;") + self.hlauyout.addWidget(self.confirm_button) + self.hlauyout.addWidget(self.cancel_button) + + self._update_button_style() diff --git a/BlocksScreen/lib/panels/widgets/dialogPage.py b/BlocksScreen/lib/panels/widgets/dialogPage.py deleted file mode 100644 index 45d067a..0000000 --- a/BlocksScreen/lib/panels/widgets/dialogPage.py +++ /dev/null @@ -1,167 +0,0 @@ -import typing - -from PyQt6 import QtCore, QtGui, QtWidgets - - -class DialogPage(QtWidgets.QDialog): - """Simple confirmation dialog with custom message and Confirm/Back buttons - - To assert if the user accepted or rejected the dialog connect to the **accepted()** or **rejected()** signals. - - The `finished()` signal can also be used to get the result of the dialog. This is emitted after - the accepted and rejected signals. - - - """ - - x_offset: float = 0.7 - y_offset: float = 0.7 - border_radius: int = 20 - border_margin: int = 5 - - def __init__( - self, - parent: QtWidgets.QWidget, - ) -> None: - super().__init__(parent) - self._setupUI() - self.setWindowFlags( - QtCore.Qt.WindowType.Popup | QtCore.Qt.WindowType.FramelessWindowHint - ) - self.setAttribute( - QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True - ) # Make background transparent - self.setWindowModality( # Force window modality to block input to other windows - QtCore.Qt.WindowModality.WindowModal - ) - self.confirm_button.clicked.connect(self.accept) - self.cancel_button.clicked.connect(self.reject) - self.setModal(True) - self.update() - - def set_message(self, message: str) -> None: - """Set dialog text message""" - self.label.setText(message) - - def _get_mainWindow_widget(self) -> typing.Optional[QtWidgets.QMainWindow]: - """Get the main application window""" - app_instance = QtWidgets.QApplication.instance() - if not app_instance: - return None - main_window = app_instance.activeWindow() - if main_window is None: - for widget in app_instance.allWidgets(): - if isinstance(widget, QtWidgets.QMainWindow): - main_window = widget - break - return main_window if isinstance(main_window, QtWidgets.QMainWindow) else None - - def _geometry_calc(self) -> None: - """Calculate dialog widget position relative to the window""" - main_window = self._get_mainWindow_widget() - width = int(main_window.width() * self.x_offset) - height = int(main_window.height() * self.y_offset) - x = int(main_window.geometry().x() + (main_window.width() - width) / 2) - y = int(main_window.geometry().y() + (main_window.height() - height) / 2) - self.setGeometry(x, y, width, height) - - def sizeHint(self) -> QtCore.QSize: - """Re-implemented method, widget size hint""" - popup_width = int(self.geometry().width()) - popup_height = int(self.geometry().height()) - popup_x = self.x() - popup_y = self.y() + (self.height() - popup_height) // 2 - self.move(popup_x, popup_y) - self.setFixedSize(popup_width, popup_height) - self.setMinimumSize(popup_width, popup_height) - return super().sizeHint() - - def resizeEvent(self, event: QtGui.QResizeEvent) -> None: - """Re-implemented method, handle resize event""" - super().resizeEvent(event) - main_window = self._get_mainWindow_widget() - if main_window is None: - return - width = int(main_window.width() * self.x_offset) - height = int(main_window.height() * self.y_offset) - label_x = (self.width() - width) // 2 - label_y = int(height / 4) - 20 # Move the label to the top (adjust as needed) - self.label.setGeometry(label_x, -label_y, width, height) - self.confirm_button.setGeometry( - int(0), self.height() - 70, int(self.width() / 2), 70 - ) - self.cancel_button.setGeometry( - int(self.width() / 2), - self.height() - 70, - int(self.width() / 2), - 70, - ) - - def open(self): - """Re-implemented method, open widget""" - self._geometry_calc() - return super().open() - - def show(self) -> None: - """Re-implemented method, show widget""" - self._geometry_calc() - return super().show() - - def paintEvent(self, event: QtGui.QPaintEvent) -> None: - """Re-implemented method, paint widget""" - self._geometry_calc() - painter = QtGui.QPainter(self) - painter.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing, True) - rect = self.rect() - painter.setBrush( - QtGui.QBrush(QtGui.QColor(63, 63, 63)) - ) # Semi-transparent dark gray - border_color = QtGui.QColor(128, 128, 128) # Gray color - pen = QtGui.QPen() - pen.setCapStyle(QtCore.Qt.PenCapStyle.RoundCap) - painter.setPen(QtGui.QPen(border_color, self.border_margin)) - painter.drawRoundedRect(rect, self.border_radius, self.border_radius) - painter.end() - - def _setupUI(self) -> None: - self.label = QtWidgets.QLabel("Test", self) - font = QtGui.QFont() - font.setPointSize(25) - self.label.setFont(font) - self.label.setStyleSheet("color: #ffffff; background: transparent;") - self.label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - self.label.setWordWrap(True) - self.confirm_button = QtWidgets.QPushButton("Confirm", self) - self.cancel_button = QtWidgets.QPushButton("Back", self) - button_font = QtGui.QFont() - button_font.setPointSize(14) - self.confirm_button.setFont(button_font) - self.cancel_button.setFont(button_font) - self.confirm_button.setStyleSheet( - """ - background-color: #4CAF50; - color: white; - border: none; - border-bottom-left-radius: 20px; - padding: 10px; - """ - ) - self.cancel_button.setStyleSheet( - """ - background-color: #F44336; - color: white; - border: none; - border-bottom-right-radius: 20px; - padding: 10px; - """ - ) - # Position buttons - self.confirm_button.setGeometry( - int(0), self.height() - 70, int(self.width() / 2), 70 - ) - self.cancel_button.setGeometry( - int(self.width() / 2), - self.height() - 70, - int(self.width() / 2), - 70, - ) diff --git a/BlocksScreen/lib/panels/widgets/loadPage.py b/BlocksScreen/lib/panels/widgets/loadPage.py deleted file mode 100644 index f5fd796..0000000 --- a/BlocksScreen/lib/panels/widgets/loadPage.py +++ /dev/null @@ -1,180 +0,0 @@ -import enum -from configfile import BlocksScreenConfig, get_configparser -from PyQt6 import QtCore, QtGui, QtWidgets - - -class LoadScreen(QtWidgets.QDialog): - class AnimationGIF(enum.Enum): - """Animation type""" - - DEFAULT = None - PLACEHOLDER = "" - - def __init__( - self, - parent: QtWidgets.QWidget, - anim_type: AnimationGIF = AnimationGIF.DEFAULT, - ) -> None: - super().__init__(parent) - - self.anim_type = anim_type - self._angle = 0 - self._span_angle = 90.0 - self._is_span_growing = True - self.min_length = 5.0 - self.max_length = 150.0 - self.length_step = 2.5 - - self.setStyleSheet( - "background-image: url(:/background/media/1st_background.png);" - ) - - self.setWindowFlags( - QtCore.Qt.WindowType.Popup | QtCore.Qt.WindowType.FramelessWindowHint - ) - self._setupUI() - config: BlocksScreenConfig = get_configparser() - try: - if config: - loading_config = config["loading"] - animation = loading_config.get( - str(self.anim_type.name), - default=LoadScreen.AnimationGIF.DEFAULT, - ) - except Exception: - self.anim_type = LoadScreen.AnimationGIF.DEFAULT - - self.timer = QtCore.QTimer(self) - self.timer.timeout.connect(self._update_animation) - - if self.anim_type == LoadScreen.AnimationGIF.PLACEHOLDER: - self.movie = QtGui.QMovie(animation) # Create QMovie object - self.gifshow.setMovie(self.movie) # Set QMovie to QLabel - self.movie.start() # Start the QMovie - - # Only start the animation timer if no GIF is provided - if self.anim_type == LoadScreen.AnimationGIF.DEFAULT: - self.timer.start(16) - - self.repaint() - - def set_status_message(self, message: str) -> None: - """Set widget status message""" - self.label.setText(message) - - def _geometry_calc(self) -> None: - """Calculate widget position relative to the screen""" - app_instance = QtWidgets.QApplication.instance() - main_window = app_instance.activeWindow() if app_instance else None - if main_window is None and app_instance: - for widget in app_instance.allWidgets(): - if isinstance(widget, QtWidgets.QMainWindow): - main_window = widget - x = main_window.geometry().x() - y = main_window.geometry().y() - width = main_window.width() - height = main_window.height() - - self.setGeometry(x, y, width, height) - - def close(self) -> bool: - """Re-implemented method, close widget""" - self.timer.stop() - self.label.setText("Loading...") - self._angle = 0 - # Stop the GIF animation if it was started - if self.anim_type != LoadScreen.AnimationGIF.DEFAULT: - self.gifshow.movie().stop() - return super().close() - - def _update_animation(self) -> None: - self._angle = (self._angle + 5) % 360 - if self._is_span_growing: - self._span_angle += self.length_step - if self._span_angle >= self.max_length: - self._span_angle = self.max_length - self._is_span_growing = False - else: - self._span_angle -= self.length_step - if self._span_angle <= self.min_length: - self._span_angle = self.min_length - self._is_span_growing = True - self.update() - - def sizeHint(self) -> QtCore.QSize: - """Re-implemented method, size hint""" - popup_width = int(self.geometry().width()) - popup_height = int(self.geometry().height()) - # Centering logic - popup_x = self.x() - popup_y = self.y() + (self.height() - popup_height) // 2 - self.move(popup_x, popup_y) - self.setFixedSize(popup_width, popup_height) - self.setMinimumSize(popup_width, popup_height) - return super().sizeHint() - - def paintEvent(self, a0: QtGui.QPaintEvent) -> None: - """Re-implemented method, paint widget""" - painter = QtGui.QPainter(self) - # loading circle draw - if self.anim_type == LoadScreen.AnimationGIF.DEFAULT: - painter.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing, True) - painter.setRenderHint( - QtGui.QPainter.RenderHint.LosslessImageRendering, True - ) - painter.setRenderHint(QtGui.QPainter.RenderHint.SmoothPixmapTransform, True) - painter.setRenderHint(QtGui.QPainter.RenderHint.TextAntialiasing, True) - pen = QtGui.QPen() - pen.setWidth(8) - pen.setColor(QtGui.QColor("#ffffff")) - pen.setCapStyle(QtCore.Qt.PenCapStyle.RoundCap) - painter.setPen(pen) - - center_x = self.width() // 2 - center_y = int(self.height() * 0.4) - arc_size = 150 - - painter.translate(center_x, center_y) - painter.rotate(self._angle) - - arc_rect = QtCore.QRectF(-arc_size / 2, -arc_size / 2, arc_size, arc_size) - span_angle = int(self._span_angle * 16) - painter.drawArc(arc_rect, 0, span_angle) - - def resizeEvent(self, event: QtGui.QResizeEvent) -> None: - """Re-implemented method, handle widget resize event""" - super().resizeEvent(event) - label_width = self.width() - label_height = 100 - label_x = (self.width() - label_width) // 2 - label_y = int(self.height() * 0.65) - margin = 20 - # Center the GIF - gifshow_width = self.width() - margin * 2 - gifshow_height = self.height() - (self.height() - label_y) - margin - - self.gifshow.setGeometry(margin, margin, gifshow_width, gifshow_height) - - self.label.setGeometry(label_x, label_y, label_width, label_height) - - def show(self) -> None: - """Re-implemented method, show widget""" - self._geometry_calc() - # Start the animation timer only if no GIF is present - if self.anim_type == LoadScreen.AnimationGIF.DEFAULT: - self.timer.start() - self.repaint() - return super().show() - - def _setupUI(self) -> None: - self.gifshow = QtWidgets.QLabel("", self) - self.gifshow.setObjectName("gifshow") - self.gifshow.setStyleSheet("background: transparent;") - self.gifshow.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) - - self.label = QtWidgets.QLabel("Test", self) - font = QtGui.QFont() - font.setPointSize(20) - self.label.setFont(font) - self.label.setStyleSheet("color: #ffffff; background: transparent;") - self.label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) diff --git a/BlocksScreen/lib/panels/widgets/loadWidget.py b/BlocksScreen/lib/panels/widgets/loadWidget.py index 9a5f3d6..c23d4a5 100644 --- a/BlocksScreen/lib/panels/widgets/loadWidget.py +++ b/BlocksScreen/lib/panels/widgets/loadWidget.py @@ -1,10 +1,24 @@ from PyQt6 import QtCore, QtGui, QtWidgets +import enum +import os +from configfile import BlocksScreenConfig, get_configparser class LoadingOverlayWidget(QtWidgets.QLabel): + """ + A full-overlay widget to display a loading animation (GIF or spinning arc). + """ + + class AnimationGIF(enum.Enum): + """Animation type""" + + DEFAULT = None + PLACEHOLDER = "placeholder" + def __init__( self, parent: QtWidgets.QWidget, + initial_anim_type: AnimationGIF = AnimationGIF.PLACEHOLDER, ) -> None: super().__init__(parent) @@ -17,12 +31,66 @@ def __init__( self._setupUI() + config: BlocksScreenConfig = get_configparser() + animation_path = None + + if initial_anim_type == LoadingOverlayWidget.AnimationGIF.PLACEHOLDER: + animation_path = ( + "~/BlocksScreen/BlocksScreen/lib/ui/resources/intro_blocks.gif" + ) + self.anim_type = initial_anim_type + + else: + try: + loading_config = config.loading + animation_path = loading_config.get( + str(initial_anim_type.name), + ) + self.anim_type = initial_anim_type + except Exception: + self.anim_type = LoadingOverlayWidget.AnimationGIF.DEFAULT + + if ( + self.anim_type != LoadingOverlayWidget.AnimationGIF.DEFAULT + and animation_path + ): + abs_animation_path = os.path.expanduser(animation_path) + + self.movie = QtGui.QMovie(abs_animation_path) + + if self.movie.isValid(): + self.gifshow.setMovie(self.movie) + self.gifshow.setScaledContents(True) + self.movie.start() + self.gifshow.show() + else: + self.anim_type = LoadingOverlayWidget.AnimationGIF.DEFAULT + self.gifshow.hide() + self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self._update_animation) - self.timer.start(16) + + if self.anim_type == LoadingOverlayWidget.AnimationGIF.DEFAULT: + self.timer.start(16) + self.gifshow.hide() + self.label.setText("Loading...") self.repaint() + def set_animation_path(self, path: str) -> None: + """Set widget animation path""" + abs_animation_path = os.path.expanduser(path) + if os.path.isfile(abs_animation_path): + self.movie = QtGui.QMovie(abs_animation_path) + if self.movie.isValid(): + self.gifshow.setMovie(self.movie) + self.gifshow.setScaledContents(True) + self.movie.start() + self.gifshow.show() + self.anim_type = LoadingOverlayWidget.AnimationGIF.PLACEHOLDER + if self.timer.isActive(): + self.timer.stop() + def set_status_message(self, message: str) -> None: """Set widget message""" self.label.setText(message) @@ -32,6 +100,12 @@ def close(self) -> bool: self.timer.stop() self.label.setText("Loading...") self._angle = 0 + if ( + self.anim_type != LoadingOverlayWidget.AnimationGIF.DEFAULT + and hasattr(self, "movie") + and self.movie.isValid() + ): + self.movie.stop() return super().close() def _update_animation(self) -> None: @@ -48,55 +122,64 @@ def _update_animation(self) -> None: self._is_span_growing = True self.update() - def paintEvent(self, a0: QtGui.QPaintEvent) -> None: + def paintEvent(self, a0: QtGui.QPaintEvent | None) -> None: """Re-implemented method, paint widget""" painter = QtGui.QPainter(self) - painter.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing, True) - painter.setRenderHint(QtGui.QPainter.RenderHint.LosslessImageRendering, True) - painter.setRenderHint(QtGui.QPainter.RenderHint.SmoothPixmapTransform, True) - painter.setRenderHint(QtGui.QPainter.RenderHint.TextAntialiasing, True) - pen = QtGui.QPen() - pen.setWidth(8) - pen.setColor(QtGui.QColor("#ffffff")) - pen.setCapStyle(QtCore.Qt.PenCapStyle.RoundCap) - painter.setPen(pen) - - center_x = self.width() // 2 - center_y = int(self.height() * 0.4) - arc_size = 150 - - painter.translate(center_x, center_y) - painter.rotate(self._angle) - - arc_rect = QtCore.QRectF(-arc_size / 2, -arc_size / 2, arc_size, arc_size) - span_angle = int(self._span_angle * 16) - painter.drawArc(arc_rect, 0, span_angle) - - def resizeEvent(self, event: QtGui.QResizeEvent) -> None: - """Re-implemented method, handle resize event""" - super().resizeEvent(event) + if self.anim_type == LoadingOverlayWidget.AnimationGIF.DEFAULT: + painter.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing, True) + painter.setRenderHint( + QtGui.QPainter.RenderHint.LosslessImageRendering, True + ) + painter.setRenderHint(QtGui.QPainter.RenderHint.SmoothPixmapTransform, True) + painter.setRenderHint(QtGui.QPainter.RenderHint.TextAntialiasing, True) + pen = QtGui.QPen() + pen.setWidth(8) + pen.setColor(QtGui.QColor("#ffffff")) + pen.setCapStyle(QtCore.Qt.PenCapStyle.RoundCap) + painter.setPen(pen) + + center_x = self.width() // 2 + center_y = int(self.height() * 0.4) + arc_size = 150 + + painter.translate(center_x, center_y) + painter.rotate(self._angle) + + arc_rect = QtCore.QRectF(-arc_size / 2, -arc_size / 2, arc_size, arc_size) + span_angle = int(self._span_angle * 16) + painter.drawArc(arc_rect, 0, span_angle) + + super().paintEvent(a0) + + def resizeEvent(self, a0: QtGui.QResizeEvent | None) -> None: + """Re-implemented method, handle widget resize event""" + super().resizeEvent(a0) label_width = self.width() label_height = 100 label_x = (self.width() - label_width) // 2 label_y = int(self.height() * 0.65) margin = 20 - # Center the GIF - gifshow_width = self.width() - margin * 2 - gifshow_height = self.height() - (self.height() - label_y) - margin - self.gifshow.setGeometry(margin, margin, gifshow_width, gifshow_height) self.label.setGeometry(label_x, label_y, label_width, label_height) + gifshow_max_height = label_y - margin + size = min(self.width() - margin * 2, gifshow_max_height) + + gifshow_x = (self.width() - size) // 2 + gifshow_y = (gifshow_max_height - size) // 2 + + self.gifshow.setGeometry(gifshow_x, gifshow_y, size, size) def show(self) -> None: """Re-implemented method, show widget""" - self.timer.start() self.repaint() return super().show() def _setupUI(self) -> None: + self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True) self.gifshow = QtWidgets.QLabel("", self) self.gifshow.setObjectName("gifshow") self.gifshow.setStyleSheet("background: transparent;") self.gifshow.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self.gifshow.hide() self.label = QtWidgets.QLabel(self) font = QtGui.QFont() From f3d071ab4c38401c1e3ff7acb4c10b58090412e8 Mon Sep 17 00:00:00 2001 From: Roberto Date: Tue, 16 Dec 2025 11:33:34 +0000 Subject: [PATCH 6/7] Refactor: change popup to Basepopup or/with loadwidget --- BlocksScreen/lib/panels/controlTab.py | 35 ++++++----- BlocksScreen/lib/panels/filamentTab.py | 16 +++-- BlocksScreen/lib/panels/printTab.py | 24 ++++--- BlocksScreen/lib/panels/utilitiesTab.py | 17 ++--- .../lib/panels/widgets/inputshaperPage.py | 62 +++++++++---------- .../lib/panels/widgets/jobStatusPage.py | 4 +- .../lib/panels/widgets/probeHelperPage.py | 12 +++- BlocksScreen/lib/panels/widgets/updatePage.py | 16 +++-- 8 files changed, 106 insertions(+), 80 deletions(-) diff --git a/BlocksScreen/lib/panels/controlTab.py b/BlocksScreen/lib/panels/controlTab.py index 99f8a3c..c17cb17 100644 --- a/BlocksScreen/lib/panels/controlTab.py +++ b/BlocksScreen/lib/panels/controlTab.py @@ -4,7 +4,8 @@ from functools import partial import re from lib.moonrakerComm import MoonWebSocket -from lib.panels.widgets.loadPage import LoadScreen +from lib.panels.widgets.loadWidget import LoadingOverlayWidget +from lib.panels.widgets.basePopup import BasePopup from lib.panels.widgets.numpadPage import CustomNumpad from lib.panels.widgets.printcorePage import SwapPrintcorePage from lib.panels.widgets.probeHelperPage import ProbeHelper @@ -79,8 +80,12 @@ def __init__( self.addWidget(self.probe_helper_page) self.printcores_page = SwapPrintcorePage(self) self.addWidget(self.printcores_page) - self.loadpage = LoadScreen(self, LoadScreen.AnimationGIF.DEFAULT) - self.addWidget(self.loadpage) + + self.loadscreen = BasePopup(self, floating=False, dialog=False) + self.loadwidget = LoadingOverlayWidget( + self, LoadingOverlayWidget.AnimationGIF.DEFAULT + ) + self.loadscreen.add_widget(self.loadwidget) self.sliderPage = SliderPage(self) self.addWidget(self.sliderPage) @@ -415,17 +420,17 @@ def handle_printcoreupdate(self, value: dict): return if value["swapping"] == "in_pos": - self.loadpage.hide() + self.loadscreen.hide() self.printcores_page.show() self.disable_popups.emit(True) self.printcores_page.setText( "Please Insert Print Core \n \n Afterwards click continue" ) if value["swapping"] == "unloading": - self.loadpage.set_status_message("Unloading print core") + self.loadwidget.set_status_message("Unloading print core") if value["swapping"] == "cleaning": - self.loadpage.set_status_message("Cleaning print core") + self.loadwidget.set_status_message("Cleaning print core") def _handle_gcode_response(self, messages: list): """Handle gcode response for Z-tilt adjustment""" @@ -448,21 +453,23 @@ def _handle_gcode_response(self, messages: list): probed_range = float(match.group(3)) tolerance = float(match.group(4)) if retries_done == retries_total: - self.loadpage.hide() + self.loadscreen.hide() return if probed_range < tolerance: - self.loadpage.hide() + self.loadscreen.hide() return - self.loadpage.set_status_message( + self.loadwidget.set_status_message( f"Retries: {retries_done}/{retries_total} | Range: {probed_range:.6f} | Tolerance: {tolerance:.6f}" ) def handle_ztilt(self): """Handle Z-Tilt Adjustment""" - self.loadpage.show() - self.loadpage.set_status_message("Please wait, performing Z-axis calibration.") + self.loadscreen.show() + self.loadwidget.set_status_message( + "Please wait, performing Z-axis calibration." + ) self.run_gcode_signal.emit("G28\nM400\nZ_TILT_ADJUST") @QtCore.pyqtSlot(str, name="on-klippy-status") @@ -479,8 +486,8 @@ def on_klippy_status(self, state: str): def show_swapcore(self): """Show swap printcore""" self.run_gcode_signal.emit("CHANGE_PRINTCORES") - self.loadpage.show() - self.loadpage.set_status_message("Preparing to swap print core") + self.loadscreen.show() + self.loadwidget.set_status_message("Preparing to swap print core") def handle_swapcore(self): """Handle swap printcore routine finish""" @@ -652,7 +659,7 @@ def on_toolhead_update(self, field: str, values: list) -> None: self.panel.mva_z_value_label.setText(f"{values[2]:.3f}") if values[0] == "252,50" and values[1] == "250" and values[2] == "50": - self.loadpage.hide + self.loadscreen.hide self.toolhead_info.update({f"{field}": values}) @QtCore.pyqtSlot(str, str, float, name="on-extruder-update") diff --git a/BlocksScreen/lib/panels/filamentTab.py b/BlocksScreen/lib/panels/filamentTab.py index 4ab358f..1271375 100644 --- a/BlocksScreen/lib/panels/filamentTab.py +++ b/BlocksScreen/lib/panels/filamentTab.py @@ -6,7 +6,8 @@ from lib.filament import Filament from lib.ui.filamentStackedWidget_ui import Ui_filamentStackedWidget -from lib.panels.widgets.loadPage import LoadScreen +from lib.panels.widgets.loadWidget import LoadingOverlayWidget +from lib.panels.widgets.basePopup import BasePopup from lib.panels.widgets.popupDialogWidget import Popup from PyQt6 import QtCore, QtGui, QtWidgets @@ -41,8 +42,11 @@ def __init__(self, parent: QtWidgets.QWidget, printer: Printer, ws, /) -> None: self.target_temp: int = 0 self.current_temp: int = 0 self.popup = Popup(self) - self.loadscreen = LoadScreen(self, LoadScreen.AnimationGIF.DEFAULT) - self.addWidget(self.loadscreen) + self.loadscreen = BasePopup(self, floating=False, dialog=False) + self.loadwidget = LoadingOverlayWidget( + self, LoadingOverlayWidget.AnimationGIF.DEFAULT + ) + self.loadscreen.add_widget(self.loadwidget) self.has_load_unload_objects = None self._filament_state = self.FilamentStates.UNKNOWN self._sensor_states = {} @@ -129,16 +133,16 @@ def on_extruder_update( if self.target_temp != 0: if self.current_temp == self.target_temp: - self.loadscreen.set_status_message("Extruder heated up \n Please wait") + self.loadwidget.set_status_message("Extruder heated up \n Please wait") return if field == "temperature": self.current_temp = round(new_value, 0) - self.loadscreen.set_status_message( + self.loadwidget.set_status_message( f"Heating up ({new_value}/{self.target_temp}) \n Please wait" ) if field == "target": self.target_temp = round(new_value, 0) - self.loadscreen.set_status_message("Heating up \n Please wait") + self.loadwidget.set_status_message("Heating up \n Please wait") @QtCore.pyqtSlot(bool, name="on_load_filament") def on_load_filament(self, status: bool): diff --git a/BlocksScreen/lib/panels/printTab.py b/BlocksScreen/lib/panels/printTab.py index 65f0030..104a765 100644 --- a/BlocksScreen/lib/panels/printTab.py +++ b/BlocksScreen/lib/panels/printTab.py @@ -14,8 +14,8 @@ from lib.panels.widgets.slider_selector_page import SliderPage from lib.utils.blocks_button import BlocksCustomButton from lib.panels.widgets.numpadPage import CustomNumpad -from lib.panels.widgets.loadPage import LoadScreen -from lib.panels.widgets.dialogPage import DialogPage +from lib.panels.widgets.loadWidget import LoadingOverlayWidget +from lib.panels.widgets.basePopup import BasePopup from configfile import BlocksScreenConfig, get_configparser from PyQt6 import QtCore, QtGui, QtWidgets @@ -85,14 +85,18 @@ def __init__( self.numpadPage = CustomNumpad(self) self.numpadPage.request_back.connect(self.back_button) self.addWidget(self.numpadPage) - self.loadscreen = LoadScreen(self, LoadScreen.AnimationGIF.DEFAULT) - self.addWidget(self.loadscreen) + + self.loadscreen = BasePopup(self, floating=False, dialog=False) + self.loadwidget = LoadingOverlayWidget( + self, LoadingOverlayWidget.AnimationGIF.DEFAULT + ) + self.loadscreen.add_widget(self.loadwidget) self.file_data: Files = file_data self.filesPage_widget = FilesPage(self) self.addWidget(self.filesPage_widget) - self.dialogPage = DialogPage(self) + self.BasePopup = BasePopup(self) self.confirmPage_widget = ConfirmWidget(self) self.addWidget(self.confirmPage_widget) @@ -295,18 +299,18 @@ def on_slidePage_request( @QtCore.pyqtSlot(str, name="delete_file") def delete_file(self, filename: str, directory: str = "gcodes") -> None: """Handle Delete file signal, shows confirmation dialog""" - self.dialogPage.set_message("Are you sure you want to delete this file?") - self.dialogPage.accepted.connect( + self.BasePopup.set_message("Are you sure you want to delete this file?") + self.BasePopup.accepted.connect( lambda: self._on_delete_file_confirmed(filename, directory) ) - self.dialogPage.open() + self.BasePopup.open() def _on_delete_file_confirmed(self, filename: str, directory: str) -> None: """Handle confirmed file deletion after user accepted the dialog""" self.file_data.on_request_delete_file(filename, directory) self.request_back.emit() self.filesPage_widget.reset_dir() - self.dialogPage.disconnect() + self.BasePopup.disconnect() def paintEvent(self, a0: QtGui.QPaintEvent) -> None: """Widget painting""" @@ -341,7 +345,7 @@ def handle_cancel_print(self) -> None: self.on_cancel_print.emit() self.loadscreen.show() self.loadscreen.setModal(True) - self.loadscreen.set_status_message("Cancelling print...\nPlease wait") + self.loadwidget.set_status_message("Cancelling print...\nPlease wait") def change_page(self, index: int) -> None: """Requests a page change page to the global manager diff --git a/BlocksScreen/lib/panels/utilitiesTab.py b/BlocksScreen/lib/panels/utilitiesTab.py index 7997353..00f59ad 100644 --- a/BlocksScreen/lib/panels/utilitiesTab.py +++ b/BlocksScreen/lib/panels/utilitiesTab.py @@ -4,7 +4,6 @@ from functools import partial from lib.moonrakerComm import MoonWebSocket -from lib.panels.widgets.loadPage import LoadScreen from lib.panels.widgets.troubleshootPage import TroubleshootPage from lib.panels.widgets.updatePage import UpdatePage from lib.printer import Printer @@ -15,7 +14,8 @@ from lib.panels.widgets.optionCardWidget import OptionCard from lib.panels.widgets.inputshaperPage import InputShaperPage -from lib.panels.widgets.dialogPage import DialogPage +from lib.panels.widgets.basePopup import BasePopup +from lib.panels.widgets.loadWidget import LoadingOverlayWidget import re @@ -120,8 +120,11 @@ def __init__( # --- UI Setup --- self.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) - self.loadPage = LoadScreen(self) - self.addWidget(self.loadPage) + self.loadPage = BasePopup(self) + self.loadwidget = LoadingOverlayWidget( + self, LoadingOverlayWidget.AnimationGIF.DEFAULT + ) + self.loadPage.add_widget(self.loadwidget) self.update_page = UpdatePage(self) self.addWidget(self.update_page) @@ -129,7 +132,7 @@ def __init__( self.is_page = InputShaperPage(self) self.addWidget(self.is_page) - self.dialog_page = DialogPage(self) + self.dialog_page = BasePopup(self, dialog=True, floating=True) self.addWidget(self.dialog_page) # --- Back Buttons --- @@ -377,7 +380,7 @@ def handle_is(self, gcode: str) -> None: self.run_gcode_signal.emit(gcode) self.change_page(self.indexOf(self.is_page)) - self.loadPage.set_status_message("Running Input Shaper...") + self.loadwidget.set_status_message("Running Input Shaper...") self.loadPage.show() @QtCore.pyqtSlot(list, name="on_object_list") @@ -680,7 +683,7 @@ def troubleshoot_request(self) -> None: def show_waiting_page(self, page_to_go_to: int, label: str, time_ms: int): """Show placeholder page""" - self.loadPage.set_status_message(label) + self.loadwidget.set_status_message(label) self.loadPage.show() QtCore.QTimer.singleShot(time_ms, lambda: self.change_page(page_to_go_to)) diff --git a/BlocksScreen/lib/panels/widgets/inputshaperPage.py b/BlocksScreen/lib/panels/widgets/inputshaperPage.py index 4538352..d96f543 100644 --- a/BlocksScreen/lib/panels/widgets/inputshaperPage.py +++ b/BlocksScreen/lib/panels/widgets/inputshaperPage.py @@ -1,4 +1,5 @@ -from lib.panels.widgets.loadPage import LoadScreen +from lib.panels.widgets.loadWidget import LoadingOverlayWidget +from lib.panels.widgets.basePopup import BasePopup from lib.utils.blocks_button import BlocksCustomButton from lib.utils.blocks_frame import BlocksCustomFrame from lib.utils.icon_button import IconButton @@ -7,11 +8,13 @@ import typing + class InputShaperPage(QtWidgets.QWidget): """Update GUI Page, retrieves from moonraker available clients and adds functionality for updating or recovering them """ + run_gcode_signal: typing.ClassVar[QtCore.pyqtSignal] = QtCore.pyqtSignal( str, name="run-gcode" ) @@ -26,7 +29,11 @@ def __init__(self, parent=None) -> None: self.ongoing_update: bool = False self.type_dict: dict = {} - self.load_popup: LoadScreen = LoadScreen(self) + self.loadscreen = BasePopup(self, floating=False, dialog=False) + self.loadwidget = LoadingOverlayWidget( + self, LoadingOverlayWidget.AnimationGIF.DEFAULT + ) + self.loadscreen.add_widget(self.loadwidget) self.repeated_request_status = QtCore.QTimer() self.repeated_request_status.setInterval(2000) # every 2 seconds self.model = EntryListModel() @@ -39,9 +46,6 @@ def __init__(self, parent=None) -> None: self.action_btn.clicked.connect(self.handle_ism_confirm) - - - def handle_update_end(self) -> None: """Handles update end signal (closes loading page, returns to normal operation) @@ -55,7 +59,7 @@ def handle_ongoing_update(self) -> None: """Handled ongoing update signal, calls loading page (blocks user interaction) """ - self.load_popup.set_status_message("Updating...") + self.loadwidget.set_status_message("Updating...") self.load_popup.show() self.repeated_request_status.start(2000) @@ -78,21 +82,17 @@ def showEvent(self, a0: QtGui.QShowEvent | None) -> None: def build_model_list(self) -> None: """Builds the model list (`self.model`) containing updatable clients""" self.update_buttons_list_widget.blockSignals(True) - self.model.setData( - self.model.index(0), True, EntryListModel.EnableRole - ) + self.model.setData(self.model.index(0), True, EntryListModel.EnableRole) self.on_item_clicked( self.model.data(self.model.index(0), QtCore.Qt.ItemDataRole.UserRole) - ) + ) self.update_buttons_list_widget.blockSignals(False) - def set_type_dictionary(self, dict) -> None: """Receives the dictionary of input shaper types from the utilities tab""" self.type_dict = dict return - @QtCore.pyqtSlot(ListItem, name="on-item-clicked") def on_item_clicked(self, item: ListItem) -> None: """Setup information for the currently clicked list item on the info box. @@ -105,25 +105,29 @@ def on_item_clicked(self, item: ListItem) -> None: if not current_info: return - self.vib_label.setText(str("%.0f" % current_info.get('vibration', 'N/A'))+ "%") - self.sug_accel_label.setText(str("%.0f" % current_info.get('max_accel', 'N/A'))+ "mm/s²") + self.vib_label.setText(str("%.0f" % current_info.get("vibration", "N/A")) + "%") + self.sug_accel_label.setText( + str("%.0f" % current_info.get("max_accel", "N/A")) + "mm/s²" + ) self.action_btn.show() - def handle_ism_confirm(self)-> None: + def handle_ism_confirm(self) -> None: current_info = self.type_dict.get(self.currentItem.text, {}) - frequency = current_info.get('frequency', 'N/A') + frequency = current_info.get("frequency", "N/A") if self.type_dict["Axis"] == "x": - self.run_gcode_signal.emit(f"SET_INPUT_SHAPER SHAPER_TYPE_X={self.currentItem.text} SHAPER_FREQ_X={frequency}") + self.run_gcode_signal.emit( + f"SET_INPUT_SHAPER SHAPER_TYPE_X={self.currentItem.text} SHAPER_FREQ_X={frequency}" + ) elif self.type_dict["Axis"] == "y": - self.run_gcode_signal.emit(f"SET_INPUT_SHAPER SHAPER_TYPE_Y={self.currentItem.text} SHAPER_FREQ_Y={frequency}") + self.run_gcode_signal.emit( + f"SET_INPUT_SHAPER SHAPER_TYPE_Y={self.currentItem.text} SHAPER_FREQ_Y={frequency}" + ) self.run_gcode_signal.emit("SAVE_CONFIG") self.reset_view_model() - - - def add_type_entry(self, cli_name: str,recommended:str = "") -> None: + def add_type_entry(self, cli_name: str, recommended: str = "") -> None: """Adds a new item to the list model""" item = ListItem( text=cli_name, @@ -386,16 +390,13 @@ def _setupUI(self) -> None: palette.setColor(palette.ColorRole.WindowText, QtGui.QColor("#FFFFFF")) self.vib_label.setFont(font) self.vib_label.setPalette(palette) - self.vib_label.setLayoutDirection( - QtCore.Qt.LayoutDirection.RightToLeft - ) + self.vib_label.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft) self.vib_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) self.vib_label.setObjectName("version-tracking") self.info_box.addWidget(self.vib_title_label, 0, 0) self.info_box.addWidget(self.vib_label, 0, 1) - self.sug_accel_title_label = QtWidgets.QLabel(self) self.sug_accel_title_label.setText("Sugested Max Acceleration:") self.sug_accel_title_label.setMinimumSize(QtCore.QSize(60, 60)) @@ -413,7 +414,6 @@ def _setupUI(self) -> None: QtCore.Qt.LayoutDirection.RightToLeft ) - self.sug_accel_label = QtWidgets.QLabel(self) self.sug_accel_label.setMinimumSize(QtCore.QSize(100, 60)) self.sug_accel_label.setMaximumSize( @@ -430,8 +430,6 @@ def _setupUI(self) -> None: self.info_box_layout.addLayout(self.info_box, 1) - - self.button_box = QtWidgets.QVBoxLayout() self.button_box.setContentsMargins(0, 0, 0, 0) self.button_box.addSpacing(-1) @@ -444,11 +442,11 @@ def _setupUI(self) -> None: self.action_btn.setPalette(palette) self.action_btn.setSizePolicy(sizePolicy) self.action_btn.setText("Confirm") - self.action_btn.setPixmap( - QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg") - ) + self.action_btn.setPixmap(QtGui.QPixmap(":/dialog/media/btn_icons/yes.svg")) self.button_box.addWidget( - self.action_btn, 0, QtCore.Qt.AlignmentFlag.AlignRight | QtCore.Qt.AlignmentFlag.AlignBottom + self.action_btn, + 0, + QtCore.Qt.AlignmentFlag.AlignRight | QtCore.Qt.AlignmentFlag.AlignBottom, ) self.info_box_layout.addLayout( diff --git a/BlocksScreen/lib/panels/widgets/jobStatusPage.py b/BlocksScreen/lib/panels/widgets/jobStatusPage.py index a09bdcd..3193d59 100644 --- a/BlocksScreen/lib/panels/widgets/jobStatusPage.py +++ b/BlocksScreen/lib/panels/widgets/jobStatusPage.py @@ -3,7 +3,7 @@ import events from helper_methods import calculate_current_layer, estimate_print_time -from lib.panels.widgets import dialogPage +from lib.panels.widgets.basePopup import BasePopup from lib.utils.blocks_button import BlocksCustomButton from lib.utils.blocks_label import BlocksLabel from lib.utils.blocks_progressbar import CustomProgressBar @@ -62,7 +62,7 @@ class JobStatusWidget(QtWidgets.QWidget): def __init__(self, parent) -> None: super().__init__(parent) - self.cancel_print_dialog = dialogPage.DialogPage(self) + self.cancel_print_dialog = BasePopup(self, floating=True) self._setupUI() self.tune_menu_btn.clicked.connect(self.tune_clicked.emit) self.pause_printing_btn.clicked.connect(self.pause_resume_print) diff --git a/BlocksScreen/lib/panels/widgets/probeHelperPage.py b/BlocksScreen/lib/panels/widgets/probeHelperPage.py index 5eeb3a3..8e3e909 100644 --- a/BlocksScreen/lib/panels/widgets/probeHelperPage.py +++ b/BlocksScreen/lib/panels/widgets/probeHelperPage.py @@ -7,7 +7,8 @@ from lib.utils.group_button import GroupButton from lib.utils.blocks_button import BlocksCustomButton -from lib.panels.widgets.loadPage import LoadScreen +from lib.panels.widgets.loadWidget import LoadingOverlayWidget +from lib.panels.widgets.basePopup import BasePopup class ProbeHelper(QtWidgets.QWidget): @@ -48,7 +49,12 @@ class ProbeHelper(QtWidgets.QWidget): def __init__(self, parent: QtWidgets.QWidget) -> None: super().__init__(parent) - self.Loadscreen = LoadScreen(self) + + self.Loadscreen = BasePopup(self) + self.loadwidget = LoadingOverlayWidget( + self, LoadingOverlayWidget.AnimationGIF.PLACEHOLDER + ) + self.Loadscreen.add_widget(self.loadwidget) self.setObjectName("probe_offset_page") self._setupUi() self.inductive_icon = QtGui.QPixmap( @@ -393,7 +399,7 @@ def handle_start_tool(self, sender: typing.Type[OptionCard]) -> None: i.setDisabled(True) self.Loadscreen.show() - self.Loadscreen.set_status_message("Homing Axes...") + self.loadwidget.set_status_message("Homing Axes...") if self.z_offset_safe_xy: self.run_gcode_signal.emit("G28\nM400") diff --git a/BlocksScreen/lib/panels/widgets/updatePage.py b/BlocksScreen/lib/panels/widgets/updatePage.py index 534bbab..5ec9ceb 100644 --- a/BlocksScreen/lib/panels/widgets/updatePage.py +++ b/BlocksScreen/lib/panels/widgets/updatePage.py @@ -1,7 +1,8 @@ import copy import typing -from lib.panels.widgets.loadPage import LoadScreen +from lib.panels.widgets.basePopup import BasePopup +from lib.panels.widgets.loadWidget import LoadingOverlayWidget from lib.utils.blocks_button import BlocksCustomButton from lib.utils.blocks_frame import BlocksCustomFrame from lib.utils.icon_button import IconButton @@ -61,8 +62,11 @@ def __init__(self, parent=None) -> None: self.cli_tracking = {} self.selected_item: ListItem | None = None self.ongoing_update: bool = False - - self.load_popup: LoadScreen = LoadScreen(self) + self.load_popup = BasePopup(self, floating=False, dialog=False) + self.loadwidget = LoadingOverlayWidget( + self, LoadingOverlayWidget.AnimationGIF.DEFAULT + ) + self.load_popup.add_widget(self.loadwidget) self.repeated_request_status = QtCore.QTimer() self.repeated_request_status.setInterval(2000) # every 2 seconds self.model = EntryListModel() @@ -93,7 +97,7 @@ def handle_ongoing_update(self) -> None: """Handled ongoing update signal, calls loading page (blocks user interaction) """ - self.load_popup.set_status_message("Updating...") + self.loadwidget.set_status_message("Updating...") self.load_popup.show() self.repeated_request_status.start(2000) @@ -151,10 +155,10 @@ def on_update_clicked(self) -> None: else: self.request_update_client.emit(cli_name) - self.load_popup.set_status_message(f"Updating {cli_name}") + self.loadwidget.set_status_message(f"Updating {cli_name}") else: self.request_recover_repo[str, bool].emit(cli_name, True) - self.load_popup.set_status_message(f"Recovering {cli_name}") + self.loadwidget.set_status_message(f"Recovering {cli_name}") self.load_popup.show() self.request_update_status.emit(False) From c84a78415c6d66188077b638ee0084efa1674987 Mon Sep 17 00:00:00 2001 From: Roberto Date: Tue, 23 Dec 2025 10:10:04 +0000 Subject: [PATCH 7/7] Rev: removed misstype --- BlocksScreen/lib/panels/utilitiesTab.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/BlocksScreen/lib/panels/utilitiesTab.py b/BlocksScreen/lib/panels/utilitiesTab.py index 00f59ad..1c9d0fa 100644 --- a/BlocksScreen/lib/panels/utilitiesTab.py +++ b/BlocksScreen/lib/panels/utilitiesTab.py @@ -247,17 +247,17 @@ def __init__( lambda: self.handle_is("SHAPER_CALIBRATE") ) - self.manuel_is = OptionCard( + self.manual_is = OptionCard( self, - "Manuel\nInput Shaper", + "Manual\nInput Shaper", "Manual Input Shaper", QtGui.QPixmap(":/input_shaper/media/btn_icons/input_shaper_manual.svg"), ) # type: ignore - self.manuel_is.setObjectName("Manual_IS_Card") + self.manual_is.setObjectName("Manual_IS_Card") self.panel.is_content_layout.addWidget( - self.manuel_is, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter + self.manual_is, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter ) - self.manuel_is.continue_clicked.connect(lambda: self.handle_is("")) + self.manual_is.continue_clicked.connect(lambda: self.handle_is("")) self.is_types: dict = {} self.is_aut_types: dict = {} @@ -363,7 +363,7 @@ def handle_is(self, gcode: str) -> None: self.aut = True self.run_gcode_signal.emit(gcode) if gcode == "": - print("Manuel Input Shaper Selected") + print("manual Input Shaper Selected") self.dialog_page.confirm_background_color("#dfdfdf") self.dialog_page.cancel_background_color("#dfdfdf") self.dialog_page.cancel_font_color("#000000")