aiohttp
免费Use when building Python async HTTP services or clients with aiohttp - web server routing, middleware, WebSocket, SSE, streaming, client sessions, pytest-aiohttp testing, or troubleshooting SSL and timeout issues
中文简介正在准备中。当前显示原文说明。
Use when building KDE Plasma 6 widgets with a Python backend - plasmoid structure, metadata.json, QML UI, configuration system, plasmapkg2 packaging, KDE Store submission, or plasmoid testing and debugging
中文简介正在准备中。当前显示原文说明。
查看安装方法安装前可以查看交给 AI 代理的指令内容。
Complete guide for developing Plasma widgets (Plasmoids) using Python backend with QML UI layer.
Important: Native Python Plasmoids (PyKDE4/PyKDE5) are deprecated in Plasma 6. Modern Plasmoids must use:
┌─────────────────────────────────────┐
│ QML UI Layer │
│ (PlasmoidItem + Kirigami) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Python Backend Logic │
│ (QObject-derived classes) │
└─────────────────────────────────────┘
| Component | Version |
|---|---|
| Plasma | 6.x |
| Qt | 6.x |
| Python | 3.8+ |
| PySide6/PyQt6 | 6.x |
# Arch/Manjaro
sudo pacman -S python-pyqt6 pyside6 kirigami plasma-framework plasma-sdk
# Fedora
sudo dnf install python3-pyqt6 python3-pyside6 kf6-kirigami-devel plasma-framework plasma-sdk
# Debian/Ubuntu
sudo apt install python3-pyqt6 python3-pyside6 kirigami-devel plasma-framework plasma-sdk
# openSUSE
sudo zypper install python3-qt6 python3-pyside6 kf6-kirigami-devel plasma-framework
pip install psutil requests pydbus
my-plasmoid/
├── package/
│ ├── contents/
│ │ ├── config/
│ │ │ ├── config.qml
│ │ │ └── main.xml
│ │ ├── ui/
│ │ │ ├── main.qml
│ │ │ └── configGeneral.qml
│ │ └── main.xml
│ └── metadata.json
├── src/
│ ├── __init__.py
│ └── backend.py
├── README.md
└── LICENSE
#!/usr/bin/env python3
"""Python backend for Plasma widget"""
from PySide6.QtCore import QObject, Signal, Slot, Property
# OR PyQt6:
# from PyQt6.QtCore import QObject, pyqtSignal as Signal, pyqtSlot as Slot, pyqtProperty as Property
class WidgetBackend(QObject):
"""Backend logic exposed to QML"""
# Signals
dataUpdated = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self._data = "Initial Value"
self._count = 0
# Properties (exposed to QML)
@Property(str, notify=dataUpdated)
def data(self):
return self._data
@data.setter
def data(self, value):
if self._data != value:
self._data = value
self.dataUpdated.emit()
@Property(int, notify=dataUpdated)
def count(self):
return self._count
# Slots (callable from QML)
@Slot(result=str)
def getData(self):
return self._data
@Slot(str)
def setData(self, value):
self.data = value
@Slot(str, result=str)
def processData(self, inputText):
"""Process input and return result"""
return f"Processed: {inputText}"
@Slot()
def refresh(self):
"""Refresh data"""
self._count += 1
self._data = f"Updated #{self._count}"
self.dataUpdated.emit()
@Slot(str, result=str)
def getSystemInfo(self, category):
"""Get system information"""
import psutil
if category == "cpu":
return f"{psutil.cpu_percent():.1f}%"
elif category == "memory":
mem = psutil.virtual_memory()
return f"{mem.percent:.1f}%"
elif category == "disk":
disk = psutil.disk_usage('/')
return f"{disk.percent:.1f}%"
return "Unknown"
| Feature | PySide6 | PyQt6 |
|---|---|---|
| Signal | Signal | pyqtSignal |
| Slot | Slot | pyqtSlot |
| Property | Property | pyqtProperty |
| License | LGPL | GPL |
| QML Registration | @QmlElement decorator | qmlRegisterType() |
PySide6 Registration:
from PySide6.QtQml import QmlElement
QML_IMPORT_NAME = "com.example.widget"
QML_IMPORT_MAJOR_VERSION = 1
@QmlElement
class WidgetBackend(QObject):
pass
PyQt6 Registration:
from PyQt6.QtQml import qmlRegisterType
qmlRegisterType(WidgetBackend, "com.example.widget", 1, 0, "WidgetBackend")
import QtQuick
import QtQuick.Layouts
import org.kde.plasma.plasmoid
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.kirigami 2.0 as Kirigami
import com.example.widget 1.0
PlasmoidItem {
id: root
// Backend instance
WidgetBackend {
id: backend
}
// Full representation (expanded widget)
Plasmoid.fullRepresentation: Kirigami.Card {
implicitWidth: Kirigami.Units.gridUnit * 20
implicitHeight: Kirigami.Units.gridUnit * 15
ColumnLayout {
anchors.fill: parent
anchors.margins: Kirigami.Units.smallSpacing
spacing: Kirigami.Units.smallSpacing
// Title
PlasmaComponents3.Label {
text: Plasmoid.configuration.customLabel || "My Widget"
font.bold: true
font.pointSize: Kirigami.Units.gridUnit * 1.2
Layout.fillWidth: true
}
// Data display
PlasmaComponents3.Label {
text: backend.data
Layout.fillWidth: true
wrapMode: Text.WordWrap
}
// System info
RowLayout {
Layout.fillWidth: true
PlasmaComponents3.Label {
text: "CPU: " + backend.getSystemInfo("cpu")
}
PlasmaComponents3.Label {
text: "RAM: " + backend.getSystemInfo("memory")
}
}
// Input field
PlasmaComponents3.TextField {
id: inputField
placeholderText: "Enter text..."
Layout.fillWidth: true
}
// Buttons
RowLayout {
Layout.fillWidth: true
PlasmaComponents3.Button {
text: "Process"
onClicked: backend.processData(inputField.text)
}
PlasmaComponents3.Button {
text: "Refresh"
icon.name: "view-refresh"
onClicked: backend.refresh()
}
}
}
}
// Compact representation (panel icon)
Plasmoid.compactRepresentation: PlasmaCore.IconItem {
source: Plasmoid.icon
anchors.centerIn: parent
implicitWidth: {
if (Plasmoid.location === PlasmaCore.Types.HorizontalPanel ||
Plasmoid.location === PlasmaCore.Types.VerticalPanel) {
return Kirigami.Units.iconSizes.medium
}
return Kirigami.Units.iconSizes.large
}
implicitHeight: implicitWidth
MouseArea {
anchors.fill: parent
onClicked: Plasmoid.expanded = !Plasmoid.expanded
}
}
// Tooltip
Plasmoid.toolTipMainText: "My Widget"
Plasmoid.toolTipSubText: backend.data
// Icon
Plasmoid.icon: "utilities-system-monitor"
}
// Correct Plasma 6 imports (no version numbers for most)
import QtQuick
import QtQuick.Layouts
import org.kde.plasma.plasmoid
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.kirigami 2.0 as Kirigami
# ✅ GOOD: Signal-based updates
class Backend(QObject):
dataChanged = Signal()
def updateData(self):
self._data = compute()
self.dataChanged.emit()
# ✅ GOOD: Lazy initialization
@Slot(result=str)
def expensiveData(self):
if not hasattr(self, '_cached'):
self._cached = self._computeExpensive()
return self._cached
# ❌ BAD: Blocking main thread
@Slot(result=str)
def slowOperation(self):
time.sleep(5) # Blocks UI
// ✅ GOOD: Use Kirigami units for scaling
width: Kirigami.Units.gridUnit * 10
spacing: Kirigami.Units.smallSpacing
// ✅ GOOD: Handle configuration defaults
text: plasmoid.configuration.label || i18n("Default")
// ❌ BAD: Hardcoded values
width: 320 // Won't scale on HiDPI
# Use Timer for periodic updates
from PySide6.QtCore import QTimer
class Backend(QObject):
def __init__(self):
self._timer = QTimer()
self._timer.timeout.connect(self.refresh)
self._timer.start(60000) # 60 seconds
Refer to these on-demand reference files for detailed topics:
references/configuration.md: metadata.json schema, KCFG main.xml, config.qml, configGeneral.qml, property aliases with cfg_ prefixreferences/packaging-publishing.md: plasmapkg2 CLI, .plasmoid package creation, local/system deployment, KDE Store submission workflowreferences/testing-debugging.md: plasmoidtest tool, exit codes, troubleshooting guide, unit/integration tests, debug logging还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Use when building Python async HTTP services or clients with aiohttp - web server routing, middleware, WebSocket, SSE, streaming, client sessions, pytest-aiohttp testing, or troubleshooting SSL and timeout issues
中文简介正在准备中。当前显示原文说明。
Use when doing structural code search and rewriting - ast-grep linting, refactoring, multi-language patterns
中文简介正在准备中。当前显示原文说明。
Use when building GBA games with the BPCore Lua engine - entity, sprite and tilemap functions, SRAM save and load, link cable multiplayer protocol, camera and scrolling, or optimization patterns
中文简介正在准备中。当前显示原文说明。
Use when running background tasks with Celery - worker and broker configuration (Redis, RabbitMQ), task routing by name vs queue, chains/groups/chords, retry patterns (autoretry_for, retry_backoff), acks_late semantics, failure detection, and monitoring with Flower
中文简介正在准备中。当前显示原文说明。
Use when building Django applications - security hardening, authentication and permissions, ORM optimization, PostgreSQL features, Django 6.0, migrations, testing, and ecosystem libraries
中文简介正在准备中。当前显示原文说明。
Use when customizing Django Admin - save_formset, get_search_results, formsets, queryset optimization, db_index, custom URLs
中文简介正在准备中。当前显示原文说明。