Qt6 QML Book/网络设置/通过HTTP为用户界面提供服务

Serving UI via HTTP

通过HTTP为用户界面提供服务

To load a simple user interface via HTTP we need to have a web-server, which serves the UI documents. We start off with our own simple web-server using a python one-liner. But first, we need to have our demo user interface. For this, we create a small RemoteComponent.qml file in our project folder and create a red rectangle inside.

为了通过HTTP加载一个简单的用户界面,我们需要一个提供UI文档的web服务器。我们从使用python one-liner的简单web服务器开始。但首先,我们需要有我们的演示用户界面。为此,我们创建了一个小的RemoteComponent.qml文件,并在其中创建一个红色矩形。

// RemoteComponent.qml
import QtQuick

Rectangle {
    width: 320
    height: 320
    color: '#ff0000'
}

To serve this file we can start a small python script:

为了提供这个文件,我们可以启动一个小的python脚本:

cd <PROJECT>
python -m http.server 8080

Now our file should be reachable via http://localhost:8080/RemoteComponent.qml. You can test it with:

现在我们的文件应该可以通过http://localhost:8080/RemoteComponent.qml.您可以通过以下方式进行测试:

curl http://localhost:8080/RemoteComponent.qml

Or just point your browser to the location. Your browser does not understand QML and will not be able to render the document through.

或者只需将浏览器指向该位置。您的浏览器不理解QML,将无法通过呈现文档。

Hopefully, Qt 6 provides such a browser in the form of the qml binary. You can directly load a remote QML document by using the following command:

Qt6有望以qml二进制文件的形式提供这样的浏览器。您可以使用以下命令直接加载远程QML文档:

qml http://localhost:8080/RemoteComponent.qml

Sweet and simple.

完美而简洁。

TIP

If the qml program is not in your path, you can find it in the Qt binaries: <qt-install-path>/<qt-version>/<your-os>/bin/qml.

如果qml程序不在您的路径中,您可以在Qt二进制文件中找到它:<Qt install path>/<Qt version>/<your os>/bin/qml。

Another way of importing a remote QML document is to dynamically load it using QML ! For this, we use a Loader element to retrieve for us the remote document.

导入远程QML文档的另一种方法是使用QML动态加载它!为此,我们使用Loader元素类型为我们检索远程文档。

// LocalHostExample.qml
import QtQuick

Loader {
    id: root
    source: 'http://localhost:8080/RemoteComponent.qml'
    onl oaded: {
        root.width = root.item.width  // qmllint disable
        root.height = root.item.height  // qmllint disable
    }
}

Now we can ask the qml executable to load the local LocalHostExample.qml loader document.

现在我们可以要求qml可执行文件加载本地LocalHostExample.qml加载器文档。

qml LocalHostExample.qml

TIP

If you do not want to run a local server you can also use the gist service from GitHub. The gist is a clipboard like online services like Pastebin and others. It is available under https://gist.github.com. I created for this example a small gist under the URL https://gist.github.com/jryannel/7983492. This will reveal a green rectangle. As the gist URL will provide the website as HTML code we need to attach a /raw to the URL to retrieve the raw file and not the HTML code.


如果不想运行本地服务器,也可以使用GitHub的gist服务。要点是一个类似剪贴板的在线服务,如Pastebin和其他。可在https://gist.github.com下载.我在URL https://gist.github.com/jryannel/7983492下为这个例子创建了一个小gist服务。这将显示一个绿色矩形。由于gist URL将以HTML代码的形式提供网站,我们需要在URL上附加一个/raw来检索原始文件,而不是HTML代码。

// GistExample.qml
import QtQuick

Loader {
    id: root
    source: 'https://gist.github.com/jryannel/7983492/raw'
    onl oaded: {
        root.width = root.item.width  // qmllint disable
        root.height = root.item.height  // qmllint disable
    }
}

To load another file over the network from RemoteComponent.qml, you will need to create a dedicated qmldir file in the same directory on the server. Once done, you will be able to reference the component by its name.

通过网络从RemoteComponent.qml加载另一个文件,您需要在服务器的同一目录中创建一个专用qmldir文件。完成后,您将能够通过其名称引用组件。

Networked Components

网络组件

Let us create a small experiment. We add to our remote side a small button as a reusable component.

让我们做一个小实验。我们在远程添加了一个小按钮作为可重用组件。

Here's the directory structure that we will use:

下面是我们将使用的目录结构:

./src/SimpleExample.qml
./src/remote/qmldir
./src/remote/Button.qml
./src/remote/RemoteComponent.qml

Our SimpleExample.qml is the same as our previous main.qml example:

我们的SimpleExample.qml与我们之前的main.qml示例相同:

import QtQuick

Loader {
    id: root
    anchors.fill: parent
    source: 'http://localhost:8080/RemoteComponent.qml'
    onl oaded: {
        root.width = root.item.width  // qmllint disable
        root.height = root.item.height  // qmllint disable
    }
}

In the remote directory, we will update the RemoteComponent.qml file so that it uses a custom Button component:

在远程目录remote中,我们将更新RemoteComponent.qml文件,以便使用自定义按钮组件Button

// remote/RemoteComponent.qml
import QtQuick

Rectangle {
    width: 320
    height: 320
    color: '#ff0000'

    Button {
        anchors.centerIn: parent
        text: qsTr('Click Me')
        onClicked: Qt.quit()
    }
}

As our components are hosted remotely, the QML engine needs to know what other components are available remotely. To do so, we define the content of our remote directory within a qmldir file:

由于我们的组件是远程托管的,所以QML引擎需要知道哪些其他组件是远程可用的。为此,我们在qmldir文件中定义远程目录的内容:

# qmldir
Button 1.0 Button.qml

And finally we will create our dummy Button.qml file:

最后,我们将创建虚拟Button.qml文件:

// remote/Button.qml
import QtQuick.Controls

Button {
    
}

We can now launch our web-server (keep in mind that we now have a remote subdirectory):

我们现在可以启动web服务器(请记住,我们现在有一个远程子目录remote):

cd src/serve-qml-networked-components/
python -m http.server --directory ./remote 8080

And remote QML loader:

远程QML加载程序:

qml SimpleExample.qml

Importing a QML components directory

导入QML组件目录

By defining a qmldir file, it's also possible to directly import a library of components from a remote repository. To do so, a classical import works:

通过定义qmldir文件,还可以直接从远程存储库导入组件库。要做到这一点,一个经典的导入是有效的:

import QtQuick
import "http://localhost:8080" as Remote

Rectangle {
    width: 320
    height: 320
    color: 'blue'

    Remote.Button {
        anchors.centerIn: parent
        text: qsTr('Quit')
        onClicked: Qt.quit()
    }
}

TIP

When using components from a local file system, they are created immediately without a latency. When components are loaded via the network they are created asynchronously. This has the effect that the time of creation is unknown and an element may not yet be fully loaded when others are already completed. Take this into account when working with components loaded over the network.

使用本地文件系统中的组件时,会立即创建它们,而不会产生延迟。当组件通过网络加载时,它们是异步创建的。这会导致创建时间未知,并且当其他元素已经完成时,该元素可能尚未完全加载。在处理通过网络加载的组件时,请考虑这一点。

 示例源码下载

上一篇:设置右键菜单


下一篇:Markdown MathJax 恒不等于输入