Two independent root causes for '左右能拉,上下不能拉':
1. Event delivery: the top 6px edge band belongs to QMenuBar, which
actively consumes mouse events (menu hover) — nothing ever propagated
to QMainWindow, so T/TL/TR (and maximize-restore from top edge) were
dead on every platform. Install an event filter on menuBar()/statusBar():
within the edge band it handles hover cursor, press (grabMouse), drag
and release; outside the band everything passes through (menus open
normally, native QSizeGrip corner drag preserved).
2. Layout minimum: MonitorPanel's minimumSizeHint (~1015px of stacked
tables/group boxes) propagated through QTabWidget → central widget →
QMainWindow, making the window minimum size 898x1121. Any vertical
shrink was clamped dead. Set explicit per-tab-page minimumSize
(320x200) + window minimumSize (760x480).
Tests: test_resize.py now drives edges through real event delivery
(childAt → child widget, propagation/filter path) for L/R/T/B/TL/TR/BL,
verifies BR stays on QSizeGrip, maximize-restore via menubar filter,
and minimum-size regression. All 8 suites pass.
User asked: '窗口应该可以前后左右拉'
Added custom edge drag handling in MainWindow (QMainWindow's default
resize support exists but ignored + we want full control for
maximized state too):
New methods in ui/main_window.py:
- _hit_test_edge(pos) -> 'L'/'R'/'T'/'B'/'TL'/'TR'/'BL'/'BR'/''
6px margin around window. Returns which edge (or corner) the
cursor is on. Returns '' when maximized/fullscreen.
- _edge_to_cursor(edge): sets Qt.SizeHor/Ver/FDiag/BDiag cursor
- _do_resize(global_pos): computes new geometry based on drag
delta. Respects self.minimumWidth/Height (QMainWindow's auto
min size from menu/toolbar/statusbar) and screen bounds.
- _restore_from_max(global_pos): when maximized, click+drag on
TOP edge → showNormal() + set geometry to mouse-relative size
+ continue drag from 'TL' corner (like Windows native behavior)
- mousePressEvent/Move/Release: hook into resize state
- leaveEvent: clear cursor when leaving window
- changeEvent: clear resize state on window state change
State fields added in __init__:
- self._resize_edge, self._resize_start_geo, self._resize_start_pos
- self._resize_margin = 6
- self._dragging_from_max = False
Fix: 'QTabWidget.RightSide' was wrong API; used 'QTabBar.RightSide'
in the multi-tab commit (unrelated, but I noticed while testing).
New test_resize.py (5 tests, all pass):
- 8-region hit-test (4 edges + 4 corners)
- Right-edge drag → width grows
- Left-edge drag → x moves right (width limited by minW)
- Top-left corner drag
- Maximized + click top edge → restored to normal
Existing tests (core 6/6, UI 3/3) still pass.
Build: 57MB exe.