Ubuntu QML中的WebView及HTML混合编程(hybrid programming)

对于大多数的网页开发者来说,我们可以充分利用我们的QML UI框架来实现一些比较炫的界面,我们也可以利用HTML5现有的应用架构来实现我们基于Web的应用.在今天的例程中,我们来展示如何把这两个方面充分结合起来.这样可以使得我们的应用更加炫,更加充分利用现有的Ubuntu QML APIs来实现我们的一些功能.


1)设计我们的HTML文件


<html>
<head>
<script>
    document.addEventListener("QMLmessage", function (event) {
        document.body.innerHTML += "<p><font size='20' color='red'>Message received.  You said " + event.detail.greeting + "</font></p>";
    });
</script>
</head>

<body>
<h1>Hello</h1>
</body>
</html>

为了说明文档的方便,我设计了一个简单的界面.


在上面的界面中,html显示的内容不包括上面的按钮部分.只显示一个"Hello".同时我们定义了一个如下的一个事件响应器:

 document.addEventListener("QMLmessage", function (event) {
        document.body.innerHTML += "<p><font size='20' color='red'>Message received.  You said " + event.detail.greeting + "</font></p>";
    });

每当有一个叫做QMLmessage的实际响应的时候,我们会在界面上自动加入我们想要的一行字.比如:

Ubuntu QML中的WebView及HTML混合编程(hybrid programming)_第1张图片


2)触发QMLmessage事件


在下面的Main.qml代码中:

import QtQuick 2.4
import Ubuntu.Components 1.3
import Ubuntu.Web 0.2
import com.canonical.Oxide 1.9 as Oxide

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "webview-oxide.liu-xiao-guo"

    property string usContext: "messaging://"

    width: units.gu(60)
    height: units.gu(85)

    Page {
        title: i18n.tr("webview-oxide")

        Rectangle {
            anchors.fill: parent

            // Both the UserScript and the call to sendMessage need to share the same
            // context, which should be in the form of a URL.  It doesn't seem to matter
            // what it is, though.
            property string usContext: "messaging://"

            WebView {
                id: webview
                anchors {
                    top: parent.top
                    left: parent.left
                    right: parent.right
                    bottom: button.top
                }
                context: webcontext
                url: {
                    console.log("address: " + Qt.resolvedUrl("index.html"))
                    return Qt.resolvedUrl("index.html")
                }
            }

            WebContext {
                id: webcontext
                userScripts: [
                    Oxide.UserScript {
                        context: usContext
                        url: Qt.resolvedUrl("oxide-user.js")
                    }
                ]
            }

            Button {
                id: button
                anchors {
                    bottom: parent.bottom
                    left: parent.left
                    right: parent.right
                }
                text: "Press Me"
                onClicked: {
                    var req = webview.rootFrame.sendMessage(usContext, "MESSAGE", {greeting: "Hello"})
                    req.onreply = function (msg) {
                        console.log("Got reply: " + msg.str);
                    }
                    req.onerror = function (code, explanation) {
                        console.log("Error " + code + ": " + explanation)
                    }
                }
            }
        }
    }
}

我们通过按钮"button"来向我们的WebView发送我们需要的QMLmessage事件.在这里我们使用了:

            WebContext {
                id: webcontext
                userScripts: [
                    Oxide.UserScript {
                        context: usContext
                        url: Qt.resolvedUrl("oxide-user.js")
                    }
                ]
            }

上面的oxide-user的内容为:

oxide.addMessageHandler("MESSAGE", function (msg) {
    var event = new CustomEvent("QMLmessage", {detail: msg.args});
    document.dispatchEvent(event);
    msg.reply({str: "OK"});
});

也就是在我们发送完一个信息后,我们同时也得到一个返回的信息"OK".这个可以在为我们的应用输出中可以看出:



这样我们实现了从QML到HTML文件的交互.这对于我们设计一些基于地图定位或导航的应用来说是非常中要的手段.

整个项目的源码在: https://github.com/liu-xiao-guo/webview-oxide


你可能感兴趣的:(Ubuntu QML中的WebView及HTML混合编程(hybrid programming))