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
32from PyQt6 .QtGui import QPainter , QPalette , QPixmap , QTransform
43from PyQt6 .QtWidgets import QFrame , QGraphicsPixmapItem , QGraphicsScene , QGraphicsView
54
5+ from editor .image_utils import build_display_image_frame
6+
67from .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