Merge pull request #7 from xstongxue/qt-skill

Qt skill
This commit is contained in:
Tu Shaokun
2026-02-03 14:09:35 +08:00
committed by GitHub
3 changed files with 193 additions and 0 deletions

View File

@@ -34,6 +34,7 @@ This is a Claude Code skill designed to help developers conduct effective code r
| **Go** | Error handling, goroutines/channels, context propagation, interface design, testing patterns |
| **C** | Pointer safety, UB pitfalls, resource management, error handling |
| **C++** | RAII, ownership, move semantics, exception safety, performance |
| **Qt** | Object model, Signals/Slots, memory management (parent/child), thread safety, GUI performance |
| **CSS/Less/Sass** | CSS variables, !important usage, performance optimization, responsive design, browser compatibility |
| **TanStack Query** | v5 best practices, queryOptions, useSuspenseQuery, optimistic updates |
| **Architecture** | SOLID principles, anti-patterns, coupling/cohesion, layered architecture |
@@ -53,6 +54,7 @@ This is a Claude Code skill designed to help developers conduct effective code r
| **reference/go.md** | ~990 | Go goroutines/channels/context/interfaces (on-demand) |
| **reference/c.md** | ~210 | C memory safety/UB/error handling (on-demand) |
| **reference/cpp.md** | ~300 | C++ RAII/lifetime/move semantics (on-demand) |
| **reference/qt.md** | ~190 | Qt object model/signals-slots/GUI performance (on-demand) |
| **reference/css-less-sass.md** | ~660 | CSS/Less/Sass variables/performance/responsive (on-demand) |
| **reference/architecture-review-guide.md** | ~470 | SOLID/anti-patterns/coupling analysis (on-demand) |
| **reference/performance-review-guide.md** | ~750 | Core Web Vitals/N+1/memory/complexity (on-demand) |
@@ -108,6 +110,7 @@ code-review-skill/
│ ├── go.md # Go patterns (on-demand)
│ ├── c.md # C patterns (on-demand)
│ ├── cpp.md # C++ patterns (on-demand)
│ ├── qt.md # Qt patterns (on-demand)
│ ├── css-less-sass.md # CSS/Less/Sass patterns (on-demand)
│ ├── architecture-review-guide.md # Architecture design review (on-demand)
│ ├── performance-review-guide.md # Performance review (on-demand)
@@ -227,6 +230,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
| **Go** | 错误处理、goroutine/channel、context 传播、接口设计、测试模式 |
| **C** | 指针/缓冲区安全、UB、资源管理、错误处理 |
| **C++** | RAII、生命周期、Rule of 0/3/5、异常安全 |
| **Qt** | 对象模型、信号/槽、内存管理父子关系、线程安全、GUI 性能 |
| **CSS/Less/Sass** | CSS 变量规范、!important 使用、性能优化、响应式设计、浏览器兼容性 |
| **TanStack Query** | v5 最佳实践、queryOptions、useSuspenseQuery、乐观更新 |
| **架构设计** | SOLID 原则、架构反模式、耦合度/内聚性、分层架构 |
@@ -246,6 +250,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
| **reference/go.md** | ~990 | Go goroutine/channel/context/接口(按需加载)|
| **reference/c.md** | ~210 | C 内存安全/UB/错误处理(按需加载)|
| **reference/cpp.md** | ~300 | C++ RAII/生命周期/移动语义(按需加载)|
| **reference/qt.md** | ~190 | Qt 对象模型/信号槽/GUI 性能(按需加载)|
| **reference/css-less-sass.md** | ~660 | CSS/Less/Sass 变量/性能/响应式(按需加载)|
| **reference/architecture-review-guide.md** | ~470 | SOLID/反模式/耦合度分析(按需加载)|
| **reference/performance-review-guide.md** | ~750 | Core Web Vitals/N+1/内存/复杂度(按需加载)|
@@ -301,6 +306,7 @@ code-review-skill/
│ ├── go.md # Go 模式(按需加载)
│ ├── c.md # C 模式(按需加载)
│ ├── cpp.md # C++ 模式(按需加载)
│ ├── qt.md # Qt 模式(按需加载)
│ ├── css-less-sass.md # CSS/Less/Sass 模式(按需加载)
│ ├── architecture-review-guide.md # 架构设计审查(按需加载)
│ ├── performance-review-guide.md # 性能审查(按需加载)

View File

@@ -185,6 +185,7 @@ Use labels to indicate priority:
| **C** | [C Guide](reference/c.md) | 指针/缓冲区, 内存安全, UB, 错误处理 |
| **C++** | [C++ Guide](reference/cpp.md) | RAII, 生命周期, Rule of 0/3/5, 异常安全 |
| **CSS/Less/Sass** | [CSS Guide](reference/css-less-sass.md) | 变量规范, !important, 性能优化, 响应式, 兼容性 |
| **Qt** | [Qt Guide](reference/qt.md) | 对象模型, 信号/槽, 内存管理, 线程安全, 性能 |
## Additional Resources

186
reference/qt.md Normal file
View File

@@ -0,0 +1,186 @@
# Qt Code Review Guide
> Code review guidelines focusing on object model, signals/slots, event loop, and GUI performance. Examples based on Qt 5.15 / Qt 6.
## Table of Contents
- [Object Model & Memory Management](#object-model--memory-management)
- [Signals & Slots](#signals--slots)
- [Containers & Strings](#containers--strings)
- [Threads & Concurrency](#threads--concurrency)
- [GUI & Widgets](#gui--widgets)
- [Meta-Object System](#meta-object-system)
- [Review Checklist](#review-checklist)
---
## Object Model & Memory Management
### Use Parent-Child Ownership Mechanism
Qt's `QObject` hierarchy automatically manages memory. For `QObject`, prefer setting a parent object over manual `delete` or smart pointers.
```cpp
// ❌ Manual management prone to memory leaks
QWidget* w = new QWidget();
QLabel* l = new QLabel();
l->setParent(w);
// ... If w is deleted, l is automatically deleted. But if w leaks, l also leaks.
// ✅ Specify parent in constructor
QWidget* w = new QWidget(this); // Owned by 'this'
QLabel* l = new QLabel(w); // Owned by 'w'
```
### Use Smart Pointers with QObject
If a `QObject` has no parent, use `QScopedPointer` or `std::unique_ptr` with a custom deleter (use `deleteLater` if cross-thread). Avoid `std::shared_ptr` for `QObject` unless necessary, as it confuses the parent-child ownership system.
```cpp
// ✅ Scoped pointer for local/member QObject without parent
QScopedPointer<MyObject> obj(new MyObject());
// ✅ Safe pointer to prevent dangling pointers
QPointer<MyObject> safePtr = obj.data();
if (safePtr) {
safePtr->doSomething();
}
```
### Use `deleteLater()`
For asynchronous deletion, especially in slots or event handlers, use `deleteLater()` instead of `delete` to ensure pending events in the event loop are processed.
---
## Signals & Slots
### Prefer Function Pointer Syntax
Use compile-time checked syntax (Qt 5+).
```cpp
// ❌ String-based (runtime check only, slower)
connect(sender, SIGNAL(valueChanged(int)), receiver, SLOT(updateValue(int)));
// ✅ Compile-time check
connect(sender, &Sender::valueChanged, receiver, &Receiver::updateValue);
```
### Connection Types
Be explicit or aware of connection types when crossing threads.
- `Qt::AutoConnection` (Default): Direct if same thread, Queued if different thread.
- `Qt::QueuedConnection`: Always posts event (thread-safe across threads).
- `Qt::DirectConnection`: Immediate call (dangerous if accessing non-thread-safe data across threads).
### Avoid Loops
Check logic that might cause infinite signal loops (e.g., `valueChanged` -> `setValue` -> `valueChanged`). Block signals or check for equality before setting values.
```cpp
void MyClass::setValue(int v) {
if (m_value == v) return; // ? Good: Break loop
m_value = v;
emit valueChanged(v);
}
```
---
## Containers & Strings
### QString Efficiency
- Use `QStringLiteral("...")` for compile-time string creation to avoid runtime allocation.
- Use `QLatin1String` for comparison with ASCII literals (in Qt 5).
- Prefer `arg()` for formatting (or `QStringBuilder`'s `%` operator).
```cpp
// ❌ Runtime conversion
if (str == "test") ...
// ✅ Prefer QLatin1String for comparison with ASCII literals (in Qt 5)
if (str == QLatin1String("test")) ... // Qt 5
if (str == u"test"_s) ... // Qt 6
```
### Container Selection
- **Qt 6**: `QList` is now the default choice (unified with `QVector`).
- **Qt 5**: Prefer `QVector` over `QList` for contiguous memory and cache performance, unless stable references are needed.
- Be aware of Implicit Sharing (Copy-on-Write). Passing containers by value is cheap *until* modified. Use `const &` for read-only access.
```cpp
// ❌ Forces deep copy if function modifies 'list'
void process(QVector<int> list) {
list[0] = 1;
}
// ✅ Read-only reference
void process(const QVector<int>& list) { ... }
```
---
## Threads & Concurrency
### Subclassing QThread vs Worker Object
Prefer the "Worker Object" pattern over subclassing `QThread` implementation details.
```cpp
// ❌ Business logic inside QThread::run()
class MyThread : public QThread {
void run() override { ... }
};
// ✅ Worker object moved to thread
QThread* thread = new QThread;
Worker* worker = new Worker;
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &Worker::process);
thread->start();
```
### GUI Thread Safety
**NEVER** access UI widgets (`QWidget` and subclasses) from a background thread. Use signals/slots to communicate updates to the main thread.
---
## GUI & Widgets
### Logic Separation
Keep business logic out of UI classes (`MainWindow`, `Dialog`). UI classes should only handle display and user input forwarding.
### Layouts
Avoid fixed sizes (`setGeometry`, `resize`). Use layouts (`QVBoxLayout`, `QGridLayout`) to handle different DPIs and window resizing gracefully.
### Blocking Event Loop
Never execute long-running operations on the main thread (freezes GUI).
- **Bad**: `Sleep()`, `while(busy)`, synchronous network calls.
- **Good**: `QProcess`, `QThread`, `QtConcurrent`, or asynchronous APIs (`QNetworkAccessManager`).
---
## Meta-Object System
### Properties & Enums
Use `Q_PROPERTY` for values exposed to QML or needing introspection.
Use `Q_ENUM` to enable string conversion for enums.
```cpp
class MyObject : public QObject {
Q_OBJECT
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
public:
enum State { Idle, Running };
Q_ENUM(State)
// ...
};
```
### qobject_cast
Use `qobject_cast<T*>` for QObjects instead of `dynamic_cast`. It is faster and doesn't require RTTI.
---
## Review Checklist
- [ ] **Memory**: Is parent-child relationship correct? Are dangling pointers avoided (using `QPointer`)?
- [ ] **Signals**: Are connections checked? Do lambdas use safe captures (context object)?
- [ ] **Threads**: Is UI accessed only from main thread? Are long tasks offloaded?
- [ ] **Strings**: Are `QStringLiteral` or `tr()` used appropriately?
- [ ] **Style**: Naming conventions (camelCase for methods, PascalCase for classes).
- [ ] **Resources**: Are resources (images, styles) loaded from `.qrc`?