qt-debugging
4
总安装量
3
周安装量
#52643
全站排名
安装命令
npx skills add https://github.com/l3digital-net/claude-code-plugins --skill qt-debugging
Agent 安装分布
opencode
3
gemini-cli
3
antigravity
3
claude-code
3
github-copilot
3
codex
3
Skill 文档
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
selfattributes 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
QObjectwith a parent is being created in a non-main thread - Fix: create the object parentless, then use
moveToThreadordeleteLaterfor cleanup
“QPixmap: Must construct a QGuiApplication before a QPaintDevice”
QPixmap,QImage, orQIconcreated beforeQApplicationexists- 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 useQPointerpattern
Event Loop Frozen / UI Unresponsive
- Blocking call on main thread (I/O,
time.sleep, heavy computation) - Fix: move to
QRunnable/QThread(seeqt-threadingskill)
# 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 emitSignal(str)equivalent - For C++: verify
Q_OBJECTis 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();