guide: add multiple files and singletons sections to intro
This commit is contained in:
		
							parent
							
								
									dfa95a1ece
								
							
						
					
					
						commit
						581ec772ac
					
				
					 3 changed files with 297 additions and 5 deletions
				
			
		| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -679,12 +679,14 @@ QML Types can be easily made into a singleton, meaning there is only one instanc
 | 
				
			||||||
of the type.
 | 
					of the type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To make a type a singleton, put `pragma Singleton` at the top of the file.
 | 
					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
 | 
					```qml
 | 
				
			||||||
pragma Singleton
 | 
					pragma Singleton
 | 
				
			||||||
import ...
 | 
					import ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Item { ... }
 | 
					Singleton { ... }
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
once a type is a singleton, its members can be accessed by name from neighboring
 | 
					once a type is a singleton, its members can be accessed by name from neighboring
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -22,11 +22,11 @@
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "locked": {
 | 
					      "locked": {
 | 
				
			||||||
        "lastModified": 1710162131,
 | 
					        "lastModified": 1710400582,
 | 
				
			||||||
        "narHash": "sha256-iaLK3zoKZ84VWvykaupB4Vk0i5xJxFkCR8xqsxiob3g=",
 | 
					        "narHash": "sha256-Qr6Nt12Wi7t5X1wbij+FuXKJnHnH2E4KpGjc9XcqTaA=",
 | 
				
			||||||
        "ref": "refs/heads/master",
 | 
					        "ref": "refs/heads/master",
 | 
				
			||||||
        "rev": "d11868c32f9c82c7e6f404f77ffe1137e8c093e0",
 | 
					        "rev": "ffbdac9977588dd89ba6f077eb1f45890002663d",
 | 
				
			||||||
        "revCount": 109,
 | 
					        "revCount": 115,
 | 
				
			||||||
        "type": "git",
 | 
					        "type": "git",
 | 
				
			||||||
        "url": "https://git.outfoxxed.me/outfoxxed/quickshell"
 | 
					        "url": "https://git.outfoxxed.me/outfoxxed/quickshell"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue