-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
368 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,368 @@ | ||
--- | ||
language: QML | ||
contributors: | ||
- ["Furkan Uzumcu", "https://zmc.space/"] | ||
filename: learnqml.qml | ||
lang: en-us | ||
--- | ||
|
||
```qml | ||
// This is a completely valid QML file that you can run using `qmlscene` if you copy the contents | ||
// into a *.qml file. | ||
// Comments start with double forward slashes. | ||
/* Or you | ||
can have | ||
multi line | ||
comments | ||
*/ | ||
// Import statement syntax is | ||
// import ${MODULE_NAME} [${VERSION_NUMBER}] [as ${QUALIFIER}] | ||
import QtQuick 2.15 | ||
import QtQuick.Window 2.15 | ||
import QtQuick.Controls 2.15 as QQC | ||
import QtQuick.Layouts 1.15 | ||
import Qt.labs.platform 1.1 | ||
// Each QML document can contain only one top level type | ||
Window { | ||
// Each object has a special and optional `id` attribute that can be used to refer to the | ||
// declared objects. An `id` has to be unique in the same document. | ||
id: root | ||
width: 400 | ||
height: 600 | ||
title: "Learn QML in Y Minutes" | ||
Item { | ||
// Every object that can be declared inherits from QObject and contains at | ||
// least one property, which is `objectName`. All the other properties are | ||
// added by extending `QObject` type. This is an `Item` type and it contains | ||
// the additional `width` and `height` properties and more. | ||
objectName: "My Item" | ||
// `id`s in the same document can be used anywhere in the same file. | ||
// You cannot access an `id` from a different file. | ||
width: root.width | ||
} | ||
// Signals are used to communicate that a certain event happened. | ||
// Some types have built-in signals | ||
Timer { | ||
id: timer | ||
interval: 500 | ||
onTriggered: { | ||
console.log("Timer triggered!") | ||
} | ||
} | ||
QtObject { | ||
id: objSignals | ||
// You can also declare your own signals. | ||
signal clicked() | ||
// Signals can also have arguments. | ||
signal mousePositionChanged(int x, int y) | ||
// The way to react to a signal emission is by adding signal handlers to | ||
// the immediate object that the signal belongs to. | ||
onClicked: () => { | ||
// Do stuff here. | ||
console.log("objSignals.clicked() signal is emitted.") | ||
} | ||
// Signal handlers must explicitly declare the arguments. | ||
onMousePositionChanged: (x, y) => { | ||
// Do stuff here. | ||
console.log("objSignals.mousePositionChanged() signal is emitted. x=", x, "y=", y) | ||
} | ||
} | ||
// If you want to declare signal handlers for other objects, you can use | ||
// `Connections`. | ||
Connections { | ||
target: objSignals | ||
// You can then declare functions with the same name as the signal | ||
// handler. | ||
function onClicked() { | ||
console.log("objSignals.clicked() signal is handled from Connections.") | ||
} | ||
} | ||
Item { | ||
visible: false | ||
// An object can support having child objects. You can add child objects | ||
// by declaring types as follows: | ||
Rectangle { | ||
width: 16 | ||
height: 16 | ||
color: "red" | ||
} | ||
} | ||
Item { | ||
id: objProperties | ||
// You can also declare your own properties. | ||
// Syntax for declaring is | ||
// [default] [required] [readonly] property ${TYPE} ${NAME} | ||
property color nextColor | ||
// Read only properties have to be initialized when declared. | ||
readonly property color defaultColor: "red" | ||
// Required properties have to be initialized where the reusable type is | ||
// used. | ||
required property color initialColor | ||
// NOTE: Although the initial assignment can be done in the same file, | ||
// it is not often the use case. | ||
initialColor: "green" | ||
// Properties are type safe and a property can only be assigned a value | ||
// that matches the property type. | ||
// property int volume: "four" // ERROR! | ||
Item { | ||
// You can create alias properties that hold a reference to another | ||
// property. | ||
property alias parentNextColor: objProperties.nextColor | ||
// Assignments to alias properties alter the property that it holds | ||
// a reference to. | ||
parentNextColor: "blue" // Changes objProperties.nextColor | ||
// Since `parentNextColor` is an alias to `nextColor`, any changes | ||
// to `nextColor` will also be reflected to `parentNextColor`. | ||
} | ||
} | ||
Item { | ||
// Property assignment values can either be static or binding | ||
// expressions. | ||
// Static value | ||
property int radius: 32 | ||
// Binding expressions describe a property's relationship to other | ||
// properties. When the value of `radius` changes, the expression here | ||
// will be re-evaluated. | ||
property int diameter: radius * 2 | ||
onDiameterChanged: { | ||
console.log("onDiameterChanged:", diameter) | ||
} | ||
} | ||
ListView { | ||
// Attached properties and signal handlers provide a way to extend an | ||
// existing object and provide more information that is otherwise not | ||
// immediately available. | ||
width: 100 | ||
height: 30 | ||
model: 3 | ||
delegate: Rectangle { | ||
// ListView provides an attached property for its children that can | ||
// be used to access more information. | ||
color: ListView.isCurrentItem ? "green" : "red" | ||
} | ||
// Attached types can also have signal handlers. | ||
// `Component` is attached to every type that's available in QML. | ||
Component.onCompleted: { | ||
console.log("This signal handler is called after object is created.") | ||
} | ||
} | ||
Rectangle { | ||
// Since this rectangle is not created by the ListView, the attached | ||
// type is not avaiable. | ||
color: ListView.isCurrentItem ? "green" : "red" | ||
} | ||
QtObject { | ||
id: calculator | ||
// Objects can also declare methods. Function declarations can annotate | ||
// the arguments, or have no arguments at all. | ||
function add(a: int, b: int): int { | ||
// Semicolon at the end of a line is optional. | ||
return a + b | ||
} | ||
function multiply(a: real, b: real): real { | ||
return a * b; | ||
} | ||
} | ||
MouseArea { | ||
anchors.fill: parent | ||
onClicked: (mouse) => { | ||
console.log("2 + 2 =", calculator.add(2, 2)) | ||
} | ||
} | ||
Item { | ||
width: 100 | ||
// Methods can also be used as binding expressions. When `width` | ||
// changes, the binding expression will evaluate and call `multiply`. | ||
height: calculator.multiply(width, 0.5) | ||
opacity: calculateOpacity() | ||
function calculateOpacity() { | ||
// If the function declaration contains references to other | ||
// properties, changes to those properties also trigger a binding | ||
// evaluation. | ||
return height < 50 ? 0.5 : 1 | ||
} | ||
} | ||
// Each QML file that starts with an upper case name declares a re-usable | ||
// component, e.g "RedRectangle.qml". | ||
// In addition, reusable components can be declared in-line. | ||
component RedRectangle: Rectangle { | ||
color: "red" | ||
} | ||
// This inline component can then be used in the same file, or in other | ||
// files by prefixing the type name with the file name that it belongs to. | ||
// | ||
// ${FILE_NAME}.RedRectangle { } | ||
// or | ||
RedRectangle { | ||
} | ||
// QML also supports enumeration declarations. | ||
component MyText: Text { | ||
enum TextType { | ||
Normal, | ||
Heading | ||
} | ||
// Enum types are assigned to integer properties. | ||
property int textType: MyText.TextType.Normal | ||
font.bold: textType == MyText.TextType.Heading | ||
font.pixelSize: textType == MyText.TextType.Heading ? 24 : 12 | ||
} | ||
// ----- Interactive Area | ||
QQC.ScrollView { | ||
anchors.fill: parent | ||
contentWidth: container.implicitWidth | ||
contentHeight: container.implicitHeight | ||
Column { | ||
id: container | ||
spacing: 6 | ||
Row { | ||
spacing: 2 | ||
QQC.Label { | ||
width: 200 | ||
anchors.verticalCenter: parent.verticalCenter | ||
text: "Click to start the timer.\nCheck the logs!" | ||
wrapMode: QQC.Label.WordWrap | ||
} | ||
QQC.Button { | ||
text: timer.running ? "Timer Running" : "Start Timer" | ||
onClicked: { | ||
timer.start() | ||
} | ||
} | ||
} | ||
Row { | ||
spacing: 2 | ||
QQC.Label { | ||
width: 200 | ||
anchors.verticalCenter: parent.verticalCenter | ||
text: "Click to emit objSignals.clicked() signal" | ||
wrapMode: QQC.Label.WordWrap | ||
} | ||
QQC.Button { | ||
property int emissionCount: 0 | ||
text: "Emitted " + emissionCount + " times." | ||
onClicked: { | ||
objSignals.clicked() | ||
emissionCount++ | ||
} | ||
} | ||
} | ||
Row { | ||
spacing: 2 | ||
QQC.Label { | ||
width: 200 | ||
anchors.verticalCenter: parent.verticalCenter | ||
text: "Click to emit objSignals.mousePositionChanged() signal" | ||
wrapMode: QQC.Label.WordWrap | ||
} | ||
QQC.Button { | ||
property int emissionCount: 0 | ||
text: "Emitted " + emissionCount + " times." | ||
onClicked: { | ||
objSignals.mousePositionChanged(32, 32) | ||
emissionCount++ | ||
} | ||
} | ||
} | ||
Rectangle { | ||
width: 200 | ||
height: 80 | ||
color: objProperties.nextColor | ||
QQC.Label { | ||
width: 200 | ||
anchors.verticalCenter: parent.verticalCenter | ||
text: "Click to change nextColor property." | ||
wrapMode: QQC.Label.WordWrap | ||
} | ||
TapHandler { | ||
onTapped: { | ||
colorDialog.open() | ||
} | ||
} | ||
ColorDialog { | ||
id: colorDialog | ||
currentColor: objProperties.initialColor | ||
onColorChanged: { | ||
objProperties.nextColor = color | ||
} | ||
} | ||
} | ||
Row { | ||
spacing: 2 | ||
Rectangle { | ||
width: 200 | ||
height: 80 | ||
color: "red" | ||
radius: radiusSlider.value | ||
QQC.Label { | ||
width: parent.width | ||
anchors.centerIn: parent | ||
text: "Use slider to change radius" | ||
wrapMode: QQC.Label.WordWrap | ||
horizontalAlignment: Qt.AlignHCenter | ||
} | ||
} | ||
QQC.Slider { | ||
id: radiusSlider | ||
width: 100 | ||
anchors.verticalCenter: parent.verticalCenter | ||
from: 0 | ||
to: 80 | ||
} | ||
} | ||
} | ||
} | ||
} | ||
``` |