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.