added markdown parser for @@ types used in typegen
This commit is contained in:
		
							parent
							
								
									77e2d05d6f
								
							
						
					
					
						commit
						00feaca3d5
					
				
					 5 changed files with 226 additions and 206 deletions
				
			
		| 
						 | 
				
			
			@ -104,12 +104,12 @@ export function getQMLTypeLinkObject(unparsed: string) {
 | 
			
		|||
        : linkSplit[0];
 | 
			
		||||
      const linkObj: QMLTypeLinkObject = {
 | 
			
		||||
        type: "qt",
 | 
			
		||||
        module: linkModule,
 | 
			
		||||
        module: linkModule.replace("_", "-"),
 | 
			
		||||
        name: linkSplit[1].slice(1),
 | 
			
		||||
      };
 | 
			
		||||
      if (linkSplit.length > 2) {
 | 
			
		||||
        linkObj.mname = linkSplit[3];
 | 
			
		||||
        linkObj.mtype = linkSplit[4];
 | 
			
		||||
        linkObj.mname = linkSplit[2].slice(1);
 | 
			
		||||
        linkObj.mtype = linkSplit[3].slice(1);
 | 
			
		||||
      }
 | 
			
		||||
      return linkObj;
 | 
			
		||||
    },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,12 @@
 | 
			
		|||
import type { Parent, Node } from "unist";
 | 
			
		||||
import { visit, CONTINUE, SKIP } from "unist-util-visit";
 | 
			
		||||
import { fromHtml } from "hast-util-from-html";
 | 
			
		||||
import type { Root } from "hast";
 | 
			
		||||
import type * as Unist from "unist";
 | 
			
		||||
import type * as Html from "hast";
 | 
			
		||||
import type * as Md from "mdast";
 | 
			
		||||
import type {
 | 
			
		||||
  AstroMarkdownOptions,
 | 
			
		||||
  MarkdownProcessor,
 | 
			
		||||
  RemarkPlugin,
 | 
			
		||||
  RehypePlugin,
 | 
			
		||||
} from "@astrojs/markdown-remark";
 | 
			
		||||
import { createMarkdownProcessor } from "@astrojs/markdown-remark";
 | 
			
		||||
| 
						 | 
				
			
			@ -18,19 +20,52 @@ import {
 | 
			
		|||
  getIconForLink,
 | 
			
		||||
} from "./helpers.ts";
 | 
			
		||||
 | 
			
		||||
// couldn't find the actual type to use
 | 
			
		||||
interface HtmlNode extends Node {
 | 
			
		||||
  value: string;
 | 
			
		||||
  type: string;
 | 
			
		||||
  tagName: string;
 | 
			
		||||
}
 | 
			
		||||
const remarkParseAtTypes: RemarkPlugin<[]> = () => {
 | 
			
		||||
  return (root: Md.Root): Md.Root => {
 | 
			
		||||
    visit(
 | 
			
		||||
      root as Unist.Parent,
 | 
			
		||||
      (rawNode: Unist.Node) => {
 | 
			
		||||
        if (rawNode.type === "text" || (rawNode.type === "code" && (rawNode as Md.Code).lang === "qml")) {
 | 
			
		||||
          const node = rawNode as Md.Literal;
 | 
			
		||||
 | 
			
		||||
          node.value = node.value.replace(
 | 
			
		||||
            /@@((?<module>([A-Z]\w*\.)*)(?<type>([A-Z]\w*))\.?)?((?<member>[a-z]\w*)((?<function>\(\))|(?<signal>\(s\)))?)?(?=[$.,;:\s]|$)/g,
 | 
			
		||||
            (_full, ...args) => {
 | 
			
		||||
              type Capture = {
 | 
			
		||||
                module: string | undefined;
 | 
			
		||||
                type: string | undefined;
 | 
			
		||||
                member: string | undefined;
 | 
			
		||||
                function: string | undefined;
 | 
			
		||||
                signal: string | undefined;
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              const groups = args.pop() as Capture;
 | 
			
		||||
 | 
			
		||||
              if (groups.module) {
 | 
			
		||||
                groups.module = groups.module.substring(0, groups.module.length - 1);
 | 
			
		||||
                const isQs = groups.module.startsWith("Quickshell");
 | 
			
		||||
                groups.module = `99M${isQs ? "QS" : "QT_qml"}_${groups.module.replace(".", "_")}`;
 | 
			
		||||
              } else groups.module = ""; // WARNING: rehype parser can't currently handle intra-module links
 | 
			
		||||
 | 
			
		||||
              groups.type = groups.type ? `99N${groups.type}` : "";
 | 
			
		||||
              groups.member = groups.member ? `99V${groups.member}` : "";
 | 
			
		||||
              const type = groups.member ? `99T${groups.function ? "func" : groups.signal ? "signal" : "prop"}` : "";
 | 
			
		||||
              return `TYPE${groups.module}${groups.type}${groups.member}${type}99TYPE`;
 | 
			
		||||
            }
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
    return root;
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const rehypeRewriteTypelinks: RehypePlugin<[]> = () => {
 | 
			
		||||
  return (root: Node): Root => {
 | 
			
		||||
  return (root: Html.Root): Html.Root => {
 | 
			
		||||
    visit(
 | 
			
		||||
      root,
 | 
			
		||||
      root as Unist.Parent,
 | 
			
		||||
      "text",
 | 
			
		||||
      (node: HtmlNode, index: number, parent: Parent) => {
 | 
			
		||||
      (node: Html.Text, index: number, parent: Html.Parent) => {
 | 
			
		||||
        let changed = false;
 | 
			
		||||
 | 
			
		||||
        node.value = node.value.replace(
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +100,7 @@ const rehypeRewriteTypelinks: RehypePlugin<[]> = () => {
 | 
			
		|||
      }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return root as Root;
 | 
			
		||||
    return root;
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +128,7 @@ export const markdownConfig: AstroMarkdownOptions = {
 | 
			
		|||
    wrap: true,
 | 
			
		||||
    transformers: [shikiRewriteTypelinks],
 | 
			
		||||
  },
 | 
			
		||||
  remarkPlugins: [[remarkAlert, { legacyTitle: true }]],
 | 
			
		||||
  remarkPlugins: [remarkParseAtTypes, [remarkAlert, { legacyTitle: true }]],
 | 
			
		||||
  rehypePlugins: [
 | 
			
		||||
    // FIXME: incompatible types between unified/Plugin and Astro/RehypePlugin
 | 
			
		||||
    [sectionize as RehypePlugin, { idPropertyName: "id" }],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ Each shell file starts with the shell root object. Only one may exist per config
 | 
			
		|||
```qml {filename="~/.config/quickshell/shell.qml"}
 | 
			
		||||
import Quickshell
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_ShellRoot {
 | 
			
		||||
@@Quickshell.ShellRoot {
 | 
			
		||||
  // ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -82,8 +82,8 @@ We'll start with an example:
 | 
			
		|||
import Quickshell // for ShellRoot and PanelWindow
 | 
			
		||||
import QtQuick // for Text
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_ShellRoot {
 | 
			
		||||
  QS_Quickshell_PanelWindow {
 | 
			
		||||
@@Quickshell.ShellRoot {
 | 
			
		||||
  @@Quickshell.PanelWindow {
 | 
			
		||||
    anchors {
 | 
			
		||||
      top: true
 | 
			
		||||
      left: true
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +92,7 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
 | 
			
		||||
    height: 30
 | 
			
		||||
 | 
			
		||||
    QT__Text {
 | 
			
		||||
    @@QtQuick.Text {
 | 
			
		||||
      // center the bar in its parent component (the window)
 | 
			
		||||
      anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -115,9 +115,8 @@ To start with lets make a clock. To get the time we'll use the `date` command.
 | 
			
		|||
We can use a [Process](/docs/types/quickshell.io/process) object to run commands
 | 
			
		||||
and return their results.
 | 
			
		||||
 | 
			
		||||
We'll listen to the [DataStreamParser.read](/docs/types/quickshell.io/datastreamparser/#signal.read)
 | 
			
		||||
[signal](/docs/configuration/qml-overview/#signals) emitted by
 | 
			
		||||
[SplitParser](/docs/types/quickshell.io/splitparser/) using a
 | 
			
		||||
We'll listen to the @@Quickshell.Io.DataStreamParser.read(s) emitted by
 | 
			
		||||
@@Quickshell.Io.SplitParser using a
 | 
			
		||||
[signal handler](/docs/configuration/qml-overview/#signal-handlers)
 | 
			
		||||
to update the text on the clock.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,8 +129,8 @@ import Quickshell
 | 
			
		|||
import Quickshell.Io // for Process
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_ShellRoot {
 | 
			
		||||
  QS_Quickshell_PanelWindow {
 | 
			
		||||
@@Quickshell.ShellRoot {
 | 
			
		||||
  @@Quickshell.PanelWindow {
 | 
			
		||||
    anchors {
 | 
			
		||||
      top: true
 | 
			
		||||
      left: true
 | 
			
		||||
| 
						 | 
				
			
			@ -140,14 +139,14 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
 | 
			
		||||
    height: 30
 | 
			
		||||
 | 
			
		||||
    QT__Text {
 | 
			
		||||
    @@QtQuick.Text {
 | 
			
		||||
      // give the text an ID we can refer to elsewhere in the file
 | 
			
		||||
      id: clock
 | 
			
		||||
 | 
			
		||||
      anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
      // create a process management object
 | 
			
		||||
      QS_Quickshell00Io_Process {
 | 
			
		||||
      @@Quickshell.Io.Process {
 | 
			
		||||
        // the command it will run, every argument is its own string
 | 
			
		||||
        command: ["date"]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +155,7 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
 | 
			
		||||
        // process the stdout stream using a SplitParser
 | 
			
		||||
        // which returns chunks of output after a delimiter
 | 
			
		||||
        stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
        stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
          // listen for the read signal, which returns the data that was read
 | 
			
		||||
          // from stdout, then write that data to the clock's text property
 | 
			
		||||
          onRead: data => clock.text = data
 | 
			
		||||
| 
						 | 
				
			
			@ -170,15 +169,15 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
## <MD_Title titleVar={2}> Running code at an interval </MD_Title>
 | 
			
		||||
 | 
			
		||||
With the above example, your bar should now display the time, but it isn't updating!
 | 
			
		||||
Let's use a [Timer](https://doc.qt.io/qt-6/qml-qtqml-timer.html) fix that.
 | 
			
		||||
Let's use a @@QtQml.Timer to fix that.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_ShellRoot {
 | 
			
		||||
  QS_Quickshell_PanelWindow {
 | 
			
		||||
@@Quickshell.ShellRoot {
 | 
			
		||||
  @@Quickshell.PanelWindow {
 | 
			
		||||
    anchors {
 | 
			
		||||
      top: true
 | 
			
		||||
      left: true
 | 
			
		||||
| 
						 | 
				
			
			@ -187,11 +186,11 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
 | 
			
		||||
    height: 30
 | 
			
		||||
 | 
			
		||||
    QT__Text {
 | 
			
		||||
    @@QtQuick.Text {
 | 
			
		||||
      id: clock
 | 
			
		||||
      anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
      QS_Quickshell00Io_Process {
 | 
			
		||||
      @@Quickshell.Io.Process {
 | 
			
		||||
        // give the process object an id so we can talk
 | 
			
		||||
        // about it from the timer
 | 
			
		||||
        id: dateProc
 | 
			
		||||
| 
						 | 
				
			
			@ -199,13 +198,13 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
        command: ["date"]
 | 
			
		||||
        running: true
 | 
			
		||||
 | 
			
		||||
        stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
        stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
          onRead: data => clock.text = data
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // use a timer to rerun the process at an interval
 | 
			
		||||
      QT_qtqml_Timer {
 | 
			
		||||
      @@QtQml.Timer {
 | 
			
		||||
        // 1000 milliseconds is 1 second
 | 
			
		||||
        interval: 1000
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -230,34 +229,31 @@ If you have multiple monitors you might have noticed that your bar
 | 
			
		|||
is only on one of them. If not, you'll still want to **follow this section
 | 
			
		||||
to make sure your bar doesn't disappear if your monitor disconnects**.
 | 
			
		||||
 | 
			
		||||
We can use a [Variants](/docs/types/quickshell/variants)
 | 
			
		||||
object to create instances of _non widget items_.
 | 
			
		||||
(See [Repeater](https://doc.qt.io/qt-6/qml-qtquick-repeater.html) for doing
 | 
			
		||||
We can use a @@Quickshell.Variants object to create instances of _non widget items_.
 | 
			
		||||
(See @@QtQuick.Repeater for doing
 | 
			
		||||
something similar with visual items.)
 | 
			
		||||
 | 
			
		||||
The `Variants` type creates instances of a
 | 
			
		||||
[Component](https://doc.qt.io/qt-6/qml-qtqml-component.html) based on a data model
 | 
			
		||||
you supply. (A component is a re-usable tree of objects.)
 | 
			
		||||
The @@Quickshell.Variants type creates instances of a @@QtQml.Component based on
 | 
			
		||||
a data model you supply. (A component is a re-usable tree of objects.)
 | 
			
		||||
 | 
			
		||||
The most common use of `Variants` in a shell is to create instances of
 | 
			
		||||
The most common use of @@Quickshell.Variants in a shell is to create instances of
 | 
			
		||||
a window (your bar) based on your monitor list (the data model).
 | 
			
		||||
 | 
			
		||||
Variants will inject the values in the data model into each new
 | 
			
		||||
@@Quickshell.Variants will inject the values in the data model into each new
 | 
			
		||||
component's `modelData` property, which means we can easily pass each screen
 | 
			
		||||
to its own component.
 | 
			
		||||
(See [Window.screen](/docs/types/quickshell/qswindow/#prop.screen).)
 | 
			
		||||
to its own component. (See @@Quickshell.QsWindow.screen.)
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_ShellRoot {
 | 
			
		||||
  QS_Quickshell_Variants {
 | 
			
		||||
@@Quickshell.ShellRoot {
 | 
			
		||||
  @@Quickshell.Variants {
 | 
			
		||||
    model: Quickshell.screens;
 | 
			
		||||
 | 
			
		||||
    delegate: QT_qtqml_Component {
 | 
			
		||||
      QS_Quickshell_PanelWindow {
 | 
			
		||||
    delegate: @@QtQml.Component {
 | 
			
		||||
      @@Quickshell.PanelWindow {
 | 
			
		||||
        // the screen from the screens list will be injected into this
 | 
			
		||||
        // property
 | 
			
		||||
        property var modelData
 | 
			
		||||
| 
						 | 
				
			
			@ -273,21 +269,21 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
 | 
			
		||||
        height: 30
 | 
			
		||||
 | 
			
		||||
        QT__Text {
 | 
			
		||||
        @@QtQuick.Text {
 | 
			
		||||
          id: clock
 | 
			
		||||
          anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
          QS_Quickshell00Io_Process {
 | 
			
		||||
          @@Quickshell.Io.Process {
 | 
			
		||||
            id: dateProc
 | 
			
		||||
            command: ["date"]
 | 
			
		||||
            running: true
 | 
			
		||||
 | 
			
		||||
            stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
            stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
              onRead: data => clock.text = data
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          QT_qtqml_Timer {
 | 
			
		||||
          @@QtQml.Timer {
 | 
			
		||||
            interval: 1000
 | 
			
		||||
            running: true
 | 
			
		||||
            repeat: true
 | 
			
		||||
| 
						 | 
				
			
			@ -301,16 +297,13 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
```
 | 
			
		||||
 | 
			
		||||
<span class="small">
 | 
			
		||||
  See also: [Property
 | 
			
		||||
  Bindings](/docs/configuration/qml-overview/#property-bindings),
 | 
			
		||||
  [Variants.component](/docs/types/quickshell/variants/#prop.component),
 | 
			
		||||
  [Quickshell.screens](/docs/types/quickshell/quickshell/#prop.screens),
 | 
			
		||||
  See also: [Property Bindings](/docs/configuration/qml-overview/#property-bindings),
 | 
			
		||||
  [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
With this example, bars will be created and destroyed as you plug and unplug them,
 | 
			
		||||
due to the reactive nature of the
 | 
			
		||||
[Quickshell.screens](/docs/types/quickshell/quickshell/#prop.screens) property.
 | 
			
		||||
@@Quickshell.Quickshell.screens property.
 | 
			
		||||
(See: [Reactive Bindings](/docs/configuration/qml-overview/#reactive-bindings).)
 | 
			
		||||
 | 
			
		||||
Now there's an important problem you might have noticed: when the window
 | 
			
		||||
| 
						 | 
				
			
			@ -325,12 +318,12 @@ import Quickshell
 | 
			
		|||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_ShellRoot {
 | 
			
		||||
  QS_Quickshell_Variants {
 | 
			
		||||
@@Quickshell.ShellRoot {
 | 
			
		||||
  @@Quickshell.Variants {
 | 
			
		||||
    model: Quickshell.screens
 | 
			
		||||
 | 
			
		||||
    delegate: QT_qtqml_Component {
 | 
			
		||||
      QS_Quickshell_PanelWindow {
 | 
			
		||||
    delegate: @@QtQml.Component {
 | 
			
		||||
      @@Quickshell.PanelWindow {
 | 
			
		||||
        property var modelData
 | 
			
		||||
        screen: modelData
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -342,7 +335,7 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
 | 
			
		||||
        height: 30
 | 
			
		||||
 | 
			
		||||
        QT__Text {
 | 
			
		||||
        @@QtQuick.Text {
 | 
			
		||||
          id: clock
 | 
			
		||||
          anchors.centerIn: parent
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -350,17 +343,17 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell00Io_Process {
 | 
			
		||||
  @@Quickshell.Io.Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
    stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
      onRead: data => clock.text = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtqml_Timer {
 | 
			
		||||
  @@QtQml.Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
| 
						 | 
				
			
			@ -400,17 +393,17 @@ import Quickshell
 | 
			
		|||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_ShellRoot {
 | 
			
		||||
@@Quickshell.ShellRoot {
 | 
			
		||||
  id: root
 | 
			
		||||
 | 
			
		||||
  // add a property in the root
 | 
			
		||||
  property string time;
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell_Variants {
 | 
			
		||||
  @@Quickshell.Variants {
 | 
			
		||||
    model: Quickshell.screens
 | 
			
		||||
 | 
			
		||||
    delegate: QT_qtqml_Component {
 | 
			
		||||
      QS_Quickshell_PanelWindow {
 | 
			
		||||
    delegate: @@QtQml.Component {
 | 
			
		||||
      @@Quickshell.PanelWindow {
 | 
			
		||||
        property var modelData
 | 
			
		||||
        screen: modelData
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -422,7 +415,7 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
 | 
			
		||||
        height: 30
 | 
			
		||||
 | 
			
		||||
        QT__Text {
 | 
			
		||||
        @@QtQuick.Text {
 | 
			
		||||
          // remove the id as we don't need it anymore
 | 
			
		||||
 | 
			
		||||
          anchors.centerIn: parent
 | 
			
		||||
| 
						 | 
				
			
			@ -434,18 +427,18 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell00Io_Process {
 | 
			
		||||
  @@Quickshell.Io.Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
    stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
      // update the property instead of the clock directly
 | 
			
		||||
      onRead: data => root.time = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtqml_Timer {
 | 
			
		||||
  @@QtQml.Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
| 
						 | 
				
			
			@ -460,12 +453,11 @@ above code, but we can make it more concise:
 | 
			
		|||
1. `Component`s can be defined implicitly, meaning we can remove the
 | 
			
		||||
   component wrapping the window and place the window directly into the
 | 
			
		||||
   `delegate` property.
 | 
			
		||||
2. The [Variants.delegate](/docs/types/quickshell/variants/#prop.delegate)
 | 
			
		||||
   property is a [Default Property](/docs/configuration/qml-overview/#the-default-property),
 | 
			
		||||
2. The @@Quickshell.Variants.delegate property is a
 | 
			
		||||
   [Default Property](/docs/configuration/qml-overview/#the-default-property),
 | 
			
		||||
   which means we can skip the `delegate:` part of the assignment.
 | 
			
		||||
   We're already using [ShellRoot](/docs/types/quickshell/shellroot/)'s
 | 
			
		||||
   default property to store our Variants, Process, and Timer components
 | 
			
		||||
   among other things.
 | 
			
		||||
   We're already using the default property of @@Quickshell.ShellRoot to store our
 | 
			
		||||
   Variants, Process, and Timer components among other things.
 | 
			
		||||
3. The ShellRoot doesn't actually need an `id` property to talk about
 | 
			
		||||
   the time property, as it is the outermost object in the file which
 | 
			
		||||
   has [special scoping rules](/docs/configuration/qml-overview/#property-access-scopes).
 | 
			
		||||
| 
						 | 
				
			
			@ -477,13 +469,13 @@ import Quickshell
 | 
			
		|||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_ShellRoot {
 | 
			
		||||
@@Quickshell.ShellRoot {
 | 
			
		||||
  property string time;
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell_Variants {
 | 
			
		||||
  @@Quickshell.Variants {
 | 
			
		||||
    model: Quickshell.screens
 | 
			
		||||
 | 
			
		||||
    QS_Quickshell_PanelWindow {
 | 
			
		||||
    @@Quickshell.PanelWindow {
 | 
			
		||||
      property var modelData
 | 
			
		||||
      screen: modelData
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -495,7 +487,7 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
 | 
			
		||||
      height: 30
 | 
			
		||||
 | 
			
		||||
      QT__Text {
 | 
			
		||||
      @@QtQuick.Text {
 | 
			
		||||
        anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
        // now just time instead of root.time
 | 
			
		||||
| 
						 | 
				
			
			@ -504,18 +496,18 @@ QS_Quickshell_ShellRoot {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell00Io_Process {
 | 
			
		||||
  @@Quickshell.Io.Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
    stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
      // now just time instead of root.time
 | 
			
		||||
      onRead: data => time = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtqml_Timer {
 | 
			
		||||
  @@QtQml.Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
| 
						 | 
				
			
			@ -534,7 +526,7 @@ To start with, let's move the entire bar into a new file.
 | 
			
		|||
```qml {filename="shell.qml"}
 | 
			
		||||
import Quickshell
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_ShellRoot {
 | 
			
		||||
@@Quickshell.ShellRoot {
 | 
			
		||||
  Bar {}
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -544,13 +536,13 @@ import Quickshell
 | 
			
		|||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_Scope {
 | 
			
		||||
@@Quickshell.Scope {
 | 
			
		||||
  property string time;
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell_Variants {
 | 
			
		||||
  @@Quickshell.Variants {
 | 
			
		||||
    model: Quickshell.screens
 | 
			
		||||
 | 
			
		||||
    QS_Quickshell_PanelWindow {
 | 
			
		||||
    @@Quickshell.PanelWindow {
 | 
			
		||||
      property var modelData
 | 
			
		||||
      screen: modelData
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -562,7 +554,7 @@ QS_Quickshell_Scope {
 | 
			
		|||
 | 
			
		||||
      height: 30
 | 
			
		||||
 | 
			
		||||
      QT__Text {
 | 
			
		||||
      @@QtQuick.Text {
 | 
			
		||||
        anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
        // now just time instead of root.time
 | 
			
		||||
| 
						 | 
				
			
			@ -571,18 +563,18 @@ QS_Quickshell_Scope {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell00Io_Process {
 | 
			
		||||
  @@Quickshell.Io.Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
    stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
      // now just time instead of root.time
 | 
			
		||||
      onRead: data => time = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtqml_Timer {
 | 
			
		||||
  @@QtQml.Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
| 
						 | 
				
			
			@ -602,12 +594,12 @@ the clock component in the bar, as well as the process and timer that
 | 
			
		|||
make up the actual clock, need to be dealt with.
 | 
			
		||||
 | 
			
		||||
To start with, we can move the clock widget to a new file. For now it's just a
 | 
			
		||||
single `Text` object but the same concepts apply regardless of complexity.
 | 
			
		||||
single @@QtQuick.Text object but the same concepts apply regardless of complexity.
 | 
			
		||||
 | 
			
		||||
```qml {filename="ClockWidget.qml"}
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QT__Text {
 | 
			
		||||
@@QtQuick.Text {
 | 
			
		||||
  // A property the creator of this type is required to set.
 | 
			
		||||
  // Note that we could just set `text` instead, but don't because your
 | 
			
		||||
  // clock probably will not be this simple.
 | 
			
		||||
| 
						 | 
				
			
			@ -622,14 +614,14 @@ import Quickshell
 | 
			
		|||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_Scope {
 | 
			
		||||
@@Quickshell.Scope {
 | 
			
		||||
  id: root
 | 
			
		||||
  property string time;
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell_Variants {
 | 
			
		||||
  @@Quickshell.Variants {
 | 
			
		||||
    model: Quickshell.screens
 | 
			
		||||
 | 
			
		||||
    QS_Quickshell_PanelWindow {
 | 
			
		||||
    @@Quickshell.PanelWindow {
 | 
			
		||||
      property var modelData
 | 
			
		||||
      screen: modelData
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -650,17 +642,17 @@ QS_Quickshell_Scope {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell00Io_Process {
 | 
			
		||||
  @@Quickshell.Io.Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
    stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
      onRead: data => time = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtqml_Timer {
 | 
			
		||||
  @@QtQml.Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
| 
						 | 
				
			
			@ -679,20 +671,20 @@ import Quickshell
 | 
			
		|||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_Scope {
 | 
			
		||||
@@Quickshell.Scope {
 | 
			
		||||
  property string time;
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell00Io_Process {
 | 
			
		||||
  @@Quickshell.Io.Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
    stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
      onRead: data => time = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtqml_Timer {
 | 
			
		||||
  @@QtQml.Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
| 
						 | 
				
			
			@ -704,14 +696,14 @@ QS_Quickshell_Scope {
 | 
			
		|||
```qml {filename="Bar.qml"}
 | 
			
		||||
import Quickshell
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_Scope {
 | 
			
		||||
@@Quickshell.Scope {
 | 
			
		||||
  // the Time type we just created
 | 
			
		||||
  Time { id: timeSource }
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell_Variants {
 | 
			
		||||
  @@Quickshell.Variants {
 | 
			
		||||
    model: Quickshell.screens
 | 
			
		||||
 | 
			
		||||
    QS_Quickshell_PanelWindow {
 | 
			
		||||
    @@Quickshell.PanelWindow {
 | 
			
		||||
      property var modelData
 | 
			
		||||
      screen: modelData
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -751,20 +743,20 @@ import Quickshell.Io
 | 
			
		|||
import QtQuick
 | 
			
		||||
 | 
			
		||||
// your singletons should always have Singleton as the type
 | 
			
		||||
QS_Quickshell_Singleton {
 | 
			
		||||
@@Quickshell.Singleton {
 | 
			
		||||
  property string time
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell00Io_Process {
 | 
			
		||||
  @@Quickshell.Io.Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: QS_Quickshell00Io_SplitParser {
 | 
			
		||||
    stdout: @@Quickshell.Io.SplitParser {
 | 
			
		||||
      onRead: data => time = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtqml_Timer {
 | 
			
		||||
  @@QtQml.Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
| 
						 | 
				
			
			@ -776,7 +768,7 @@ QS_Quickshell_Singleton {
 | 
			
		|||
```qml {filename="ClockWidget.qml"}
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QT__Text {
 | 
			
		||||
@@QtQuick.Text {
 | 
			
		||||
  // we no longer need time as an input
 | 
			
		||||
 | 
			
		||||
  // directly access the time property from the Time singleton
 | 
			
		||||
| 
						 | 
				
			
			@ -787,13 +779,13 @@ QT__Text {
 | 
			
		|||
```qml {filename="Bar.qml"}
 | 
			
		||||
import Quickshell
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_Scope {
 | 
			
		||||
@@Quickshell.Scope {
 | 
			
		||||
  // no more time object
 | 
			
		||||
 | 
			
		||||
  QS_Quickshell_Variants {
 | 
			
		||||
  @@Quickshell.Variants {
 | 
			
		||||
    model: Quickshell.screens
 | 
			
		||||
 | 
			
		||||
    QS_Quickshell_PanelWindow {
 | 
			
		||||
    @@Quickshell.PanelWindow {
 | 
			
		||||
      property var modelData
 | 
			
		||||
      screen: modelData
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -830,11 +822,11 @@ import Quickshell
 | 
			
		|||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_Singleton {
 | 
			
		||||
@@Quickshell.Singleton {
 | 
			
		||||
  property var date: new Date()
 | 
			
		||||
  property string time: date.toLocaleString(Qt.locale())
 | 
			
		||||
 | 
			
		||||
  QT_qtqml_Timer {
 | 
			
		||||
  @@QtQml.Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,19 +32,19 @@ page has good documentation of the basic layout types and how to use them.
 | 
			
		|||
## <MD_Title titleVar={2}> Manual Positioning </MD_Title>
 | 
			
		||||
 | 
			
		||||
If layouts and anchors can't easily fulfill your usecase, you can also manually position and size
 | 
			
		||||
components by setting their `x`, `y`, `width` and `height` properties, which are relative to
 | 
			
		||||
the parent component.
 | 
			
		||||
components by setting their @@QtQuick.Item.x, @@QtQuick.Item.y, @@QtQuick.Item.width and @@QtQuick.Item.height
 | 
			
		||||
properties, which are relative to the parent component.
 | 
			
		||||
 | 
			
		||||
This example puts a 100x100px blue rectangle at x=20,y=40 in the parent item. Ensure the size
 | 
			
		||||
of the parent is large enough for its content or positioning based on them will break.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  // make sure the component is large enough to fit its children
 | 
			
		||||
  implicitWidth: childrenRect.width
 | 
			
		||||
  implicitHeight: childrenRect.height
 | 
			
		||||
 | 
			
		||||
  QT__Rectangle {
 | 
			
		||||
  @@QtQuick.Rectangle {
 | 
			
		||||
    color: "blue"
 | 
			
		||||
    x: 20
 | 
			
		||||
    y: 40
 | 
			
		||||
| 
						 | 
				
			
			@ -58,27 +58,22 @@ QT__Item {
 | 
			
		|||
 | 
			
		||||
### <MD_Title titleVar={3}> Component Size </MD_Title>
 | 
			
		||||
 | 
			
		||||
The [Item.implicitHeight] and [Item.implicitWidth] properties control the _base size_ of a
 | 
			
		||||
component, before layouts are applied. These properties are _not_ the same as
 | 
			
		||||
[Item.height] and [Item.width] which are the final size of the component.
 | 
			
		||||
The @@QtQuick.Item.implicitHeight and @@QtQuick.Item.implicitWidth properties control the
 | 
			
		||||
_base size_ of a component, before layouts are applied. These properties are _not_ the same as
 | 
			
		||||
@@QtQuick.Item.height and @@QtQuick.Item.width which are the final size of the component.
 | 
			
		||||
You should nearly always use the implicit size properties when creating a component,
 | 
			
		||||
however using the normal width and height properties is fine if you know an
 | 
			
		||||
item will never go in a layout.
 | 
			
		||||
 | 
			
		||||
[Item.height]: https://doc.qt.io/qt-6/qml-qtquick-item.html#height-prop
 | 
			
		||||
[Item.width]: https://doc.qt.io/qt-6/qml-qtquick-item.html#width-prop
 | 
			
		||||
[Item.implicitHeight]: https://doc.qt.io/qt-6/qml-qtquick-item.html#implicitHeight-prop
 | 
			
		||||
[Item.implicitWidth]: https://doc.qt.io/qt-6/qml-qtquick-item.html#implicitWidth-prop
 | 
			
		||||
 | 
			
		||||
This example component puts a colored rectangle behind some text, and will act the same
 | 
			
		||||
way in a layout as the text by itself.
 | 
			
		||||
 | 
			
		||||
```qml {filename="TextWithBkgColor.qml"}
 | 
			
		||||
QT__Rectangle {
 | 
			
		||||
@@QtQuick.Rectangle {
 | 
			
		||||
  implicitWidth: text.implicitWidth
 | 
			
		||||
  implicitHeight: text.implicitHeight
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: text
 | 
			
		||||
    text: "hello!"
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -88,18 +83,18 @@ QT__Rectangle {
 | 
			
		|||
If you want to size your component based on multiple others or use any other math you can.
 | 
			
		||||
 | 
			
		||||
```qml {filename="PaddedTexts.qml"}
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  // width of both texts plus 5
 | 
			
		||||
  implicitWidth: text1.implicitWidth + text2.implicitWidth + 5
 | 
			
		||||
  // max height of both texts plus 5
 | 
			
		||||
  implicitHeight: Math.min(text1.implicitHeight, text2.implicitHeight) + 5
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: text1
 | 
			
		||||
    text: "text1"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: text2
 | 
			
		||||
    anchors.left: text1.left
 | 
			
		||||
    text: "text2"
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +105,7 @@ QT__Item {
 | 
			
		|||
### <MD_Title titleVar={3}> Coordinate space </MD_Title>
 | 
			
		||||
 | 
			
		||||
You should always position or size components relative to the closest possible
 | 
			
		||||
parent. Often this is just the `parent` property.
 | 
			
		||||
parent. Often this is just the @@QtQuick.Item.parent property.
 | 
			
		||||
 | 
			
		||||
Refrain from using things like the size of your screen to size a component,
 | 
			
		||||
as this will break as soon as anything up the component hierarchy changes, such
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ import QtQuick 6.0
 | 
			
		|||
import "myjs.js" as MyJs
 | 
			
		||||
 | 
			
		||||
// Root Object
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  // Id assignment
 | 
			
		||||
 | 
			
		||||
  id: root
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ Expressions are snippets of javascript code assigned to a property. The last (or
 | 
			
		|||
can be the return value, or an explicit return statement (multiline expressions only) can be used.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  // simple expression
 | 
			
		||||
  property: 5
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -252,7 +252,7 @@ Properties can be defined inside of objects with the following syntax:
 | 
			
		|||
- `binding` is the property binding. See [Property bindings](#property-bindings) for details.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  // normal property
 | 
			
		||||
  property int foo: 3
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -274,12 +274,12 @@ Types can have a _default property_ which must accept either an object or a list
 | 
			
		|||
The default property will allow you to assign a value to it without using the name of the property:
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  // normal property
 | 
			
		||||
  foo: 3
 | 
			
		||||
 | 
			
		||||
  // this item is assigned to the outer object's default property
 | 
			
		||||
  QT__Item {
 | 
			
		||||
  @@QtQuick.Item {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -288,16 +288,16 @@ If the default property is a list, you can put multiple objects into it the same
 | 
			
		|||
would put a single object in:
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  // normal property
 | 
			
		||||
  foo: 3
 | 
			
		||||
 | 
			
		||||
  // this item is assigned to the outer object's default property
 | 
			
		||||
  QT__Item {
 | 
			
		||||
  @@QtQuick.Item {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // this one is too
 | 
			
		||||
  QT__Item {
 | 
			
		||||
  @@QtQuick.Item {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -308,13 +308,13 @@ Every object has a special property called `id` that can be assigned to give
 | 
			
		|||
the object a name it can be referred to throughout the current file. The id must be lowercase.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT_qtquick11layouts_ColumnLayout {
 | 
			
		||||
  QT__Text {
 | 
			
		||||
@@QtQuick.Layouts.ColumnLayout {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: text
 | 
			
		||||
    text: "Hello World!"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtquick11controls_Button {
 | 
			
		||||
  @@QtQuick.Controls.Button {
 | 
			
		||||
    text: "Make the text red";
 | 
			
		||||
    onClicked: text.color = "red";
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -344,14 +344,14 @@ The `parent` property is also defined for all objects, but may not always point
 | 
			
		|||
looks like it should. Use the `id` property if `parent` does not do what you want.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  property string rootDefinition
 | 
			
		||||
 | 
			
		||||
  QT__Item {
 | 
			
		||||
  @@QtQuick.Item {
 | 
			
		||||
    id: mid
 | 
			
		||||
    property string midDefinition
 | 
			
		||||
 | 
			
		||||
    QT__Text {
 | 
			
		||||
    @@QtQuick.Text {
 | 
			
		||||
      property string innerDefinition
 | 
			
		||||
 | 
			
		||||
      // legal - innerDefinition is defined on the current object
 | 
			
		||||
| 
						 | 
				
			
			@ -402,19 +402,19 @@ functions, meaning if one of the properties a function depends on is re-evaluate
 | 
			
		|||
every expression depending on the function is also re-evaluated.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT_qtquick11layouts_ColumnLayout {
 | 
			
		||||
@@QtQuick.Layouts.ColumnLayout {
 | 
			
		||||
  property int clicks: 0
 | 
			
		||||
 | 
			
		||||
  function makeClicksLabel(): string {
 | 
			
		||||
    return "the button has been clicked " + clicks + " times!";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtquick11controls_Button {
 | 
			
		||||
  @@QtQuick.Controls.Button {
 | 
			
		||||
    text: "click me"
 | 
			
		||||
    onClicked: clicks += 1
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    text: makeClicksLabel()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -450,7 +450,7 @@ Lambda syntax:
 | 
			
		|||
Assigning functions to properties:
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  // using functions
 | 
			
		||||
  function dub(number: int): int { return number * 2; }
 | 
			
		||||
  property var operation: dub
 | 
			
		||||
| 
						 | 
				
			
			@ -463,7 +463,7 @@ QT__Item {
 | 
			
		|||
An overcomplicated click counter using a lambda callback:
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT_qtquick11layouts_ColumnLayout {
 | 
			
		||||
@@QtQuick.Layouts.ColumnLayout {
 | 
			
		||||
  property int clicks: 0
 | 
			
		||||
 | 
			
		||||
  function incrementAndCall(callback) {
 | 
			
		||||
| 
						 | 
				
			
			@ -471,14 +471,14 @@ QT_qtquick11layouts_ColumnLayout {
 | 
			
		|||
    callback(clicks);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtquick11controls_Button {
 | 
			
		||||
  @@QtQuick.Controls.Button {
 | 
			
		||||
    text: "click me"
 | 
			
		||||
    onClicked: incrementAndCall(clicks => {
 | 
			
		||||
        label.text = `the button was clicked ${clicks} time(s)!`;
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: label
 | 
			
		||||
    text: "the button has not been clicked"
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -510,7 +510,7 @@ Signals all have a `connect(<function>)` method which invokes the given function
 | 
			
		|||
or signal when the signal is emitted.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT_qtquick11layouts_ColumnLayout {
 | 
			
		||||
@@QtQuick.Layouts.ColumnLayout {
 | 
			
		||||
  property int clicks: 0
 | 
			
		||||
 | 
			
		||||
  function updateText() {
 | 
			
		||||
| 
						 | 
				
			
			@ -518,12 +518,12 @@ QT_qtquick11layouts_ColumnLayout {
 | 
			
		|||
    label.text = `the button has been clicked ${clicks} times!`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtquick11controls_Button {
 | 
			
		||||
  @@QtQuick.Controls.Button {
 | 
			
		||||
    id: button
 | 
			
		||||
    text: "click me"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: label
 | 
			
		||||
    text: "the button has not been clicked"
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -540,9 +540,9 @@ QT_qtquick11layouts_ColumnLayout {
 | 
			
		|||
  immediately once the object is fully initialized.
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
When the button is clicked, the button emits the `clicked` signal which we connected to
 | 
			
		||||
`updateText`. The signal then invokes `updateText` which updates the counter and the
 | 
			
		||||
text on the label.
 | 
			
		||||
When the button is clicked, the button emits the @@QtQuick.Controls.Button.clicked(s)
 | 
			
		||||
signal which we connected to `updateText`. The signal then invokes `updateText`
 | 
			
		||||
which updates the counter and the text on the label.
 | 
			
		||||
 | 
			
		||||
##### <MD_Title titleVar={5}> Signal handlers </MD_Title>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -553,10 +553,10 @@ property implicitly defined which can be set to a function. (Note that the first
 | 
			
		|||
signal's name it capitalized.)
 | 
			
		||||
 | 
			
		||||
Below is the same example as in [Making Connections](#making-connections),
 | 
			
		||||
this time using the implicit signal handler property to handle `button.clicked`.
 | 
			
		||||
this time using the implicit signal handler property to handle @@QtQuick.Controls.Button.clicked(s).
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT_qtquick11layouts_ColumnLayout {
 | 
			
		||||
@@QtQuick.Layouts.ColumnLayout {
 | 
			
		||||
  property int clicks: 0
 | 
			
		||||
 | 
			
		||||
  function updateText() {
 | 
			
		||||
| 
						 | 
				
			
			@ -564,12 +564,12 @@ QT_qtquick11layouts_ColumnLayout {
 | 
			
		|||
    label.text = `the button has been clicked ${clicks} times!`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtquick11controls_Button {
 | 
			
		||||
  @@QtQuick.Controls.Button {
 | 
			
		||||
    text: "click me"
 | 
			
		||||
    onClicked: updateText()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: label
 | 
			
		||||
    text: "the button has not been clicked"
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -579,18 +579,18 @@ QT_qtquick11layouts_ColumnLayout {
 | 
			
		|||
##### <MD_Title titleVar={5}> Indirect signal handlers </MD_Title>
 | 
			
		||||
 | 
			
		||||
When it is not possible or not convenient to directly define a signal handler, before resorting
 | 
			
		||||
to `.connect`ing the properties, a [Connections] object can be used to access them.
 | 
			
		||||
to `.connect`ing the properties, a @@QtQml.Connections object can be used to access them.
 | 
			
		||||
 | 
			
		||||
This is especially useful to connect to signals of singletons.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
  QT_qtquick11controls_Button {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  @@QtQuick.Controls.Button {
 | 
			
		||||
    id: myButton
 | 
			
		||||
    text "click me"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtqml_Connections {
 | 
			
		||||
  @@QtQml.Connections {
 | 
			
		||||
    target: myButton
 | 
			
		||||
 | 
			
		||||
    function onClicked() {
 | 
			
		||||
| 
						 | 
				
			
			@ -609,8 +609,8 @@ Whenever the property is re-evaluated, its change signal is emitted. This is use
 | 
			
		|||
to update dependent properties, but can be directly used, usually with a signal handler.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT_qtquick11layouts_ColumnLayout {
 | 
			
		||||
  CheckBox {
 | 
			
		||||
@@QtQuick.Layouts.ColumnLayout {
 | 
			
		||||
  @@QtQuick.Controls.CheckBox {
 | 
			
		||||
    text: "check me"
 | 
			
		||||
 | 
			
		||||
    onCheckStateChanged: {
 | 
			
		||||
| 
						 | 
				
			
			@ -618,7 +618,7 @@ QT_qtquick11layouts_ColumnLayout {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: label
 | 
			
		||||
    text: labelText(false)
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -629,19 +629,19 @@ QT_qtquick11layouts_ColumnLayout {
 | 
			
		|||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In this example we listen for the `checkState` property of the CheckBox changing
 | 
			
		||||
In this example we listen for changes to the @@QtQuick.Controls.CheckBox.checkState property of the CheckBox
 | 
			
		||||
using its change signal, `checkStateChanged` with the signal handler `onCheckStateChanged`.
 | 
			
		||||
 | 
			
		||||
Since text is also a property we can do the same thing more concisely:
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT_qtquick11layouts_ColumnLayout {
 | 
			
		||||
  CheckBox {
 | 
			
		||||
@@QtQuick.Layouts.ColumnLayout {
 | 
			
		||||
  @@QtQuick.Controls.CheckBox {
 | 
			
		||||
    id: checkbox
 | 
			
		||||
    text: "check me"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: label
 | 
			
		||||
    text: labelText(checkbox.checkState == Qt.Checked)
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -655,13 +655,13 @@ QT_qtquick11layouts_ColumnLayout {
 | 
			
		|||
And the function can also be inlined to an expression:
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT_qtquick11layouts_ColumnLayout {
 | 
			
		||||
  CheckBox {
 | 
			
		||||
@@QtQuick.Layouts.ColumnLayout {
 | 
			
		||||
  @@QtQuick.Controls.CheckBox {
 | 
			
		||||
    id: checkbox
 | 
			
		||||
    text: "check me"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: label
 | 
			
		||||
    text: {
 | 
			
		||||
      const checked = checkbox.checkState == Qt.Checked;
 | 
			
		||||
| 
						 | 
				
			
			@ -682,11 +682,11 @@ tell you if it can be used as an attached object and how.
 | 
			
		|||
Attached objects are accessed in the form `<Typename>.<member>` and can have
 | 
			
		||||
properties, functions and signals.
 | 
			
		||||
 | 
			
		||||
A good example is the [Component](https://doc.qt.io/qt-6/qml-qtqml-component.html) type,
 | 
			
		||||
A good example is the @@QtQml.Component type,
 | 
			
		||||
which is attached to every object and often used to run code when an object initializes.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Text {
 | 
			
		||||
@@QtQuick.Text {
 | 
			
		||||
  Component.onCompleted: {
 | 
			
		||||
    text = "hello!"
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -706,14 +706,14 @@ are not visible outside the file.
 | 
			
		|||
 | 
			
		||||
```qml
 | 
			
		||||
// MyText.qml
 | 
			
		||||
QT__Rectangle {
 | 
			
		||||
@@QtQuick.Rectangle {
 | 
			
		||||
  required property string text
 | 
			
		||||
 | 
			
		||||
  color: "red"
 | 
			
		||||
  implicitWidth: textObj.implicitWidth
 | 
			
		||||
  implicitHeight: textObj.implicitHeight
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: textObj
 | 
			
		||||
    anchors.fill: parent
 | 
			
		||||
    text: parent.text
 | 
			
		||||
| 
						 | 
				
			
			@ -721,7 +721,7 @@ QT__Rectangle {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// AnotherComponent.qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  MyText {
 | 
			
		||||
    // The `text` property of `MyText` is required, so we must set it.
 | 
			
		||||
    text: "Hello World!"
 | 
			
		||||
| 
						 | 
				
			
			@ -748,13 +748,13 @@ 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.
 | 
			
		||||
@@Quickshell.Singleton the root item of your type.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
pragma Singleton
 | 
			
		||||
import ...
 | 
			
		||||
 | 
			
		||||
QS_Quickshell_Singleton {
 | 
			
		||||
@@Quickshell.Singleton {
 | 
			
		||||
  ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -785,18 +785,18 @@ A reactive binding occurs automatically when you use one or more properties in t
 | 
			
		|||
of another property. .
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  property int clicks: 0
 | 
			
		||||
 | 
			
		||||
  QT_qtquick11controls_Button {
 | 
			
		||||
  @@QtQuick.Controls.Button {
 | 
			
		||||
    text: `clicks: ${clicks}`
 | 
			
		||||
    onClicked: clicks += 1
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In this example, the button's `text` property is re-evaluated every time the button is clicked, because
 | 
			
		||||
the `clicks` property has changed.
 | 
			
		||||
In this example, the button's @@QtQuick.Controls.Button.text property is re-evaluated
 | 
			
		||||
every time the button is clicked, because the `clicks` property has changed.
 | 
			
		||||
 | 
			
		||||
###### <MD_Title titleVar={6}> Avoiding creation </MD_Title>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -806,10 +806,10 @@ You can use the `Component.onCompleted` signal to set a value using a property w
 | 
			
		|||
as assignments to properties do not create binding.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  property string theProperty: "initial value"
 | 
			
		||||
 | 
			
		||||
  QT__Text {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    // text: "Right now, theProperty is: " + theProperty
 | 
			
		||||
    Component.onCompleted: text = "At creation time, theProperty is: " + theProperty
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -826,13 +826,13 @@ The `Qt.binding` function takes another function as an argument, and when assign
 | 
			
		|||
the property will use that function as its binding expression.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
  QT__Text {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: boundText
 | 
			
		||||
    text: "not bound to anything"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtquick11controls_Button {
 | 
			
		||||
  @@QtQuick.Controls.Button {
 | 
			
		||||
    text: "bind the above text"
 | 
			
		||||
    onClicked: {
 | 
			
		||||
      if (boundText.text == "not bound to anything") {
 | 
			
		||||
| 
						 | 
				
			
			@ -853,13 +853,13 @@ be updated.
 | 
			
		|||
To remove a binding, just assign a new value to the property without using `Qt.binding`.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
QT__Item {
 | 
			
		||||
  QT__Text {
 | 
			
		||||
@@QtQuick.Item {
 | 
			
		||||
  @@QtQuick.Text {
 | 
			
		||||
    id: boundText
 | 
			
		||||
    text: `button is pressed: ${theButton.pressed}`
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QT_qtquick11controls_Button {
 | 
			
		||||
  @@QtQuick.Controls.Button {
 | 
			
		||||
    id: theButton
 | 
			
		||||
    text: "break the binding"
 | 
			
		||||
    onClicked: boundText.text = `button was pressed at the time the binding was broken: ${pressed}`
 | 
			
		||||
| 
						 | 
				
			
			@ -876,13 +876,11 @@ it will not be updated further by the binding.
 | 
			
		|||
Often not all of your interface needs to load immediately. By default the QML
 | 
			
		||||
engine initializes every object in the scene before showing anything onscreen.
 | 
			
		||||
For parts of the interface you don't need to be immediately visible, load them
 | 
			
		||||
asynchronously using a [LazyLoader](/docs/types/quickshell/lazyloader).
 | 
			
		||||
asynchronously using a @@Quickshell.LazyLoader.
 | 
			
		||||
See its documentation for more information.
 | 
			
		||||
 | 
			
		||||
#### <MD_Title titleVar={4}> Components </MD_Title>
 | 
			
		||||
 | 
			
		||||
Another delayed loading mechanism is the [Component](https://doc.qt.io/qt-6/qml-qtqml-component.html) type.
 | 
			
		||||
Another delayed loading mechanism is the @@QtQml.Component type.
 | 
			
		||||
This type can be used to create multiple instances of objects or lazily load them. It's used by types such
 | 
			
		||||
as [Repeater](https://doc.qt.io/qt-6/qml-qtquick-repeater.html)
 | 
			
		||||
and [Quickshell.Variants](/docs/types/quickshell/variants)
 | 
			
		||||
to create instances of a component at runtime.
 | 
			
		||||
as @@QtQuick.Repeater and @@Quickshell.Variants to create instances of a component at runtime.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue