Skip to content

Commit ad6eb02

Browse files
committed
fix(editor): align dual-pane comparison views
1 parent ac2504e commit ad6eb02

2 files changed

Lines changed: 33 additions & 7 deletions

File tree

desktop_qt_ui/ui/editor/graphics_view.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from PyQt6.QtCore import QPointF, QRectF, Qt, QTimer, pyqtSignal
22
from PyQt6.QtGui import QColor, QPainter, QPalette, QTransform
33
from PyQt6.QtWidgets import QFrame, QGraphicsPixmapItem, QGraphicsScene, QGraphicsView
4-
from services import get_logger
5-
from ui.theme import is_dark_theme
64

75
from editor.editor_model import EditorModel
86
from editor.render_coordinator import RenderCoordinator
7+
from services import get_logger
8+
from ui.theme import is_dark_theme
99

1010
from .graphics_view_input import GraphicsViewInputMixin
1111
from .graphics_view_layers import GraphicsViewLayersMixin
@@ -168,6 +168,13 @@ def get_image_scene_rect(self) -> QRectF | None:
168168
return QRectF(r)
169169
return None
170170

171+
def get_view_scene_rect(self) -> QRectF | None:
172+
"""返回当前视图实际使用的场景范围,供双栏视图同步平移边界。"""
173+
rect = self.scene.sceneRect()
174+
if rect.isValid() and not rect.isNull():
175+
return QRectF(rect)
176+
return self.get_image_scene_rect()
177+
171178
def _setup_view(self):
172179
self.setMouseTracking(True)
173180
self.viewport().setMouseTracking(True)

desktop_qt_ui/ui/editor/original_compare_view.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
from editor.image_utils import build_display_image_frame
2-
from PyQt6.QtCore import QPointF, QRectF, Qt
1+
from PyQt6.QtCore import QMargins, QPointF, QRectF, Qt
32
from PyQt6.QtGui import QPainter, QPalette, QPixmap, QTransform
43
from PyQt6.QtWidgets import QFrame, QGraphicsPixmapItem, QGraphicsScene, QGraphicsView
54

5+
from editor.image_utils import build_display_image_frame
6+
67
from .graphics_view import canvas_background_color
78

89

@@ -109,6 +110,7 @@ def sync_view_state(self, transform, center_scene):
109110
self._last_transform = QTransform(transform)
110111
self._last_center_scene = QPointF(center_scene)
111112
self._last_scene_rect = self._resolve_source_scene_rect()
113+
self._sync_source_viewport_geometry()
112114

113115
if self._image_item is None:
114116
return
@@ -121,16 +123,33 @@ def sync_view_state(self, transform, center_scene):
121123
self.viewport().update()
122124

123125
def _resolve_source_scene_rect(self) -> QRectF | None:
124-
# 只取图片 item 矩形:主场景 itemsBoundingRect 会被旋转辅助线等
125-
# 临时超长 item 污染,导致对比视图滚动范围失控
126+
# 主画布显式维护了不受临时 item 影响的 sceneRect,并在图片四周留出
127+
# 平移余量。双栏必须复用同一范围,否则靠近边缘时 centerOn 会在左栏
128+
# 提前被图片边界钳制,造成两栏错位。
126129
if self._source_view is None:
127130
return None
128-
getter = getattr(self._source_view, "get_image_scene_rect", None)
131+
getter = getattr(self._source_view, "get_view_scene_rect", None)
129132
if getter is None:
130133
return None
131134
return getter()
132135

136+
def _sync_source_viewport_geometry(self) -> None:
137+
"""让只读栏的有效视口与可能显示滚动条的主画布完全等大。"""
138+
if self._source_view is None:
139+
return
140+
source_viewport = self._source_view.viewport()
141+
content_rect = self.contentsRect()
142+
margins = QMargins(
143+
0,
144+
0,
145+
max(0, content_rect.width() - source_viewport.width()),
146+
max(0, content_rect.height() - source_viewport.height()),
147+
)
148+
if self.viewportMargins() != margins:
149+
self.setViewportMargins(margins)
150+
133151
def resizeEvent(self, event):
134152
super().resizeEvent(event)
153+
self._sync_source_viewport_geometry()
135154
if self._image_item is not None and self._last_center_scene is not None:
136155
self.centerOn(self._last_center_scene)

0 commit comments

Comments
 (0)