import QtQuick 2.9
import QtQuick.Controls 1.3
ApplicationWindow {
title: "Example"
visible: true
width: 300
height: 300
Button {
text: "Button"
anchors.centerIn: parent
onClicked: console.log('Hello')
}
}I may be biased, but to me the QML code is much cleaner and clearer than JSX.
(Think of an Item as a visual component, which can either be referred to by an id or, as I've done here, referred to by its children as "parent".)
Item {
property int count: 1
Button {
height: 30; width: 80
onClicked: parent.count++
}
Text {
height: 20; width: 30
text: parent.count
}
}
The text will update every time you click the button.What's nice about react is that the JSX syntax is just sugar that converts to function calls.
The standard way to do this in QML is using the Loader object: http://doc.qt.io/qt-5/qml-qtqml-component.html
You can also go full-eval of course: http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation...
You have been able to bind closures to events in Qt for... dunnno... 6 years maybe ?
View = fn(state) solves longstanding issues with all the previous approaches, and of course it decreases their complexity. It is also the first approach that's breaching the platform barrier successfully while maintaining the high-level. You can write React for countless of targets, being able to re-use and apply the eco-system.
Could you please paste an example of a real, functional QT component? For instance a component that is re-used in another component,
const A = ({ text }) => <div>{text}</div>
const B = () => <A text="hello" />
<B /> // -> <div>hello</div>
as well as functional composition (higher-order-components): const canBeDisabled = Component => props => props.disabled ? null : <Component {...props} />
const ComposedB = canBeDisabled(B)
<ComposedB /> // -> <div>hello</div>
<ComposedB disabled /> // -> null
an example for statefull components would also be nice: class C extends Component {
state = { count: 0 }
up = () => this.setState(state => ({ count: state.count + 1 })
render() {
return <div onClick={this.up}>{this.state.count}</div>
}
}
<C /> // -> <div>0</div>, clicks count up reactively Text {
property int count: 0
text: count
MouseArea {
anchors.fill: parent
onClicked: count++
}
}
if you put this in a file `C.qml` or load it as a component (http://doc.qt.io/qt-5/qml-qtqml-component.html), then you can reuse it in other components: Item {
C { }
C { count: 23 } // starts at 23
}
For your functionally composed example, all qt objects have a `visible` property so you'd generally do : MyItem {
visible: props.disabled
}
Note that unlike React, the "default" paradigm is not functional : in QML you describe directly a dataflow graph between the properties of your objects. e.g. C { id: myCount }
Rectangle {
color: "red"
// the width will change whenever the count increase
width: Math.cos(myCount.count) / 2
}
This is because the objects with which you work in QML are exactly the ones that are going to be rendered - and at a fairly low-level: they mostly translate directly to GL / D3D primitives ; there is no need for a transformative pass like with react.There is a major difference between that and Reacts approach.
const A = () => <div>...</div>
const B = () => <h1><A /></h1>
Notice that the B component can refer to the A component because it's in the same scope. There's no magic and no binding/loading. A is a function that is called inside B's function body. It also isn't done by inference of an ID (which would be registration).Yes, an equivalent in QML would look like this if you want it in a single file:
Component {
id: a
Text { text: "foo" }
}
Component {
id: b
Rectangle { Loader { sourceComponent: a } }
}
but the language really wants you to have one component per file, so : A.qml:
Text { text: "foo" }
B.qml
Rectangle { A { } }
> if QT is the same,It's not. QML is at its core not a functional language, it's a declarative & reactive language. In my experience, at least 30-40% of QML code does not need any functions.
> There's no magic and no binding/loading.
I'm not sure we are using the same meaning of binding. The "A" token in your example is obviously bound to the "A" variable declared before.
> It also isn't done by inference of an ID (which would be registration).
ids in QML are just the variable names. eg
Rectangle {
A { id: foo }
width: 2 * foo.width
}http://blog.qt.io/blog/2018/04/13/qt-for-python-is-coming-to...
License-wise: "Qt for Python will have the same licensing as Qt for Application Development, i.e. it will be available under GPL, LGPL and commercial."
It doesn't serve the author well to make this comparison. Saying it's less messy to manage Proton/React source code files and the associated Node/JS/etc infrastructure is an extremely dubious claim. One of the things I like best about Qt is how non-messy Qt development is. Most everything (source files, resources, etc.) lives in a well-organized project that is easily managed using the Qt Creator IDE. The project structure is well-documented and standardized.
It's also quite strange to compare React code to code using the Python binding for Qt. That's not how most Qt apps are written. Most Qt apps these days use QML, which is based on regular old JavaScript. Besides being a more accurate representation of the way Qt development is normally done, it would also be more interesting to compare one JavaScript-based framework to another. (Although I recommend not making the comparison at all, since I don't believe a fair comparison would favor Proton.)