QT使用 C++编写 QML 扩展

本教程介绍了如何使用C++扩展QML,创建自定义QML类型,如PieChart,支持属性、信号和绑定。通过插件部署,可以在QML中使用这些扩展。教程涵盖创建新类型、连接到C++方法和信号、添加属性绑定、使用自定义属性类型和列表属性类型,以及编写扩展插件。
摘要由CSDN通过智能技术生成

QML模块提供了一组 API,用于通过C++扩展扩展 QML。您可以编写扩展来添加自己的 QML 类型、扩展现有 Qt 类型或调用普通 QML 代码无法访问的 C/C++ 函数。

本教程介绍如何使用包含核心 QML 功能(包括属性、信号和绑定)的C++编写 QML 扩展。它还显示了如何通过插件部署扩展。

本教程中介绍的许多主题及其文档子主题中都有更详细的记录。特别是,您可能对子主题和 .

运行教程示例

本教程中的代码可作为示例项目提供,其中包含与每个教程章节关联的子项目。在 中,打开模式并从中选择教程。在模式下,展开扩展 qml 项目,右键单击要运行的子项目(章节),然后选择 。

创建教程项目

我们使用Qt Creator中的Qt快速应用程序模板创建一个新项目,如中所述。

第 1 章:创建新类型

extending-qml/chapter1-basics

扩展 QML 时的一项常见任务是提供一种新的 QML 类型,该类型支持内置 .例如,这可以用于实现特定的数据模型,或为类型提供自定义绘制和绘图功能,或访问无法通过内置 QML 功能访问的系统功能(如网络编程)。

在本教程中,我们将展示如何使用 Qt Quick 模块中的C++类来扩展 QML。最终结果将是一个简单的饼图显示,由几个自定义QML类型实现,这些类型通过QML功能(如绑定和信号)连接在一起,并通过插件提供给QML运行时。

首先,让我们创建一个名为“PieChart”的新 QML 类型,它有两个属性:名称和颜色。我们将在名为“Charts”的可导入类型命名空间中提供它,版本为 1.0。

我们希望此类型可以从 QML 中使用,如下所示:PieChart

<span style="color:#404244"><span style="background-color:#ffffff"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#ffff55">import</span> <span style="color:#4f9d08">Charts</span> <span style="color:#ff55ff">1.0</span>

<span style="color:#4f9d08">PieChart</span> <span style="color:#ffffff">{</span>
    <span style="color:#ffffff">width</span><span style="color:#ffffff">:</span> <span style="color:#ff55ff">100</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">height</span><span style="color:#ffffff">:</span> <span style="color:#ff55ff">100</span>
    <span style="color:#ffffff">name</span><span style="color:#ffffff">:</span> <span style="color:#aaaaaa">"A simple pie chart"</span>
    <span style="color:#ffffff">color</span><span style="color:#ffffff">:</span> <span style="color:#aaaaaa">"red"</span>
<span style="color:#ffffff">}</span></span></span></span></span>

为此,我们需要一个封装此类型及其两个属性的 C++ 类。由于QML广泛使用了Qt,这个新类必须:PieChart

  • 继承自
  • 使用宏声明其属性

类声明

这是我们的类,定义在:PieChartpiechart.h

<span style="color:#404244"><span style="background-color:#ffffff"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#55ffff">#include</span> <span style="color:#ffffff"><</span><span style="color:#4f9d08">QtQuick</span><span style="color:#ffffff">/</span><span style="color:#4f9d08">QQuickPaintedItem</span><span style="color:#ffffff">></span>
<span style="color:#55ffff">#include</span> <span style="color:#ffffff"><</span><span style="color:#4f9d08">QColor</span><span style="color:#ffffff">></span>

<span style="color:#ffff55">class</span> <span style="color:#4f9d08">PieChart</span> <span style="color:#ffffff">:</span> <span style="color:#ffff55">public</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qquickpainteditem.html" href="https://doc.qt.io/qt-6/qquickpainteditem.html"><span style="color:#21be2b">QQuickPaintedItem</span></a>
<span style="color:#ffffff">{</span><span style="color:#ffffff">
    Q_OBJECT
    Q_PROPERTY</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qstring.html" href="https://doc.qt.io/qt-6/qstring.html"><span style="color:#21be2b">QString</span></a><span style="color:#ffffff"> name READ name WRITE setName FINAL</span><span style="color:#ffffff">)</span><span style="color:#ffffff">
    Q_PROPERTY</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qcolor.html" href="https://doc.qt.io/qt-6/qcolor.html"><span style="color:#21be2b">QColor</span></a><span style="color:#ffffff"> color READ color WRITE setColor FINAL</span><span style="color:#ffffff">)</span><span style="color:#ffffff">
    QML_ELEMENT

</span><span style="color:#ffff55">public</span><span style="color:#ffffff">:</span>
    <span style="color:#4f9d08">PieChart</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qquickitem.html" href="https://doc.qt.io/qt-6/qquickitem.html"><span style="color:#21be2b">QQuickItem</span></a> <span style="color:#ffffff">*</span><span style="color:#ffffff">parent </span><span style="color:#ffffff">=</span> <span style="color:#ffff55">nullptr</span><span style="color:#ffffff">);</span>

    <a data-cke-saved-href="https://doc.qt.io/qt-6/qstring.html" href="https://doc.qt.io/qt-6/qstring.html"><span style="color:#21be2b">QString</span></a><span style="color:#ffffff"> name</span><span style="color:#ffffff">()</span> <span style="color:#ffff55">const</span><span style="color:#ffffff">;</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> setName</span><span style="color:#ffffff">(</span><span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qstring.html" href="https://doc.qt.io/qt-6/qstring.html"><span style="color:#21be2b">QString</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">name</span><span style="color:#ffffff">);</span>

    <a data-cke-saved-href="https://doc.qt.io/qt-6/qcolor.html" href="https://doc.qt.io/qt-6/qcolor.html"><span style="color:#21be2b">QColor</span></a><span style="color:#ffffff"> color</span><span style="color:#ffffff">()</span> <span style="color:#ffff55">const</span><span style="color:#ffffff">;</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> setColor</span><span style="color:#ffffff">(</span><span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qcolor.html" href="https://doc.qt.io/qt-6/qcolor.html"><span style="color:#21be2b">QColor</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">color</span><span style="color:#ffffff">);</span>

    <span style="color:#ffff55">void</span><span style="color:#ffffff"> paint</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qpainter.html" href="https://doc.qt.io/qt-6/qpainter.html"><span style="color:#21be2b">QPainter</span></a> <span style="color:#ffffff">*</span><span style="color:#ffffff">painter</span><span style="color:#ffffff">)</span> <span style="color:#ffff55">override</span><span style="color:#ffffff">;</span>

<span style="color:#ffff55">private</span><span style="color:#ffffff">:</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qstring.html" href="https://doc.qt.io/qt-6/qstring.html"><span style="color:#21be2b">QString</span></a><span style="color:#ffffff"> m_name</span><span style="color:#ffffff">;</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qcolor.html" href="https://doc.qt.io/qt-6/qcolor.html"><span style="color:#21be2b">QColor</span></a><span style="color:#ffffff"> m_color</span><span style="color:#ffffff">;</span>
<span style="color:#ffffff">};</span></span></span></span></span>

该类继承自,因为我们想重写 () 以使用 API 执行绘制操作。如果类只是表示某种数据类型,而不是实际需要显示的项,则可以简单地从 继承。或者,如果我们想扩展现有的基于-的类的功能,它可以从该类继承。或者,如果我们想创建一个不需要使用 API 执行绘制操作的视觉项,我们可以 子类 .

该类定义两个属性,以及 ,以及宏和重写 ()。该类是使用宏注册的,以允许从 QML 使用它。如果不注册类,将无法创建 .PieChartnamecolorPieChartapp.qmlPieChart

qmake 设置

要使注册生效,将在项目文件中添加该选项,并给出 和:qmltypesCONFIGQML_IMPORT_NAMEQML_IMPORT_MAJOR_VERSION

<span style="color:#404244"><span style="background-color:#ffffff"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#ffffff">CONFIG </span><span style="color:#ffffff">+=</span><span style="color:#ffffff"> qmltypes
QML_IMPORT_NAME </span><span style="color:#ffffff">=</span> <span style="color:#4f9d08">Charts</span><span style="color:#ffffff">
QML_IMPORT_MAJOR_VERSION </span><span style="color:#ffffff">=</span> <span style="color:#ff55ff">1</span></span></span></span></span>

CMake 设置

同样,要在使用 CMake 时使注册生效,请使用以下命令:

<span style="color:#404244"><span style="background-color:#ffffff"><span style="background-color:#3a4055"><span style="color:#ffffff">qt_add_qml_module(chapter1-basics
    URI Charts
    QML_FILES app.qml
    NO_RESOURCE_TARGET_PATH
    DEPENDENCIES QtQuick
)</span></span></span></span>

类实现

中的类实现只是根据需要设置和返回 and 值,并实现绘制简单的饼图。它还会关闭标志以启用绘画:piechart.cppm_namem_colorpaint()

<span style="color:#404244"><span style="background-color:#ffffff"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#4f9d08">PieChart</span><span style="color:#ffffff">::</span><span style="color:#4f9d08">PieChart</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qquickitem.html" href="https://doc.qt.io/qt-6/qquickitem.html"><span style="color:#21be2b">QQuickItem</span></a> <span style="color:#ffffff">*</span><span style="color:#ffffff">parent</span><span style="color:#ffffff">)</span>
    <span style="color:#ffffff">:</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qquickpainteditem.html" href="https://doc.qt.io/qt-6/qquickpainteditem.html"><span style="color:#21be2b">QQuickPaintedItem</span></a><span style="color:#ffffff">(</span><span style="color:#ffffff">parent</span><span style="color:#ffffff">)</span>
<span style="color:#ffffff">{</span>
<span style="color:#ffffff">}</span>
<span style="color:#ffffff">...</span>
<span style="color:#ffff55">void</span> <span style="color:#4f9d08">PieChart</span><span style="color:#ffffff">::</span><span style="color:#ffffff">paint</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qpainter.html" href="https://doc.qt.io/qt-6/qpainter.html"><span style="color:#21be2b">QPainter</span></a> <span style="color:#ffffff">*</span><span style="color:#ffffff">painter</span><span style="color:#ffffff">)</span>
<span style="color:#ffffff">{</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qpen.html" href="https://doc.qt.io/qt-6/qpen.html"><span style="color:#21be2b">QPen</span></a><span style="color:#ffffff"> pen</span><span style="color:#ffffff">(</span><span style="color:#ffffff">m_color</span><span style="color:#ffffff">,</span> <span style="color:#ff55ff">2</span><span style="color:#ffffff">);</span><span style="color:#ffffff">
    painter</span><span style="color:#ffffff">-</span><span style="color:#ffffff">></span><span style="color:#ffffff">setPen</span><span style="color:#ffffff">(</span><span style="color:#ffffff">pen</span><span style="color:#ffffff">);</span><span style="color:#ffffff">
    painter</span><span style="color:#ffffff">-</span><span style="color:#ffffff">></span><span style="color:#ffffff">setRenderHints</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qpainter.html" href="https://doc.qt.io/qt-6/qpainter.html"><span style="color:#21be2b">QPainter</span></a><span style="color:#ffffff">::</span><span style="color:#4f9d08">Antialiasing</span><span style="color:#ffffff">,</span> <span style="color:#ffff55">true</span><span style="color:#ffffff">);</span><span style="color:#ffffff">
    painter</span><span style="color:#ffffff">-</span><span style="color:#ffffff">></span><span style="color:#ffffff">drawPie</span><span style="color:#ffffff">(</span><span style="color:#ffffff">boundingRect</span><span style="color:#ffffff">()</span><span style="color:#ffffff">.</span><span style="color:#ffffff">adjusted</span><span style="color:#ffffff">(</span><span style="color:#ff55ff">1</span><span style="color:#ffffff">,</span> <span style="color:#ff55ff">1</span><span style="color:#ffffff">,</span> <span style="color:#ffffff">-</span><span style="color:#ff55ff">1</span><span style="color:#ffffff">,</span> <span style="color:#ffffff">-</span><span style="color:#ff55ff">1</span><span style="color:#ffffff">)</span><span style="color:#ffffff">,</span> <span style="color:#ff55ff">90</span> <span style="color:#ffffff">*</span> <span style="color:#ff55ff">16</span><span style="color:#ffffff">,</span> <span style="color:#ff55ff">290</span> <span style="color:#ffffff">*</span> <span style="color:#ff55ff">16</span><span style="color:#ffffff">);</span>
<span style="color:#ffffff">}</span></span></span></span></span>

QML 用法

现在我们已经定义了类型,我们将从 QML 使用它。该文件创建一个项目,并使用标准 QML 项目显示饼图的详细信息:PieChartapp.qmlPieChart

<span style="color:#404244"><span style="background-color:#ffffff"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#ffff55">import</span> <span style="color:#4f9d08">Charts</span>
<span style="color:#ffff55">import</span> <span style="color:#4f9d08">QtQuick</span>

<a data-cke-saved-href="https://doc.qt.io/qt-6/qml-qtquick-item.html" href="https://doc.qt.io/qt-6/qml-qtquick-item.html"><span style="color:#21be2b">Item</span></a> <span style="color:#ffffff">{</span>
    <span style="color:#ffffff">width</span><span style="color:#ffffff">:</span> <span style="color:#ff55ff">300</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">height</span><span style="color:#ffffff">:</span> <span style="color:#ff55ff">200</span>

    <span style="color:#4f9d08">PieChart</span> <span style="color:#ffffff">{</span>
        <span style="color:#ffffff">id</span><span style="color:#ffffff">:</span> <span style="color:#ffffff">aPieChart</span>
        <span style="color:#ffffff">anchors</span><span style="color:#ffffff">.</span><span style="color:#ffffff">centerIn</span><span style="color:#ffffff">:</span> <span style="color:#ffffff">parent</span>
        <span style="color:#ffffff">width</span><span style="color:#ffffff">:</span> <span style="color:#ff55ff">100</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">height</span><span style="color:#ffffff">:</span> <span style="color:#ff55ff">100</span>
        <span style="color:#ffffff">name</span><span style="color:#ffffff">:</span> <span style="color:#aaaaaa">"A simple pie chart"</span>
        <span style="color:#ffffff">color</span><span style="color:#ffffff">:</span> <span style="color:#aaaaaa">"red"</span>
    <span style="color:#ffffff">}</span>

    <a data-cke-saved-href="https://doc.qt.io/qt-6/qml-qtquick-text.html" href="https://doc.qt.io/qt-6/qml-qtquick-text.html"><span style="color:#21be2b">Text</span></a> <span style="color:#ffffff">{</span>
        <span style="color:#ffffff">anchors</span> <span style="color:#ffffff">{</span> <span style="color:#ffffff">bottom</span><span style="color:#ffffff">:</span> <span style="color:#ffffff">parent</span><span style="color:#ffffff">.</span><span style="color:#ffffff">bottom</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">horizontalCenter</span><span style="color:#ffffff">:</span> <span style="color:#ffffff">parent</span><span style="color:#ffffff">.</span><span style="color:#ffffff">horizontalCenter</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">bottomMargin</span><span style="color:#ffffff">:</span> <span style="color:#ff55ff">20</span> <span style="color:#ffffff">}</span>
        <span style="color:#ffffff">text</span><span style="color:#ffffff">:</span> <span style="color:#ffffff">aPieChart</span><span style="color:#ffffff">.</span><span style="color:#ffffff">name</span>
    <span style="color:#ffffff">}</span>
<span style="color:#ffffff">}</span></span></span></span></span>

请注意,尽管颜色在 QML 中指定为字符串,但它会自动转换为 PieChart 属性的对象。为各种其他 .例如,像“640x480”这样的字符串可以自动转换为值。color

我们还将创建一个使用 运行和显示 的 C++ 应用程序。app.qml

这是应用程序:main.cpp

<span style="color:#404244"><span style="background-color:#ffffff"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#55ffff">#include</span> <span style="color:#aaaaaa">"piechart.h"</span>
<span style="color:#55ffff">#include</span> <span style="color:#ffffff"><</span><span style="color:#4f9d08">QtQuick</span><span style="color:#ffffff">/</span><span style="color:#4f9d08">QQuickView</span><span style="color:#ffffff">></span>
<span style="color:#55ffff">#include</span> <span style="color:#ffffff"><</span><span style="color:#4f9d08">QGuiApplication</span><span style="color:#ffffff">></span>

<span style="color:#ffff55">int</span><span style="color:#ffffff"> main</span><span style="color:#ffffff">(</span><span style="color:#ffff55">int</span><span style="color:#ffffff"> argc</span><span style="color:#ffffff">,</span> <span style="color:#ffff55">char</span> <span style="color:#ffffff">*</span><span style="color:#ffffff">argv</span><span style="color:#ffffff">[</span><span style="color:#ffffff">]</span><span style="color:#ffffff">)</span>
<span style="color:#ffffff">{</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qguiapplication.html" href="https://doc.qt.io/qt-6/qguiapplication.html"><span style="color:#21be2b">QGuiApplication</span></a><span style="color:#ffffff"> app</span><span style="color:#ffffff">(</span><span style="color:#ffffff">argc</span><span style="color:#ffffff">,</span><span style="color:#ffffff"> argv</span><span style="color:#ffffff">);</span>

    <a data-cke-saved-href="https://doc.qt.io/qt-6/qquickview.html" href="https://doc.qt.io/qt-6/qquickview.html"><span style="color:#21be2b">QQuickView</span></a><span style="color:#ffffff"> view</span><span style="color:#ffffff">;</span><span style="color:#ffffff">
    view</span><span style="color:#ffffff">.</span><span style="color:#ffffff">setResizeMode</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qquickview.html" href="https://doc.qt.io/qt-6/qquickview.html"><span style="color:#21be2b">QQuickView</span></a><span style="color:#ffffff">::</span><span style="color:#4f9d08">SizeRootObjectToView</span><span style="color:#ffffff">);</span><span style="color:#ffffff">
    view</span><span style="color:#ffffff">.</span><span style="color:#ffffff">setSource</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亭台六七座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值