@@ -71,7 +71,11 @@ def selectionCommand(self, index, event=None):
7171
7272
7373class VideoListDockWidget (QtWidgets .QDockWidget ):
74- """dock for listing video files associated with the project."""
74+ """dock for listing video files associated with the project.
75+
76+ Uses a debounce timer to delay video loading when rapidly switching videos
77+ with , and . keys, preventing race conditions from out-of-order signal processing.
78+ """
7579
7680 selectionChanged = QtCore .Signal (str )
7781
@@ -80,6 +84,13 @@ def __init__(self, *args, **kwargs):
8084 self .setWindowTitle ("Project Videos" )
8185 self ._project = None
8286 self ._suppress_selection_event = False
87+ self ._pending_selection = None # Track the pending video selection
88+
89+ # Debounce timer to delay video loading when rapidly switching videos
90+ self ._debounce_timer = QtCore .QTimer (self )
91+ self ._debounce_timer .setSingleShot (True )
92+ self ._debounce_timer .setInterval (150 ) # 150ms delay
93+ self ._debounce_timer .timeout .connect (self ._emit_pending_selection )
8394
8495 self ._video_filter_box = QtWidgets .QLineEdit (self )
8596 self ._video_filter_box .setFocusPolicy (QtCore .Qt .FocusPolicy .ClickFocus )
@@ -98,14 +109,27 @@ def __init__(self, *args, **kwargs):
98109 self ._video_filter_box .textChanged .connect (self ._filter_list )
99110
100111 def _selection_changed (self , current , _ ):
101- """Emit signal when the selected video changes."""
102- if self ._suppress_selection_event :
112+ """Handle video selection change with debouncing.
113+
114+ When rapidly switching videos, this cancels pending video loads and
115+ delays the selectionChanged signal emission to prevent race conditions.
116+ """
117+ if self ._suppress_selection_event or not current :
103118 return
104- if current :
105- video = current .data (QtCore .Qt .ItemDataRole .UserRole )
106- self .selectionChanged .emit (video )
107- else :
108- self .selectionChanged .emit ("" )
119+
120+ # Store the pending selection.
121+ self ._pending_selection = current .data (QtCore .Qt .ItemDataRole .UserRole )
122+
123+ # Cancel any pending timer and start a new one
124+ # This ensures only the final video in a rapid sequence gets loaded
125+ self ._debounce_timer .stop ()
126+ self ._debounce_timer .start ()
127+
128+ def _emit_pending_selection (self ):
129+ """Emit the pending selection signal after the debounce timer expires."""
130+ if self ._pending_selection is not None :
131+ self .selectionChanged .emit (self ._pending_selection )
132+ self ._pending_selection = None
109133
110134 def _filter_list (self , text ):
111135 """Filter the video list based on the text entered in the filter box."""
0 commit comments