refactor main window stacked widget - #298
Robert0Mart wants to merge 7 commits into
Conversation
90444fa to
0c5b070
Compare
There was a problem hiding this comment.
What's good
- Drops the generated
mainWindow.ui/mainWindow_ui.pyplus the unusedmainWindow_v2pair (~2.5k lines). - Every
self.ui.*reference inmainWindow.pyis converted, and no other module reaches into the oldUi_MainWindow. - The four page moves into
widgets/MainWindow/are 100% renames, and every importer (mainWindow.py,tests/panels/conftest.py,test_update_page_unit.py,test_connection_page.py) is updated in the same PR. _setup_ui()runs before any widget is used andcurrentChangedis connected after it, so the temporarysetCurrentIndex(3)fires no slot.- It sets the
_setup_uipattern the rest of the stack (#299-#332) follows. - All 20 resource keys in
_setup_uiresolve ondev.
1. mainWindow.py:1273: _setup_ui is pyuic output moved into a linted file
BlocksScreen/lib/ui is excluded from ruff (exclude) and pylint (ignore-paths). lib/panels/ is not, so these ~420 generated lines now count against the pylint score: one method with ~250 statements trips R0915 (too-many-statements) and R0914 (too-many-locals), and mainWindow.py grows to ~1690 lines. Split it by region so each piece is readable and under the limits:
def _setup_ui(self) -> None:
"""Build header bar, tab widget and tab pages."""
self._setup_window()
self._setup_tabs()
self._setup_header()
self.setCentralWidget(self.main_widget)2. mainWindow.py:1373-1496: the four tab blocks are the same 31 lines with different names
A factory removes ~90 lines. Two quirks to keep: controlTab alone uses a 720 base width, and the filament disabled icon is really named ICON_filamente_blocked.png, so pass the blocked path explicitly or rename the resource:
def _make_tab(self, name: str, stem: str, blocked: str) -> QtWidgets.QWidget:
tab = QtWidgets.QWidget()
tab.setObjectName(name)
tab.setMinimumSize(720, 420)
tab.setMaximumSize(1024, 720)
icon = QtGui.QIcon()
base = ":/icons/media/main_menu/"
icon.addPixmap(QtGui.QPixmap(f"{base}{stem}.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
icon.addPixmap(QtGui.QPixmap(f"{base}{stem}_pressed.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.On)
icon.addPixmap(QtGui.QPixmap(f"{base}{blocked}"), QtGui.QIcon.Mode.Disabled, QtGui.QIcon.State.On)
self.main_content_widget.addTab(tab, icon, "")
return tab
self.printTab = self._make_tab("printTab", "ICON_home", "ICON_home_blocked.png")3. mainWindow.py:1663-1694: _translate wraps internal property keys
No QTranslator is installed anywhere, so _translate does nothing. Also, button_type, name and display_format are keys the paint code switches on, not user text. Routing them through translation means a future .qm could break rendering. Set them directly:
self.extruder_temp_display.setProperty("button_type", "secondary_display")
self.chamber_temp_display.setProperty("display_format", "dual")4. mainWindow.py:1303-1305: stylesheet that does not parse
"MainWindow > {\n url(...Momcake-Thin.ttf);\n}" has no selector after > and no property before url(...), so Qt logs a parse warning on every start. It was dead in the .ui too. Now that it's hand-written code, delete it. setWindowTitle("MainWindow") and QIcon.fromTheme("applications-other") do nothing on a frameless kiosk either.
# delete the self.setStyleSheet("MainWindow > ...") call5. mainWindow.py:1695: dead writes inside _setup_ui
setCurrentIndex(3) is overwritten by setCurrentIndex(0) at :143. The "Filament" / "nozzle" placeholder texts are overwritten by "PLA" / "0.4mm" at :228-231. Set each value once, in _setup_ui:
self.filament_type_icon.setText("PLA")
self.nozzle_size_icon.setText("0.4mm")6. mainWindow.py:1307-1343: layout hints on widgets that have no layout
main_content_widget and main_header_layout are placed with setGeometry on a main_widget that has no layout. setSizePolicy, stretch, setSizeIncrement and setBaseSize do nothing there, and the last two only apply to top-level windows. Keep the min/max clamps and drop the rest:
self.main_content_widget.setGeometry(QtCore.QRect(0, 60, 800, 420))
self.main_content_widget.setMinimumSize(800, 400)
self.main_content_widget.setMaximumSize(1024, 720)7. widgets/MainWindow/: new package has no __init__.py
Both lib/panels/ and lib/panels/widgets/ are regular packages, but this one is an implicit namespace package. The same applies to the folders the rest of the stack adds (Common, ControlTab, FilamentTab, PrintTab, UtilitiesTab), so one commit with six empty __init__.py files covers them all. PEP 8 prefers lowercase package names, optional since the whole stack uses PascalCase.
# BlocksScreen/lib/panels/widgets/MainWindow/__init__.py
"""Main-window overlay pages: cancel, connection, notification, update."""8. mainWindow.py:26-30: imports are interleaved
isort sorts case-sensitively, so the MainWindow.* imports group before basePopup. The default ruff selection has no I, so CI won't flag it, but ruff check --select I --fix will:
from lib.panels.widgets.MainWindow.cancelPage import CancelPage
from lib.panels.widgets.MainWindow.connectionPage import ConnectionPage
from lib.panels.widgets.MainWindow.notificationPage import NotificationPage
from lib.panels.widgets.MainWindow.updatePage import UpdatePage
from lib.panels.widgets.basePopup import BasePopup
from lib.panels.widgets.loadWidget import LoadingOverlayWidget9. scripts/requirements-dev.txt:10: second copy of the numpy==2.1.0 pin
scripts/requirements.txt:5 already pins it (for blocks_Scrollbar.py). Two copies will drift, include the runtime file instead:
-r requirements.txt
10. tests/panels/conftest.py:21-23: global purge of every lib.* module
This runs at collection time and also evicts real modules that other test directories already imported in the same xdist worker. Any later string patch such as patch("lib.utils.x.Y") re-imports a fresh copy and patches that copy instead of the one the test holds. The comment names the real culprit (tests/lib/conftest.py leaking a bare MagicMock for lib.utils), so fix the leak there:
# tests/lib/conftest.py
@pytest.fixture(autouse=True)
def _lib_utils_stub(monkeypatch):
monkeypatch.setitem(sys.modules, "lib.utils", MagicMock())11. tests/panels/conftest.py:52,104: stub left for a deleted module
lib.ui.mainWindow_ui / Ui_MainWindow are still stubbed, but this PR deletes that module:
# drop "lib.ui.mainWindow_ui" from _STUB_MODULES and the Ui_MainWindow assignment0c5b070 to
9bc42af
Compare
Descritpion
BlocksScreen/lib/panels/mainWindow.py
BlocksScreen/lib/panels/widgets/MainWindow/cancelPage.py
BlocksScreen/lib/panels/widgets/MainWindow/connectionPage.py
BlocksScreen/lib/panels/widgets/MainWindow/notificationPage.py
BlocksScreen/lib/panels/widgets/MainWindow/updatePage.py
BlocksScreen/lib/ui/mainWindow.ui
BlocksScreen/lib/ui/mainWindow_ui.py
BlocksScreen/lib/ui/mainWindow_v2.ui
BlocksScreen/lib/ui/mainWindow_v2_ui.py
tests/panels/conftest.py
tests/panels/test_main_window_unit.py
scripts/requirements-dev.txt