如何在QML中定义Javascript资源
2016-12-02 09:54
369 查看
目录(?)[+]
在QML的设计中,在很多的情况下,我们可以把我们的逻辑代码通过JavaScript来书写,而且可以把我们的JS代码掩埋在我们的QML代码中,比如典型的代码如下:
[html] view
plain copy
Button {
text: "Calculate"
onClicked: {
console.log("Change button is clicked")
console.log(Method.factorial(10));
console.log(Method.factorialCallCount())
}
}
在上面的代码中,我们定义了一个Button按钮.每当我们的按钮的触碰事件click发生时,我们可以在我们的QML文件中直接按照上面的方法来执行我们的Javascript代码.在onClicked后面的"{"及"}"中间其实就是我们的Javascript代码来实现我们的逻辑处理.
事实上,如果我们的逻辑比较复杂,并且有时,我们想把我们的逻辑及UI (由QML语言描述)分开的话,这时候,我们可以直接把我们的逻辑代码放入到一个叫做Javascript的文件之中.然后再在我们的QML文件中进行直接import.这样的好处是界面和逻辑分开,也可以使得我们的QML代码简单明了.
在QML中引入Javascript有两种方式.有兴趣的开发者可以参阅Qt的官方文档.在该文档中,如果不是自己亲手去实验,其实也很晦涩难懂.简单地说,这两种方式是:
stateful:在这种方式下,js模块中所定义的变量在每次被import后,都会被拷贝一份.所以如果有被多次import就有多个拷贝,而且每个的值都可能会有不同. 在这种过情况下,js文件可以直接访问在我们QML文件中所定义的object
statelss:在这种情况下,js所定义的模块就像一个公共分享的库一样.它里面的方法都可以被使用,并且模块里定义的变量在所以被import的QML代码中独一份,无论被import多少次.另外,它不可以直接访问QML文件中的object尽管可以通过参数的传人对所要求的object进行修改.
plain copy
// MyButton.qml
import QtQuick 2.0
import "my_button_impl.js" as Logic // a new instance of this JavaScript resource is loaded for each instance of Button.qml
import "factorial.js" as Method
Rectangle {
id: rect
width: 200
height: 100
color: "red"
property int count: 0
property alias text: mytext.text
signal clicked()
Text {
id: mytext
anchors.centerIn: parent
font.pixelSize: units.gu(3)
}
MouseArea {
id: mousearea
anchors.fill: parent
onClicked: {
rect.clicked()
count = Logic.onClicked(rect)
console.log(Method.factorialCallCount())
}
}
}
plain copy
// this state is separate for each instance of MyButton
var clickCount = 0;
function onClicked(obj) {
clickCount += 1;
if ((clickCount % 5) == 0) {
obj.color = Qt.rgba(1,0,0,1);
} else {
obj.color = Qt.rgba(0,1,0,1);
}
return clickCount;
}
function changeBackgroundColor() {
main.backgroundColor = "green"
}
在我们的MyButton.qml中,我们import了my_button_impl.js这个文件.由于这个js文件的最前面没有".pragma library",所以它是一个stateful的Javascript.如果我们有多个MyButton的实例,那么每个按钮都分别有自己的clickCount变量,并且它们之间毫无关系.
我们在我们的Main.qml中加入两个我们设计的MyButton按钮:
plain copy
Column {
anchors.centerIn: parent
spacing: units.gu(5)
MyButton {
anchors.horizontalCenter: parent.horizontalCenter
text: "Button " + count
onClicked: {
console.log("Button 1 is clicked!")
}
}
MyButton {
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
text: "Button " + count
onClicked: {
console.log("Button 2 is clicked!")
}
}
}
运行我们的代码:
从上面的输出可以看出,两个按钮的count可以是完全不同的.它们之间完全独立.
另外,我们也在我们的my_button_impl.js中设计了如下的函数:
[html] view
plain copy
function changeBackgroundColor() {
main.backgroundColor = "green"
}
显然它可以直接访问我们在Main.qml中的object Main.运行我们应用,点击"Change color"按钮:
可以看见我们的MainView的背景颜色已经发生改变了.
[html] view
plain copy
.pragma library
我们一个完整的factorial.js文件如下:
[html] view
plain copy
.pragma library
var factorialCount = 0;
function factorial(a) {
// a = parseInt(a);
// factorial recursion
if (a > 0)
return a * factorial(a - 1);
// shared state
factorialCount += 1;
// recursion base-case.
return 1;
}
function factorialCallCount() {
return factorialCount;
}
function changeBackgroundColor() {
main.backgroundColor = "green"
}
function changeBackground(obj) {
obj.backgroundColor = "green"
}
在这个模块中,我们定义了一个factorialCount的变量.由于是stateless,所有这个变量对于所有的import文件来说,只有一个.有点类似于C++类中static变量.在我们的Main.qml中,我们定义了一个按钮:
plain copy
Button {
text: "Calculate"
onClicked: {
console.log("Calculate button is clicked")
console.log(Method.factorial(10));
console.log(Method.factorialCallCount())
}
}
按下这个按钮,factorial将会帮我们计算我们的结果,同时会显示factorial被调用多少次.在我们的MyButton.qml中,我们也在点击的地方展示这个数据:
plain copy
MouseArea {
id: mousearea
anchors.fill: parent
onClicked: {
rect.clicked()
count = Logic.onClicked(rect)
console.log(Method.factorialCallCount())
}
}
如果我们点击"Calculate"按钮,在点击MyButton按钮,我们将可以看到同样的factorialCount值.
同样的,如果在我们的factorial.js中直接访问object main来修改它的属性,就像:
[html] view
plain copy
function changeBackgroundColor() {
main.backgroundColor = "green"
}
这样是不可以的.我们必须通过如下的方法来修改:
[html] view
plain copy
function changeBackground(obj) {
obj.backgroundColor = "green"
}
我们在我们的Main.qml中使用如下的代码来实现:
[html] view
plain copy
Button {
text: "Change color via stateless "
onClicked: {
Method.changeBackground(main)
}
}
整个项目的源码:https://github.com/liu-xiao-guo/JsInQml
原文地址:http://blog.csdn.net/ubuntutouch/article/details/51451757
在QML的设计中,在很多的情况下,我们可以把我们的逻辑代码通过JavaScript来书写,而且可以把我们的JS代码掩埋在我们的QML代码中,比如典型的代码如下:
[html] view
plain copy
Button {
text: "Calculate"
onClicked: {
console.log("Change button is clicked")
console.log(Method.factorial(10));
console.log(Method.factorialCallCount())
}
}
在上面的代码中,我们定义了一个Button按钮.每当我们的按钮的触碰事件click发生时,我们可以在我们的QML文件中直接按照上面的方法来执行我们的Javascript代码.在onClicked后面的"{"及"}"中间其实就是我们的Javascript代码来实现我们的逻辑处理.
事实上,如果我们的逻辑比较复杂,并且有时,我们想把我们的逻辑及UI (由QML语言描述)分开的话,这时候,我们可以直接把我们的逻辑代码放入到一个叫做Javascript的文件之中.然后再在我们的QML文件中进行直接import.这样的好处是界面和逻辑分开,也可以使得我们的QML代码简单明了.
在QML中引入Javascript有两种方式.有兴趣的开发者可以参阅Qt的官方文档.在该文档中,如果不是自己亲手去实验,其实也很晦涩难懂.简单地说,这两种方式是:
stateful:在这种方式下,js模块中所定义的变量在每次被import后,都会被拷贝一份.所以如果有被多次import就有多个拷贝,而且每个的值都可能会有不同. 在这种过情况下,js文件可以直接访问在我们QML文件中所定义的object
statelss:在这种情况下,js所定义的模块就像一个公共分享的库一样.它里面的方法都可以被使用,并且模块里定义的变量在所以被import的QML代码中独一份,无论被import多少次.另外,它不可以直接访问QML文件中的object尽管可以通过参数的传人对所要求的object进行修改.
1)stateful
我们特意在我们的例子中加入我们一个特有的MyButton.qml:MyButton.qml
[html] viewplain copy
// MyButton.qml
import QtQuick 2.0
import "my_button_impl.js" as Logic // a new instance of this JavaScript resource is loaded for each instance of Button.qml
import "factorial.js" as Method
Rectangle {
id: rect
width: 200
height: 100
color: "red"
property int count: 0
property alias text: mytext.text
signal clicked()
Text {
id: mytext
anchors.centerIn: parent
font.pixelSize: units.gu(3)
}
MouseArea {
id: mousearea
anchors.fill: parent
onClicked: {
rect.clicked()
count = Logic.onClicked(rect)
console.log(Method.factorialCallCount())
}
}
}
my_button_impl.js
[html] viewplain copy
// this state is separate for each instance of MyButton
var clickCount = 0;
function onClicked(obj) {
clickCount += 1;
if ((clickCount % 5) == 0) {
obj.color = Qt.rgba(1,0,0,1);
} else {
obj.color = Qt.rgba(0,1,0,1);
}
return clickCount;
}
function changeBackgroundColor() {
main.backgroundColor = "green"
}
在我们的MyButton.qml中,我们import了my_button_impl.js这个文件.由于这个js文件的最前面没有".pragma library",所以它是一个stateful的Javascript.如果我们有多个MyButton的实例,那么每个按钮都分别有自己的clickCount变量,并且它们之间毫无关系.
我们在我们的Main.qml中加入两个我们设计的MyButton按钮:
Main.qml
[html] viewplain copy
Column {
anchors.centerIn: parent
spacing: units.gu(5)
MyButton {
anchors.horizontalCenter: parent.horizontalCenter
text: "Button " + count
onClicked: {
console.log("Button 1 is clicked!")
}
}
MyButton {
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
text: "Button " + count
onClicked: {
console.log("Button 2 is clicked!")
}
}
}
运行我们的代码:
从上面的输出可以看出,两个按钮的count可以是完全不同的.它们之间完全独立.
另外,我们也在我们的my_button_impl.js中设计了如下的函数:
[html] view
plain copy
function changeBackgroundColor() {
main.backgroundColor = "green"
}
显然它可以直接访问我们在Main.qml中的object Main.运行我们应用,点击"Change color"按钮:
可以看见我们的MainView的背景颜色已经发生改变了.
2)stateless
针对这种情况,在Javascript文件的开头部分必须是一下的语句:[html] view
plain copy
.pragma library
我们一个完整的factorial.js文件如下:
[html] view
plain copy
.pragma library
var factorialCount = 0;
function factorial(a) {
// a = parseInt(a);
// factorial recursion
if (a > 0)
return a * factorial(a - 1);
// shared state
factorialCount += 1;
// recursion base-case.
return 1;
}
function factorialCallCount() {
return factorialCount;
}
function changeBackgroundColor() {
main.backgroundColor = "green"
}
function changeBackground(obj) {
obj.backgroundColor = "green"
}
在这个模块中,我们定义了一个factorialCount的变量.由于是stateless,所有这个变量对于所有的import文件来说,只有一个.有点类似于C++类中static变量.在我们的Main.qml中,我们定义了一个按钮:
Main.qml
[html] viewplain copy
Button {
text: "Calculate"
onClicked: {
console.log("Calculate button is clicked")
console.log(Method.factorial(10));
console.log(Method.factorialCallCount())
}
}
按下这个按钮,factorial将会帮我们计算我们的结果,同时会显示factorial被调用多少次.在我们的MyButton.qml中,我们也在点击的地方展示这个数据:
MyButton.qml
[html] viewplain copy
MouseArea {
id: mousearea
anchors.fill: parent
onClicked: {
rect.clicked()
count = Logic.onClicked(rect)
console.log(Method.factorialCallCount())
}
}
如果我们点击"Calculate"按钮,在点击MyButton按钮,我们将可以看到同样的factorialCount值.
同样的,如果在我们的factorial.js中直接访问object main来修改它的属性,就像:
[html] view
plain copy
function changeBackgroundColor() {
main.backgroundColor = "green"
}
这样是不可以的.我们必须通过如下的方法来修改:
[html] view
plain copy
function changeBackground(obj) {
obj.backgroundColor = "green"
}
我们在我们的Main.qml中使用如下的代码来实现:
[html] view
plain copy
Button {
text: "Change color via stateless "
onClicked: {
Method.changeBackground(main)
}
}
整个项目的源码:https://github.com/liu-xiao-guo/JsInQml
原文地址:http://blog.csdn.net/ubuntutouch/article/details/51451757
相关文章推荐
- js 动态生成json对象、时时更新json对象的方法
- Newtonsoft.Json高级用法
- 详解JavaScript中数组的reduce方法
- 基于javascript实现按圆形排列DIV元素(二)
- 解决调用Iframe引入跨域访问页js方法问题
- git命令整理
- js跨域调用报表
- 201612020940——《Javascript深拷贝》
- 用JS获取Html标签属性
- 基于javascript实现按圆形排列DIV元素(一)
- Console命令详解,让调试js代码变得更简单
- Jquery 中的$(this) 和javascript中的this
- js封装一个出去字符串中的空格方法
- JSPatch基础用法总结
- Servlet上传微小工程
- javascript实现鼠标点击页面 移动DIV
- JS基础一
- id pid格式json数据,生成树算法
- 八幅漫画理解使用JSON Web Token设计单点登录系统
- javascript url参数重构