@@ -208,6 +208,17 @@ def clear_all_state(self):
208208 self .scene .removeItem (self ._preview_item )
209209 self ._preview_item = None
210210
211+ # 清空框选矩形
212+ if self ._box_select_rect_item :
213+ try :
214+ if self ._box_select_rect_item .scene ():
215+ self .scene .removeItem (self ._box_select_rect_item )
216+ except RuntimeError :
217+ pass # C++ 对象已被删除
218+ self ._box_select_rect_item = None
219+ self ._is_box_selecting = False
220+ self ._box_select_start_pos = None
221+
211222 # 清空缓存
212223 if hasattr (self , '_text_render_cache' ):
213224 self ._text_render_cache .clear ()
@@ -246,6 +257,7 @@ def on_image_changed(self, image):
246257 self ._inpainted_image_item = None
247258 self ._preview_item = None
248259 self ._image_np = None
260+ self ._box_select_rect_item = None # scene.clear() 会删除所有 item
249261
250262 if image is None :
251263 return
@@ -1154,8 +1166,17 @@ def mousePressEvent(self, event):
11541166 self ._is_box_selecting = True
11551167 self ._box_select_start_pos = self .mapToScene (event .pos ())
11561168
1157- # 创建框选矩形
1158- if self ._box_select_rect_item is None :
1169+ # 创建框选矩形(检查是否需要重新创建)
1170+ need_create = self ._box_select_rect_item is None
1171+ if not need_create :
1172+ # 检查 C++ 对象是否仍然有效
1173+ try :
1174+ _ = self ._box_select_rect_item .scene ()
1175+ except RuntimeError :
1176+ need_create = True
1177+ self ._box_select_rect_item = None
1178+
1179+ if need_create :
11591180 pen = QPen (QColor (0 , 120 , 215 , 180 )) # 蓝色半透明
11601181 pen .setWidth (2 )
11611182 pen .setStyle (Qt .PenStyle .DashLine )
@@ -1186,12 +1207,24 @@ def mouseMoveEvent(self, event):
11861207 """Handle mouse move for drawing."""
11871208 # 处理框选
11881209 if self ._is_box_selecting and self ._box_select_start_pos :
1189- current_pos = self .mapToScene (event .pos ())
1190- # 更新框选矩形
1191- rect = QRectF (self ._box_select_start_pos , current_pos ).normalized ()
1192- self ._box_select_rect_item .setRect (rect )
1193- event .accept ()
1194- return
1210+ # 检查框选矩形是否仍然有效(可能在切换图片时被删除)
1211+ if self ._box_select_rect_item is None :
1212+ self ._is_box_selecting = False
1213+ self ._box_select_start_pos = None
1214+ return
1215+ try :
1216+ current_pos = self .mapToScene (event .pos ())
1217+ # 更新框选矩形
1218+ rect = QRectF (self ._box_select_start_pos , current_pos ).normalized ()
1219+ self ._box_select_rect_item .setRect (rect )
1220+ event .accept ()
1221+ return
1222+ except RuntimeError :
1223+ # C++ 对象已被删除,重置状态
1224+ self ._box_select_rect_item = None
1225+ self ._is_box_selecting = False
1226+ self ._box_select_start_pos = None
1227+ return
11951228
11961229 if self ._is_drawing_textbox :
11971230 self ._update_textbox_drawing (event .pos ())
@@ -1231,31 +1264,36 @@ def mouseReleaseEvent(self, event):
12311264 # 处理框选完成
12321265 if self ._is_box_selecting and event .button () == Qt .MouseButton .LeftButton :
12331266 self ._is_box_selecting = False
1267+ self ._box_select_start_pos = None
12341268
1235- # 隐藏框选矩形
1269+ # 隐藏框选矩形(检查对象是否仍然有效)
12361270 if self ._box_select_rect_item :
1237- select_rect = self ._box_select_rect_item .rect ()
1238- self ._box_select_rect_item .setVisible (False )
1239-
1240- # 查找框内的所有 RegionTextItem
1241- selected_indices = []
1242- for i , item in enumerate (self ._region_items ):
1243- if isinstance (item , RegionTextItem ):
1244- # 检查 item 的边界是否与选择框相交
1245- item_rect = item .sceneBoundingRect ()
1246- if select_rect .intersects (item_rect ):
1247- selected_indices .append (i )
1248-
1249- # 更新选择
1250- ctrl_pressed = bool (event .modifiers () & Qt .KeyboardModifier .ControlModifier )
1251- if ctrl_pressed :
1252- # Ctrl+框选:添加到现有选择
1253- current_selection = self .model .get_selection ()
1254- new_selection = list (set (current_selection + selected_indices ))
1255- self .model .set_selection (new_selection )
1256- else :
1257- # 普通框选:替换选择
1258- self .model .set_selection (selected_indices )
1271+ try :
1272+ select_rect = self ._box_select_rect_item .rect ()
1273+ self ._box_select_rect_item .setVisible (False )
1274+
1275+ # 查找框内的所有 RegionTextItem
1276+ selected_indices = []
1277+ for i , item in enumerate (self ._region_items ):
1278+ if isinstance (item , RegionTextItem ):
1279+ # 检查 item 的边界是否与选择框相交
1280+ item_rect = item .sceneBoundingRect ()
1281+ if select_rect .intersects (item_rect ):
1282+ selected_indices .append (i )
1283+
1284+ # 更新选择
1285+ ctrl_pressed = bool (event .modifiers () & Qt .KeyboardModifier .ControlModifier )
1286+ if ctrl_pressed :
1287+ # Ctrl+框选:添加到现有选择
1288+ current_selection = self .model .get_selection ()
1289+ new_selection = list (set (current_selection + selected_indices ))
1290+ self .model .set_selection (new_selection )
1291+ else :
1292+ # 普通框选:替换选择
1293+ self .model .set_selection (selected_indices )
1294+ except RuntimeError :
1295+ # C++ 对象已被删除,重置引用
1296+ self ._box_select_rect_item = None
12591297
12601298 event .accept ()
12611299 return
0 commit comments