qt

Community

Qt conventions for clean C++/QML code

AuthordotBeeps
Version1.0.0
Installs0

System Documentation

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.

Dependency Matrix

Required Modules

None required

Components

Standard package

💻 Claude Code Installation

Recommended: Let Claude install automatically. Simply copy and paste the text below to Claude Code.

Please help me install this Skill:
Name: qt
Download link: https://github.com/dotBeeps/pantry/archive/main.zip#qt

Please download this .zip file, extract it, and install it in the .claude/skills/ directory.
View Source Repository

Agent Skills Search Helper

Install a tiny helper to your Agent, search and equip skill from 471,000+ vetted skills library on demand.