Skip to main content

Overview

Batch operations allow you to modify metadata across multiple files simultaneously, making it efficient to manage large music collections.

Global Edit Mode

Global Edit Mode enables batch editing by selecting multiple files:

Entering Global Edit Mode

1

Select Multiple Files

Click and drag to select multiple files in the file list, or use Ctrl+A to select all visible files.
2

Global Mode Activates

The sidebar automatically switches to Global Edit mode when multiple files are selected.
3

Edit Fields

Modify any metadata fields. Empty fields will keep their original values.
4

Save Changes

Press Ctrl+S or click Save to apply changes to all selected files.
# From tagqt/ui/main.py - Detecting multiple selection
def _handle_selection_deferred(self):
    files = self.get_selected_files()
    
    if len(files) > 1:
        self.sidebar.set_global_mode(True)
        self.current_file = None 
        self.metadata = None
    elif len(files) == 1:
        self.sidebar.set_global_mode(False)
        self.load_file(files[0])

Exiting Global Edit Mode

Press Escape to exit Global Edit mode and return to single-file editing:
# From tagqt/ui/main.py - Exit global mode
def exit_global_mode(self):
    self.sidebar.set_global_mode(False)
    
    files = self.get_selected_files()
    if files:
        first_file = files[0]
        # ... select and load first file ...
Empty fields in Global Edit mode preserve the original values for each file. Only fields with content will be applied.

Global Save Operation

When saving in Global Edit mode, TagQt processes all selected files:
# From tagqt/ui/main.py - Global save workflow
def save_metadata(self):
    if getattr(self.sidebar, 'is_global_mode', False):
        files = self.get_selected_files()
        if not files:
            return
            
        changes = self.sidebar.get_modified_fields()
        if not changes:
            self.show_toast("No fields were modified.")
            return
            
        if not self._prepare_batch("Global Save Status"):
            return
        self.progress_bar.setRange(0, len(files))
        self.progress_bar.setFormat("Saving... 0%")
        
        self._start_batch_worker(SaveWorker(files, changes))

Batch Worker System

All batch operations use a threaded worker system to prevent UI blocking:
# From tagqt/ui/main.py - Starting batch operations
def _start_batch_worker(self, worker, result_handler=None, connect_log=False):
    self.thread = QThread()
    self.worker = worker
    self.worker.moveToThread(self.thread)
    
    self.thread.started.connect(self.worker.run)
    self.worker.finished.connect(self.thread.quit)
    
    self.worker.progress.connect(self.on_batch_progress)
    self.worker.result.connect(result_handler or self.on_batch_result)
    self.worker.finished.connect(self.on_batch_finished)
    
    self.thread.start()

Progress Tracking

Batch operations display real-time progress:

Progress Bar

Shows percentage completion and current operation

Status Dialog

Click the progress bar to view detailed status for each file
# From tagqt/ui/main.py - Progress updates
def on_batch_progress(self, current, total):
    if total > 0:
        target_value = int((current / total) * 100)
        self.progress_bar.setMaximum(100)
        
        self._progress_animation.setStartValue(self.progress_bar.value())
        self._progress_animation.setEndValue(target_value)
        self._progress_animation.start()
        
        self.progress_bar.setFormat(f"Processing... {target_value}%")
    self.batch_dialog.update_progress(current, total)

Batch Status Dialog

The Batch Status Dialog provides detailed information:
  • Per-file status - Success, Skipped, Error, etc.
  • Status messages - What happened to each file
  • Result summary - Total counts by status
# From tagqt/ui/main.py - Adding results
def on_batch_result(self, filepath, status, message):
    self.batch_dialog.add_result(filepath, status, message)
    if status in ["Updated", "Success", "Found"]:
        self.file_list.update_file(filepath)

Canceling Operations

Cancel long-running batch operations using the Cancel button:
# From tagqt/ui/main.py - Canceling
def cancel_batch_operation(self):
    if hasattr(self, 'worker') and self.worker:
        self.worker.stop()
    
    self.batch_cancel_btn.setEnabled(False)
    self.batch_cancel_btn.setText("Stopping...")
Some operations like file renaming cannot be safely canceled mid-operation and may complete the current file before stopping.

Scoped Operations

All batch operations (“All Visible”) only affect visible files. Use the filter input to scope operations to specific subsets.
# From tagqt/ui/main.py - Getting all visible files
def get_all_files(self):
    files = []
    iterator = QTreeWidgetItemIterator(self.file_list)
    while iterator.value():
        item = iterator.value()
        # Check if item is hidden
        if not item.isHidden():
            filepath = item.data(0, Qt.UserRole)
            if filepath:
                files.append(filepath)
        iterator += 1
    return list(set(files))

Context Menu Operations

Right-click selected files for batch operations:
  • Get Covers (Selected)
  • Get Lyrics (Selected)
  • Resize Covers (Selected)
  • Romanize Lyrics (Selected)
  • Rename Files (Selected)
  • Re-encode FLAC (Selected)
  • Auto-Tag (Selected)
# From tagqt/ui/main.py - Context menu
def show_context_menu(self, pos):
    menu = QMenu(self)
    
    files = self.get_selected_files()
    has_selection = len(files) > 0
    
    get_covers_action = QAction("Get Covers (Selected)", self)
    get_covers_action.triggered.connect(self.fetch_covers_context)
    get_covers_action.setEnabled(has_selection)
    menu.addAction(get_covers_action)

Available Batch Operations

Get Lyrics (All)

Fetch lyrics for all visible files

Get Covers (All)

Download album artwork for all files

Auto-Tag (All)

Fetch metadata from MusicBrainz

Resize Covers

Resize embedded cover art

Rename Files

Batch rename based on metadata

Romanize Lyrics

Convert Korean lyrics to romanized text

Case Conversion

Convert to Title Case, UPPERCASE, or lowercase

Re-encode FLAC

Re-encode FLAC files with optimal compression

Performance Considerations

Batch operations are processed sequentially to respect API rate limits (MusicBrainz) and prevent resource exhaustion.
The worker system ensures:
  • Non-blocking UI - Application remains responsive
  • Progress updates - Real-time feedback
  • Error handling - Individual file failures don’t stop the batch
  • Cancellation support - Stop operations mid-process

Keyboard Shortcuts

ShortcutAction
Ctrl+GEnter Global Edit mode (select all visible)
Ctrl+ASelect all files
EscapeExit Global Edit mode
Ctrl+SSave changes

Next Steps

Metadata Editing

Learn about single file editing

Auto-Tagging

Automate metadata with MusicBrainz

Build docs developers (and LLMs) love