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