QtHandler

class QtHandler(parent: Optional[QObject] = None, level: int = logging.ERROR)

Bases: Handler

Surface log records to the user as modal dialogs.

Attached to the root logger by poriscope.main_app.App.configure_logger() alongside the console and file handlers.

The default level is ERROR, not NOTSET. Log severity is not a statement about how the user should be interrupted: routine states legitimately log at WARNING - an empty channel, a cold start with no analysis tabs instantiated yet, an operation proceeding without an optional filter - and none of those warrant a modal dialog. Anything the user should be told rather than interrupted by belongs on the add_text_to_display panel instead.

Note poriscope.models.main_model.MainModel.update_logging_level() deliberately skips this handler when it applies a new level to the root logger’s handlers, so choosing a more verbose log level does not turn warnings back into dialogs.

Public Methods

Abstract Methods

These methods must be implemented by subclasses.

(none)

Concrete Methods

QtHandler.emit(record: LogRecord) None

Hand the record to the GUI thread.

Parameters:

record (logging.LogRecord) – The record to display.

QtHandler.show_message_box(record: LogRecord) None

Display one record, queueing any that arrive while a dialog is up.

A modal QMessageBox runs its own nested event loop, during which further queued records are still delivered here. They used to be dropped outright, so a burst of genuine errors showed the first and silently lost the rest - the empty-state path that logs twice in a row lost its second message every time. They are now queued and shown in turn once the dialog closes.

Parameters:

record (logging.LogRecord) – The record to display.

Private Methods

Abstract Methods

These methods must be implemented by subclasses.

(none)

Concrete Methods

QtHandler.__init__(parent: QObject | None = None, level: int = 40)

Build the handler and its cross-thread emitter.

Parameters:
  • parent (Optional[QObject]) – Unused; accepted for symmetry with QObject constructors.

  • level (int) – Minimum level that raises a dialog. Defaults to ERROR.

QtHandler._queue_record(record: LogRecord) None

Hold a record that arrived while a dialog was open.

Records whose formatted text matches the one currently on screen, or one already waiting, are dropped rather than queued - so a loop logging the same failure per event or per channel yields one dialog rather than one per iteration. Distinct messages are all kept.

Parameters:

record (logging.LogRecord) – The record to queue.

QtHandler._show_next_pending() None

Re-post the next queued record, or report what was suppressed.

The record is re-posted through the emitter rather than displayed directly so that it is handled on a later turn of the event loop; showing it inline would nest one dialog’s handler inside another’s for the whole queue.