guide: add multiple files and singletons sections to intro

This commit is contained in:
outfoxxed 2024-03-14 02:45:47 -07:00
parent dfa95a1ece
commit 581ec772ac
Signed by: outfoxxed
GPG Key ID: 4C88A185FB89301E
3 changed files with 297 additions and 5 deletions

View File

@ -514,3 +514,293 @@ ShellRoot {
}
}
```
## Multiple files
In an example as small as this it isn't a problem, but as your project
gets bigger you may become annoyed having everything all
in one file. Luckily its easy to break a component out to a new file.
Lets move the entire bar into a new file to make space for other widgets:
```qml {filename="shell.qml"}
import Quickshell
ShellRoot {
Bar {}
}
```
```qml {filename="Bar.qml"}
import Quickshell
import Quickshell.Io
import QtQuick
Scope {
property string time;
Variants {
variants: Quickshell.screens.map(screen => ({ screen }))
PanelWindow {
anchors {
top: true
left: true
right: true
}
height: 30
Text {
anchors.centerIn: parent
// now just time instead of root.time
text: time
}
}
}
Process {
id: dateProc
command: ["date"]
running: true
stdout: SplitParser {
// now just time instead of root.time
onRead: data => time = data
}
}
Timer {
interval: 1000
running: true
repeat: true
onTriggered: dateProc.running = true
}
}
```
<span class="small">See also: [Scope](/docs/types/quickshell/scope/)</span>
Any qml file that starts with an uppercase letter can be referenced this way.
We can bring in other folders as well using
[import statements](/docs/configuration/qml-overview/#explicit-imports).
Now what about breaking out the clock? This is a bit more complex because
the clock component in the bar and the process and timer that make up the actual
clock both need to be dealt with.
To start with let's move the clock to a new file. For now it's just a
single `Text` object but the same concepts apply regardless of complexity
(and you probably want a more complicated clock than this.)
```qml {filename="ClockWidget.qml"}
import QtQuick
// Item is a common base type for visual components
Item {
// make a property the creator of this type is required to set
required property string time
// size the item to its children
width: childrenRect.width
height: childrenRect.height
// use the default property to contain the clock
Text {
text: time
}
}
```
```qml {filename="Bar.qml"}
import Quickshell
import Quickshell.Io
import QtQuick
Scope {
id: root
property string time;
Variants {
variants: Quickshell.screens.map(screen => ({ screen }))
PanelWindow {
anchors {
top: true
left: true
right: true
}
height: 30
// the ClockWidget type we just created
ClockWidget {
anchors.centerIn: parent
// Warning: setting `time: time` will bind time to itself which is not what we want
time: root.time
}
}
}
Process {
id: dateProc
command: ["date"]
running: true
stdout: SplitParser {
onRead: data => time = data
}
}
Timer {
interval: 1000
running: true
repeat: true
onTriggered: dateProc.running = true
}
}
```
While this example is larger than what we had before, we can now expand
on the clock widget without cluttering the bar file.
Let's deal with the clock's update logic now:
```qml {filename="Time.qml"}
import Quickshell
import Quickshell.Io
import QtQuick
Scope {
property string time;
Process {
id: dateProc
command: ["date"]
running: true
stdout: SplitParser {
onRead: data => time = data
}
}
Timer {
interval: 1000
running: true
repeat: true
onTriggered: dateProc.running = true
}
}
```
```qml {filename="Bar.qml"}
import Quickshell
Scope {
// the Time type we just created
Time { id: timeSource }
Variants {
variants: Quickshell.screens.map(screen => ({ screen }))
PanelWindow {
anchors {
top: true
left: true
right: true
}
height: 30
ClockWidget {
anchors.centerIn: parent
// now using the time from timeSource
time: timeSource.time
}
}
}
}
```
## Singletons
Now you might be thinking, why do we need the `Time` type in
our bar file, and the answer is we don't. We can make `Time`
a [singleton](/docs/configuration/qml-overview/#singletons).
A singleton object has only one instance, and is accessible from
any scope.
```qml {filename="Time.qml"}
// with this line our type becomes a singleton
pragma Singleton
import Quickshell
import Quickshell.Io
import QtQuick
// your singletons should always have Singleton as the type
Singleton {
property string time;
Process {
id: dateProc
command: ["date"]
running: true
stdout: SplitParser {
onRead: data => time = data
}
}
Timer {
interval: 1000
running: true
repeat: true
onTriggered: dateProc.running = true
}
}
```
```qml {filename="ClockWidget.qml"}
import QtQuick
Item {
// we no longer need time as an input
width: childrenRect.width
height: childrenRect.height
Text {
// directly access the time property from the Time singleton
text: Time.time
}
}
```
```qml {filename="Bar.qml"}
import Quickshell
Scope {
// no more time object
Variants {
variants: Quickshell.screens.map(screen => ({ screen }))
PanelWindow {
anchors {
top: true
left: true
right: true
}
height: 30
ClockWidget {
anchors.centerIn: parent
// no more time binding
}
}
}
}
```

View File

@ -679,12 +679,14 @@ QML Types can be easily made into a singleton, meaning there is only one instanc
of the type.
To make a type a singleton, put `pragma Singleton` at the top of the file.
To ensure it behaves correctly with quickshell you should also make
[Singleton](/docs/types/quickshell/singleton) the root item of your type.
```qml
pragma Singleton
import ...
Item { ... }
Singleton { ... }
```
once a type is a singleton, its members can be accessed by name from neighboring

View File

@ -22,11 +22,11 @@
]
},
"locked": {
"lastModified": 1710162131,
"narHash": "sha256-iaLK3zoKZ84VWvykaupB4Vk0i5xJxFkCR8xqsxiob3g=",
"lastModified": 1710400582,
"narHash": "sha256-Qr6Nt12Wi7t5X1wbij+FuXKJnHnH2E4KpGjc9XcqTaA=",
"ref": "refs/heads/master",
"rev": "d11868c32f9c82c7e6f404f77ffe1137e8c093e0",
"revCount": 109,
"rev": "ffbdac9977588dd89ba6f077eb1f45890002663d",
"revCount": 115,
"type": "git",
"url": "https://git.outfoxxed.me/outfoxxed/quickshell"
},