Files
Grid_Trading/docs/superpowers/plans/2026-07-09-gui-visual-refresh.md
2026-07-14 16:21:32 +08:00

6.0 KiB

GUI Visual Refresh Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Refresh the PySide6 main window into a clean light desktop-tool style and apply A-share profit/loss colors to all PnL-like fields.

Architecture: Keep the existing MainWindow layout and data flow. Add focused UI helpers in main_window.py for theme setup, table setup, and PnL styling, then cover them with lightweight offscreen GUI tests.

Tech Stack: Python 3.11+, PySide6, pytest.


File Structure

  • Modify src/grid_trading/ui/main_window.py: apply QSS theme, assign object names, centralize table setup, and style PnL labels/items.
  • Modify tests/test_ui.py: add offscreen GUI tests for theme markers and profit/loss item styling.
  • No domain, service, storage, or database changes.

Task 1: Add Failing GUI Tests

Files:

  • Test: tests/test_ui.py

  • Step 1: Write failing tests for theme markers and PnL colors

def test_main_window_applies_light_theme(tmp_path, monkeypatch):
    monkeypatch.setenv("QT_QPA_PLATFORM", "offscreen")

    from PySide6.QtWidgets import QApplication
    from grid_trading.services.trading_service import TradingService
    from grid_trading.ui.main_window import MainWindow

    app = QApplication.instance() or QApplication([])
    service = TradingService(tmp_path / "grid.db")
    window = MainWindow(service)

    assert window.centralWidget().objectName() == "appRoot"
    assert window.holdings_table.alternatingRowColors()
    assert "QMainWindow" in window.styleSheet()

    window.close()
    service.close()
    app.processEvents()
def test_profit_and_loss_cells_use_a_share_colors(tmp_path, monkeypatch):
    monkeypatch.setenv("QT_QPA_PLATFORM", "offscreen")

    from datetime import datetime
    from decimal import Decimal
    from PySide6.QtGui import QColor
    from PySide6.QtWidgets import QApplication
    from grid_trading.domain.models import PositionSummary
    from grid_trading.services.trading_service import TradingService
    from grid_trading.ui.main_window import MainWindow

    app = QApplication.instance() or QApplication([])
    service = TradingService(tmp_path / "grid.db")
    window = MainWindow(service)
    window._positions = [
        PositionSummary(
            instrument_id=1,
            code="510300",
            name="沪深300ETF",
            total_quantity=100,
            available_quantity=100,
            base_quantity=0,
            grid_quantity=100,
            remaining_cost=Decimal("1000"),
            average_cost=Decimal("10"),
            position_breakeven_price=Decimal("10"),
            account_breakeven_price=Decimal("10"),
            realized_pnl=Decimal("12.34"),
            grid_profit=Decimal("-5.67"),
            current_price=Decimal("10.50"),
            market_value=Decimal("1050"),
            floating_pnl=Decimal("50"),
            last_quote_at=datetime(2026, 7, 9, 10, 0, 0),
        )
    ]

    window._fill_holdings_table()

    profit_item = window.holdings_table.item(0, 10)
    loss_item = window.holdings_table.item(0, 11)
    assert profit_item.foreground().color() == QColor("#c62828")
    assert profit_item.font().bold()
    assert loss_item.foreground().color() == QColor("#2e7d32")
    assert loss_item.font().bold()

    window.close()
    service.close()
    app.processEvents()
  • Step 2: Run the tests and verify they fail

Run:

pytest tests/test_ui.py::test_main_window_applies_light_theme tests/test_ui.py::test_profit_and_loss_cells_use_a_share_colors -q

Expected: both new tests fail because object names, theme QSS, alternating row setup, and PnL item colors do not exist yet.

Task 2: Add Light Theme and Shared Table Setup

Files:

  • Modify: src/grid_trading/ui/main_window.py

  • Step 1: Add imports and theme constants

Add Decimal, QBrush, QColor, QFont, and QAbstractItemView imports needed by the helpers.

  • Step 2: Apply theme in _build_ui

Set root.setObjectName("appRoot"), call self._apply_light_theme(), and set object names on the navigation, summary card frames, toolbar buttons, tab widget, and tables.

  • Step 3: Add _apply_light_theme and _configure_table

Create helpers that set the QSS theme once and apply consistent table settings: alternating rows, row selection, no editing, visible grid, row height, and header resize behavior.

  • Step 4: Run theme test

Run:

pytest tests/test_ui.py::test_main_window_applies_light_theme -q

Expected: PASS.

Task 3: Add PnL Styling Helpers

Files:

  • Modify: src/grid_trading/ui/main_window.py

  • Step 1: Add _style_pnl_item, _style_pnl_label, and _make_item

Use the raw Decimal | None value, not the formatted string, to decide color and font weight:

  • value > 0: foreground #c62828, bold.

  • value < 0: foreground #2e7d32, bold.

  • otherwise: default foreground, non-bold.

  • Step 2: Use helpers in summary and tables

Apply the helpers to summary floating PnL and these table columns:

  • holdings: columns 10, 11, 12.

  • grid levels: column 6.

  • open grid lots: column 5.

  • grid matches: column 7.

  • Step 3: Run PnL style test

Run:

pytest tests/test_ui.py::test_profit_and_loss_cells_use_a_share_colors -q

Expected: PASS.

Task 4: Full Verification

Files:

  • No additional changes expected.

  • Step 1: Run UI test module

Run:

pytest tests/test_ui.py -q

Expected: PASS.

  • Step 2: Run full test suite

Run:

pytest -q

Expected: PASS.

  • Step 3: Review diff

Run:

git diff -- src/grid_trading/ui/main_window.py tests/test_ui.py docs/superpowers/specs/2026-07-09-gui-visual-refresh-design.md docs/superpowers/plans/2026-07-09-gui-visual-refresh.md

Expected: diff only contains the UI theme, PnL styling, tests, and docs for this task.