qt-debugging

- Read the full Qt warning output — Qt prints actionable warnings before crashes

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "qt-debugging" with this command: npx skills add l3digital-net/claude-code-plugins/l3digital-net-claude-code-plugins-qt-debugging

Qt Debugging

Diagnostic Approach

  • Read the full Qt warning output — Qt prints actionable warnings before crashes

  • Categorize the failure type (see categories below)

  • Isolate — reproduce with a minimal test case

  • Fix and verify with QT_QPA_PLATFORM=offscreen pytest

Enabling Verbose Qt Output

Show all Qt debug/warning messages

QT_LOGGING_RULES="*.debug=true" python -m myapp

Filter to specific categories

QT_LOGGING_RULES="qt.qpa.=true;qt.widgets.=true" python -m myapp

C++

qputenv("QT_LOGGING_RULES", "*.debug=true");

Python: install message handler to capture Qt output

from PySide6.QtCore import qInstallMessageHandler, QtMsgType

def qt_message_handler(mode: QtMsgType, context, message: str) -> None: if mode == QtMsgType.QtCriticalMsg or mode == QtMsgType.QtFatalMsg: import traceback traceback.print_stack() print(f"Qt [{mode.name}]: {message}")

qInstallMessageHandler(qt_message_handler)

Common Failure Categories

Widget Never Appears

  • show() not called on top-level widget

  • Parent widget not shown (child inherits visibility)

  • setFixedSize(0, 0) or zero content margins collapsing it

  • Widget created after app.exec() returns (after event loop exits)

  • setVisible(False) still in effect

Diagnostic

print(widget.isVisible(), widget.size(), widget.parentWidget())

Crash / Segfault on Widget Access

  • Widget garbage-collected (Python deleted the QWidget before Qt finished with it)

  • Common cause: widget stored only in a local variable, not self._widget

  • Fix: always assign widgets to self attributes in init

BAD — local variable, GC can collect it

def setup(self): btn = QPushButton("Click") # may be deleted immediately

GOOD

def setup(self): self._btn = QPushButton("Click")

"QObject: Cannot create children for a parent in a different thread"

  • A QObject with a parent is being created in a non-main thread

  • Fix: create the object parentless, then use moveToThread or deleteLater for cleanup

"QPixmap: Must construct a QGuiApplication before a QPaintDevice"

  • QPixmap , QImage , or QIcon created before QApplication exists

  • Fix: move all Qt object construction after app = QApplication(sys.argv)

"RuntimeError: Internal C++ object (QWidget) already deleted"

  • Accessing a Python wrapper after Qt deleted the underlying C++ object

  • Common with deleteLater() — the deletion happens asynchronously

  • Fix: check sip.isdeleted(widget) (PyQt6) or use QPointer pattern

Event Loop Frozen / UI Unresponsive

  • Blocking call on main thread (I/O, time.sleep , heavy computation)

  • Fix: move to QRunnable /QThread (see qt-threading skill)

Quick diagnostic: add to slow code path

from PySide6.QtCore import QCoreApplication QCoreApplication.processEvents() # temporarily unblocks — confirms event loop is stuck

Signal Connected But Never Fires

  • Verify the sender object is still alive

  • Add debug connection: signal.connect(lambda *a: print("FIRED", a))

  • Check signal type signature matches — Signal(int) will not fire if you emit Signal(str) equivalent

  • For C++: verify Q_OBJECT is present and moc ran after last change

Memory / Resource Leak Detection

Track live QObject count

from PySide6.QtCore import QObject

No built-in — use objgraph

import objgraph objgraph.show_most_common_types(limit=20) objgraph.show_growth()

Useful Diagnostic Patterns

Dump full widget tree

def dump_widget_tree(widget, indent=0): print(" " * indent + repr(widget)) for child in widget.children(): if isinstance(child, QWidget): dump_widget_tree(child, indent + 1)

Check if event loop is running

from PySide6.QtCore import QEventLoop print(QCoreApplication.instance().loopLevel()) # > 0 if exec() is running

Force sync paint (debugging paint issues)

widget.repaint() # synchronous vs update() which defers

QSS / Style Debugging

Print effective stylesheet for a widget

print(widget.styleSheet())

Check if style rules are applying

Add a unique background to isolate

widget.setStyleSheet("background: lime;") # visible indicator

Force re-evaluation after property change

widget.style().unpolish(widget) widget.style().polish(widget) widget.update()

C++ Specific

// Enable ASAN for memory errors // cmake -DCMAKE_CXX_FLAGS="-fsanitize=address" ...

// Qt debug output qDebug() << "Widget size:" << widget->size(); qWarning() << "Unexpected state:" << state;

// Print all object properties qDebug() << widget->metaObject()->className();

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

qt-qml

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

qt-architecture

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

qt-packaging

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

qt-layouts

No summary provided by upstream source.

Repository SourceNeeds Review