@@ -260,6 +260,17 @@ def __init__(self, image_path: str, animation: str = "circle") -> None:
260260 super ().__init__ ()
261261 self ._image_path = image_path
262262 self ._animation = animation
263+ self ._progress = 0.0
264+ self ._committed = False
265+ self ._areas : list [tuple [int , int , int , int , float ]] = []
266+ self ._per_screen_scaled_old : list [tuple [QPixmap , int , int ]] = []
267+ self ._per_screen_scaled_new : list [tuple [QPixmap , int , int ]] = []
268+ self .fit_mode = _read_fit_mode ()
269+ self ._bg_color = _read_background_color ()
270+ self ._pixmap_new = QPixmap ()
271+ self ._pixmap_old = QPixmap ()
272+ self ._resources_freed = False
273+
263274 self .setGeometry (QApplication .primaryScreen ().geometry ())
264275 self .setAttribute (Qt .WidgetAttribute .WA_TransparentForMouseEvents , True )
265276 self .setAttribute (Qt .WidgetAttribute .WA_ShowWithoutActivating , True )
@@ -268,17 +279,6 @@ def __init__(self, image_path: str, animation: str = "circle") -> None:
268279 self .setAttribute (Qt .WidgetAttribute .WA_DeleteOnClose , True )
269280 self .winId ()
270281
271- self ._pixmap_new = QPixmap ()
272- self ._pixmap_old = QPixmap ()
273-
274- self .fit_mode = _read_fit_mode ()
275- self ._bg_color = _read_background_color ()
276- self ._areas : list [tuple [int , int , int , int , float ]] = []
277- self ._per_screen_scaled_old : list [tuple [QPixmap , int , int ]] = []
278- self ._per_screen_scaled_new : list [tuple [QPixmap , int , int ]] = []
279- self ._progress = 0.0
280- self ._committed = False
281-
282282 self ._timeline = QTimeLine (self ._ANIMATION_MS , self )
283283 self ._timeline .setUpdateInterval (self ._FRAME_MS )
284284 self ._timeline .setEasingCurve (QEasingCurve .Type .OutQuad )
@@ -287,9 +287,9 @@ def __init__(self, image_path: str, animation: str = "circle") -> None:
287287
288288 def start (self ) -> None :
289289 """Load images asynchronously, then attach to WorkerW and begin animation."""
290- self ._loader = _ImageLoader (self ._image_path , _transcoded_wallpaper_path ())
291- self ._loader .loaded .connect (self ._on_images_loaded )
292- self ._loader .start ()
290+ self ._wallpaper_loader = _ImageLoader (self ._image_path , _transcoded_wallpaper_path ())
291+ self ._wallpaper_loader .loaded .connect (self ._on_images_loaded )
292+ self ._wallpaper_loader .start ()
293293
294294 def _on_images_loaded (self , new_img : QImage , old_img : QImage ) -> None :
295295 self ._pixmap_new = QPixmap .fromImage (new_img )
@@ -617,15 +617,39 @@ def paintEvent(self, _) -> None:
617617 p .drawPixmap (dx + ox_n , dy + oy_n , scaled_n )
618618 p .restore ()
619619
620+ def _free_resources (self ):
621+ if getattr (self , "_resources_freed" , True ):
622+ return
623+ self ._resources_freed = True
624+
625+ for tl in (self ._timeline , getattr (self , "_fade_timeline" , None )):
626+ if tl and tl .state () != QTimeLine .State .NotRunning :
627+ tl .stop ()
628+
629+ self ._pixmap_new = QPixmap ()
630+ self ._pixmap_old = QPixmap ()
631+ self ._per_screen_scaled_new .clear ()
632+ self ._per_screen_scaled_old .clear ()
633+
634+ wl = getattr (self , "_wallpaper_loader" , None )
635+ if wl is not None :
636+ try :
637+ wl .loaded .disconnect ()
638+ except TypeError , RuntimeError :
639+ pass
640+ if wl .isRunning ():
641+ wl .quit ()
642+ wl .wait (1000 )
643+ self ._wallpaper_loader = None
644+
620645 def nativeEvent (self , _ , message ):
621646 msg = ctypes .cast (int (message ), ctypes .POINTER (wintypes .MSG )).contents
622647 if msg .message == WM_DESTROY :
648+ self ._free_resources ()
623649 self .deleteLater ()
624650 return True , 0
625651 return False , 0
626652
627653 def closeEvent (self , event ) -> None :
628- for tl in (self ._timeline , getattr (self , "_fade_timeline" , None )):
629- if tl and tl .state () != QTimeLine .State .NotRunning :
630- tl .stop ()
654+ self ._free_resources ()
631655 super ().closeEvent (event )
0 commit comments