| name | pyside6-reviewer |
| description | Code review and PR review skill for Python PySide6/Qt 6.8+ applications. Focuses on modern best practices, performance, thread safety, signal/slot patterns, Model/View architecture, QML integration, and async patterns. Use when reviewing Python Qt code, PySide6 PRs, GUI application code, or when asked to review code that uses QtWidgets, QtQuick, QtCore, QtGui, or any Qt module. Catches common anti-patterns, memory issues, thread violations, and suggests modern Qt 6.8+ idioms.
|
PySide6 Code Reviewer
Expert code review for modern PySide6/Qt 6.8+ applications.
Review Process
- Identify Qt version assumptions — Verify code targets Qt 6.8+ (no Qt5 compat)
- Check thread safety — All GUI operations on main thread, proper worker patterns
- Validate signal/slot usage — Modern connection syntax, proper signatures
- Assess Model/View implementation — Role usage, data method patterns, index validity
- Review resource management — Parent-child ownership, prevent leaks
- Evaluate async patterns — QThread, QtConcurrent, asyncio integration
- Check QML integration — Property bindings, type registration, context exposure
Critical Anti-Patterns (Always Flag)
class Worker(QThread):
def run(self):
self.label.setText("Done")
def on_button_click(self):
time.sleep(5)
requests.get(url)
self.connect(button, SIGNAL("clicked()"), self.handler)
button.clicked.connect("self.handler")
label = QLabel("text")
obj.deleteLater()
del obj
class BadWorker(QThread):
def run(self):
self.progress_bar.setValue(50)
Modern Patterns (Require These)
Signal/Slot Connections
button.clicked.connect(self.on_click)
button.clicked.connect(lambda: self.handler(arg))
class Worker(QObject):
progress = Signal(int)
result = Signal(str, list)
error = Signal(Exception)
finished = Signal()
Thread-Safe Worker Pattern
class Worker(QObject):
finished = Signal()
progress = Signal(int)
result = Signal(object)
error = Signal(str)
@Slot()
def run(self):
try:
for i in range(100):
self.progress.emit(i)
self.result.emit(data)
except Exception as e:
self.error.emit(str(e))
finally:
self.finished.emit()
thread = QThread()
worker = Worker()
worker.moveToThread(thread)
thread.started.connect(worker.run)
worker.finished.connect(thread.quit)
worker.finished.connect(worker.deleteLater)
thread.finished.connect(thread.deleteLater)
thread.start()
Async Integration (Qt 6.8+)
import asyncio
from PySide6.QtAsyncio import QAsyncioEventLoopPolicy
asyncio.set_event_loop_policy(QAsyncioEventLoopPolicy())
class AsyncWidget(QWidget):
async def fetch_data(self):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json()
def start_fetch(self):
asyncio.ensure_future(self.fetch_data())
Detailed Reference Files
- references/signals-slots.md — Signal/slot patterns, connection types, thread-safe emission
- references/model-view.md — QAbstractItemModel, roles, proxies, delegates
- references/threading.md — QThread, QtConcurrent, async patterns, thread pools
- references/widgets.md — Widget lifecycle, layouts, styling, high-DPI
- references/qml-integration.md — QML/Python bridge, properties, type registration
- references/performance.md — Paint optimization, model efficiency, lazy loading
- references/anti-patterns.md — Comprehensive anti-pattern catalog with fixes
Review Checklist (Use for PRs)
Thread Safety
Memory Management
Signal/Slot Correctness
Model/View
Performance
Qt 6.8+ Specifics