qt

Enforce Qt/C++/QML conventions for memory ownership and signal-slot usage.

Updated Mar 31, 2026
One-click install
npx skills add https://github.com/dotBeeps/pantry --skill qt
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: qt
Source: https://github.com/dotBeeps/pantry/tree/main/morsels/skills/qt
Command: npx skills add https://github.com/dotBeeps/pantry --skill qt

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Establishes consistent Qt/C++/QML development practices to improve code reliability and maintainability beyond what basic linters enforce.

Core Features & Use Cases

  • Qt object tree memory management: pass parent to constructors, don't manually delete parented objects
  • Avoid raw new for non-QObject types—prefer std::unique_ptr / std::make_unique
  • Use QScopedPointer or std::unique_ptr for QObjects only when they have no parent
  • Connect signals to slots with the pointer-to-member syntax: connect(sender, &Sender::signal, receiver, &Receiver::slot) — never use string-based SIGNAL()/SLOT() macros
  • Mark all Q_PROPERTY declarations FINAL unless subclass override is intentional
  • Use QStringLiteral for compile-time string literals, QLatin1StringView for ASCII comparisons
  • Prefer qsizetype over int for container sizes and indices
  • Use Q_EMIT / Q_SIGNAL / Q_SLOT keywords over emit / signals / slots to avoid macro conflicts

QML

  • Declarative bindings over imperative assignments — avoid Component.onCompleted property sets when a binding works
  • Keep JavaScript in QML minimal — complex logic belongs in C++ exposed via Q_INVOKABLE or properties
  • One QML component per file, filename matches component name (PascalCase)
  • Group property declarations: id, custom properties, standard properties, signal handlers, child objects
  • Use required property for component APIs — don't rely on context properties
  • Prefer Loader for conditionally instantiated heavy components
  • Use qmllint and qmlformat — configure them in the project's .qmllint.ini

Signals & Slots

  • Prefer &Class::method connections over lambdas unless you need captures
  • Always consider object lifetime — use QPointer or ensure receiver outlives the connection
  • Use Qt::QueuedConnection explicitly only when crossing thread boundaries
  • Disconnect signals in destructors only if the receiver outlives the sender

Structure

  • Separate QML from C++ backend: qml/ for UI, src/ for logic
  • Use QML modules (qt_add_qml_module) — don't register types manually with qmlRegisterType
  • CMake is the only supported build system — no qmake for new projects
  • Use qt_standard_project_setup() in CMakeLists.txt

Testing

  • Use QTest framework with QVERIFY, QCOMPARE, QTEST_MAIN
  • Test QML with QQuickTest and TestCase components
  • Use QSignalSpy to verify signal emissions
  • Mock external dependencies, but never mock Qt internals

Threading

  • Never touch GUI objects from worker threads
  • Use QThread::create() or subclass QObject and moveToThread() — don't subclass QThread
  • Prefer QtConcurrent::run for simple parallel tasks
  • Use signals/slots for cross-thread communication — Qt handles marshalling

Error Handling

  • Check return values from QFile::open, QProcess::start, etc. — they return bool, not exceptions
  • Use qWarning(), qCritical(), qDebug() with category logging (Q_LOGGING_CATEGORY)
  • Never use C++ exceptions across Qt API boundaries

Quick Start

Follow these Qt conventions at project start to ensure memory-safe ownership, robust signal-slot usage, and clean QML structure.

Frequently Asked Questions about qt

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I manage Qt object memory and avoid leaks in C++?▼

Qt object tree memory management requires passing a parent to constructors and avoiding manual deletion of parented objects. For non-QObjects, avoid raw new and prefer std::unique_ptr. Use QScopedPointer or std::unique_ptr for QObjects only when they have no parent.

What is the best way to connect Qt signals and slots safely?▼

The best way to connect Qt signals and slots is using the pointer-to-member syntax: connect(sender, &Sender::signal, receiver, &Receiver::slot). Never use string-based SIGNAL()/SLOT() macros. Always consider object lifetime using QPointer, and prefer member functions over lambdas unless captures are needed.

How do I organize QML components and keep UI logic maintainable?▼

Organize QML components by keeping one component per file with matching PascalCase filenames. Keep JavaScript minimal and move complex logic to C++ via Q_INVOKABLE. Use required property for component APIs instead of context properties, and prefer declarative bindings over imperative Component.onCompleted assignments.

Does Qt work with CMake or should I use qmake for new projects?▼

CMake is the only supported build system for new Qt projects; qmake should not be used. Configure projects using qt_standard_project_setup() in CMakeLists.txt. Use QML modules via qt_add_qml_module rather than manually registering types with qmlRegisterType.

How do I handle threading in Qt without crashing the GUI?▼

Qt threading requires never touching GUI objects from worker threads. Use QThread::create() or subclass QObject and moveToThread() instead of subclassing QThread. For simple parallel tasks, prefer QtConcurrent::run, and use signals and slots for cross-thread communication so Qt handles marshalling.

Why should I use QStringLiteral and qsizetype in Qt C++ code?▼

QStringLiteral optimizes string creation at compile-time and QLatin1StringView improves ASCII comparisons. Using qsizetype over int for container sizes and indices prevents truncation on 64-bit platforms. Additionally, using Q_EMIT, Q_SIGNAL, and Q_SLOT keywords avoids macro conflicts.