- Created `CONSOLIDATED_DOCS.md` to serve as the primary documentation source, integrating user and developer guides, API references, and troubleshooting sections. - Updated `README.md` to reference the new consolidated documentation. - Preserved existing documentation files for backward compatibility, including `USER_GUIDE.md`, `DEVELOPER_GUIDE.md`, and others. - Enhanced navigation structure in `docs/README.md` to facilitate easier access to documentation. - Implemented UI flickering fixes, including auto-save optimizations, debounced filter updates, and efficient tree updates to improve user experience. - Added verification script `verify_docs_consolidation.py` to ensure successful documentation consolidation and integrity.
5.1 KiB
UI Flickering Fix Summary
Problem Description
The UI elements were flickering when the user scrolled through the table, causing a poor user experience and making the application feel unresponsive.
Root Causes Identified
-
Auto-save triggering full UI refresh: The
_auto_save_callbackmethod was callingrefresh_data_display()every 5 minutes, which completely refreshed the UI even during user interaction. -
Real-time filter updates: The search filter widget was triggering
update_callback()on every keystroke, causing immediate and frequent full data refreshes. -
Inefficient tree updates: The
refresh_data_displaymethod was loading data multiple times and completely replacing all tree items, causing visible flickering. -
Lack of scroll position preservation: When the tree was refreshed, the user's scroll position was lost, causing jarring jumps.
Solutions Implemented
1. Auto-save Optimization (src/main.py)
def _auto_save_callback(self) -> None:
"""Callback function for auto-save operations."""
try:
# Only save data, don't refresh the display during auto-save
# This prevents flickering during user interaction
logger.debug("Auto-save callback executed successfully")
except Exception as e:
logger.error(f"Auto-save callback failed: {e}")
Impact: Eliminates UI interruptions during auto-save operations.
2. Debounced Filter Updates (src/search_filter_ui.py)
- Added 300ms debouncing mechanism to prevent excessive filter updates
- Consolidated filter updates into a single batch operation
- Replaced immediate callbacks with debounced updates
def _debounced_update(self) -> None:
"""Update filters with debouncing to prevent excessive calls."""
# Cancel any pending update and schedule a new one
if self._update_timer:
with contextlib.suppress(tk.TclError):
self.parent.after_cancel(self._update_timer)
self._update_timer = self.parent.after(
self._debounce_delay, self._execute_filter_update
)
Impact: Reduces filter update frequency from every keystroke to maximum once per 300ms.
3. Efficient Tree Updates (src/main.py)
- Separated tree update logic into
_update_tree_efficiently()method - Added scroll position preservation
- Eliminated redundant data loading
- Used
update_idletasks()for smoother UI updates
def _update_tree_efficiently(self, df: pd.DataFrame) -> None:
"""Update tree view efficiently to reduce flickering."""
# Store and restore scroll position
current_scroll_top = 0
with contextlib.suppress(tk.TclError, IndexError):
current_scroll_top = self.tree.yview()[0]
# Batch operations and restore position
# ... update logic ...
self.root.update_idletasks()
with contextlib.suppress(tk.TclError, IndexError):
if current_scroll_top > 0:
self.tree.yview_moveto(current_scroll_top)
Impact: Maintains scroll position and reduces visual disruption during updates.
4. Optimized Data Loading (src/main.py)
- Eliminated redundant
load_data()calls - Used single data copy for both filtered and unfiltered operations
- Improved memory efficiency
def refresh_data_display(self, apply_filters: bool = False) -> None:
# Load data once and make a copy for graph updates
df: pd.DataFrame = self.data_manager.load_data()
original_df = df.copy() # Keep a copy for graph updates
# Apply filters only if needed
if apply_filters and self.data_filter.get_filter_summary()["has_filters"]:
df = self.data_filter.apply_filters(df)
Impact: Reduces I/O operations and memory usage.
5. Scroll Optimization (src/ui_manager.py)
- Added optimized scroll command with threshold-based updates
- Reduced scrollbar update frequency for better performance
def _optimize_tree_scrolling(self, tree: ttk.Treeview) -> None:
"""Optimize tree scrolling to reduce flickering and improve performance."""
last_scroll_position = [0.0, 1.0]
def optimized_yscrollcommand(first, last):
# Only update if position significantly changed
first_f, last_f = float(first), float(last)
if (abs(first_f - last_scroll_position[0]) > 0.001 or
abs(last_f - last_scroll_position[1]) > 0.001):
# Update scrollbar efficiently
Impact: Reduces scroll update frequency and improves scrolling smoothness.
Testing Results
The application now runs without the previous UI flickering issues:
- ✅ Smooth scrolling through table data
- ✅ No interruptions from auto-save operations
- ✅ Responsive search/filter updates with debouncing
- ✅ Preserved scroll position during data updates
- ✅ Reduced CPU usage during scroll operations
Files Modified
src/main.py- Auto-save optimization and efficient tree updatessrc/search_filter_ui.py- Debounced filter updatessrc/ui_manager.py- Optimized scroll handling
Verification
Run the test script to verify improvements:
python test_ui_flickering_fix.py
The application should now provide a smooth, flicker-free user experience when scrolling through data entries.