QML-Leiste und -Panel von Grund auf mit Quickshell entwickeln
Bewertung —Ein Leitfaden zum Erstellen einer leichten, animierten und modularen oberen Leiste (Panel) und eines Status-Widgets für Wayland mit Quickshell-Komponenten.
Inhalt
Zusammenfassung: Es wird Schritt für Schritt gezeigt, wie man mit Quickshell eine obere Leiste im Omarchy-Stil schreibt: die in Module aufgeteilte Verzeichnisstruktur unter
~/.config/quickshell/, dieshell.qml, die die Bildschirmebene festlegt, dieWorkspaces.qml, die Hyprland-Arbeitsbereiche als anklickbare Schaltflächen anzeigt, und weiche Übergänge mitBehavior on-Blöcken.
Wenn man in einer Wayland-Umgebung eine persönliche obere Leiste (Panel) entwickeln wollte, gab es traditionell zwei Möglichkeiten: GTK-basierte Panels, die auf statische Konfigurationsdateien beschränkt sind, oder extrem schwergewichtige JavaScript-Lösungen, die eine Browser-Engine ausführen. Quickshell verbindet die starke deklarative Struktur von QML direkt mit den Wayland-Protokollen und vereint so die besten Seiten beider Welten.
In diesem Artikel sehen wir uns Schritt für Schritt an, wie man mit Quickshell eine leichte, modulare obere Leiste im Omarchy-Stil mit flüssigen Animationen aufbaut.
1. Verzeichnisstruktur und Grundkonfiguration
Quickshell-Konfigurationen liegen standardmäßig im Verzeichnis ~/.config/quickshell/. Für eine saubere Architektur ist es der beste Ansatz, die Komponenten in Module aufzuteilen:
~/.config/quickshell/
├── shell.qml # Ana giriş noktası
├── components/
│ ├── Workspaces.qml # Çalışma alanları modülü
│ ├── WindowTitle.qml # Aktif pencere başlığı
│ └── SystemTray.qml # Sistem tepsisi ve göstergeler
└── theme/
└── Theme.qml # Global renk ve tipografi tanımları
2. Die Haupt-Shell: shell.qml
Die Datei shell.qml legt die Bildschirmebene und die Abmessungen des Hauptrahmens fest:
import QtQuick 2.15
import QtQuick.Layouts 1.15
import Quickshell 1.0
import Quickshell.Wayland 1.0
import "components"
import "theme"
Scope {
PanelWindow {
id: bar
anchors {
top: true
left: true
right: true
}
height: 36
WlrLayershell.layer: WlrLayer.Top
WlrLayershell.exclusiveZone: 36
color: Theme.background
RowLayout {
anchors.fill: parent
anchors.leftMargin: 12
anchors.rightMargin: 12
spacing: 8
// Sol: Çalışma Alanları
Workspaces {
Layout.alignment: Qt.AlignLeft
}
// Orta: Aktif Pencere
WindowTitle {
Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter
}
// Sağ: Sistem Durumu
SystemTray {
Layout.alignment: Qt.AlignRight
}
}
}
}
3. Arbeitsbereichsanzeige: Workspaces.qml
Hyprland-Arbeitsbereiche als dynamische Buttons aufzulisten und sie per Mausklick anklickbar zu machen, ist recht einfach:
import QtQuick 2.15
import QtQuick.Layouts 1.15
import Quickshell.Hyprland 1.0
import "../theme"
RowLayout {
spacing: 4
Repeater {
model: 5
Rectangle {
id: wsButton
property int wsId: index + 1
property bool isActive: Hyprland.activeWorkspace.id === wsId
width: 24
height: 24
radius: 4
color: isActive ? Theme.accent : Theme.surface
border.color: isActive ? Theme.accent : Theme.border
Text {
anchors.centerIn: parent
text: wsId
font.family: "JetBrains Mono"
font.pixelSize: 11
font.bold: isActive
color: isActive ? Theme.background : Theme.textMuted
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: Hyprland.dispatch("workspace " + wsId)
}
Behavior on color {
ColorAnimation { duration: 120 }
}
}
}
}
4. Flüssige Übergänge und Hover-Effekte
Der größte Vorteil von QML ist, dass es über CSS-Animationen hinaus hardwaregestützte und physikbasierte Interpolation bietet. Zum Beispiel wird das sanfte Aufleuchten eines Buttons beim Darüberfahren mit der Maus mit Behavior on ...-Blöcken in einer einzigen Zeile gelöst.
Da mit Quickshell entwickelte Komponenten nicht als eigenständige Fenster, sondern auf einer einzigen Oberfläche auf der GPU gezeichnet werden, kommt es zu keinem Frame-Dropping.
Meine Lesart
- Komponenten in Module aufzuteilen erleichtert die Wartung: jedes Teil liegt in seiner eigenen QML-Datei.
- Die Animation steckt in QML selbst: mit
Behavior onwerden Übergänge ohne zusätzliche Bibliothek geschrieben. - Das Zeichnen auf einer einzigen Oberfläche sorgt für Flüssigkeit: die Komponenten werden nicht in getrennten Fenstern, sondern auf derselben GPU-Oberfläche gezeichnet.