qtwidget嵌入qml

我在学习qml的过程中想到了一个问题,qtwidget界面如何嵌入qml组件。接下来时一步步实现

我们和往常一样先创建一个mainwindow程序,在模块中加入

 QT += quickwidgets

因为我们需要用到

#include<QtQuickWidgets/QQuickWidget>

这个组件把qml包装起来,这个组件的属性和函数可以在qtcreater中搜到看看,接下来就是和往常用其他组件一样创建组件,设置组件属性把他和qml程序关联起来,源码如下

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QtQuickWidgets/QQuickWidget>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 创建 QQuickWidget 容器
    QQuickWidget *qmlWidget = new QQuickWidget(this);
    qmlWidget->setSource(QUrl("qrc:/main.qml"));  // 加载 QML 文件
    qmlWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);  // QML 尺寸随容器变化

    // 设置为主窗口中心组件
    setCentralWidget(qmlWidget);
    resize(800, 600);  // 初始窗口大小
}

MainWindow::~MainWindow()
{
    delete ui;
}

 创建一个资源文件,创建一个测试用的qml程序放进去保存文件结构如下:

qml程序内容:

import QtQuick
import QtQuick.Controls

Rectangle {
    color: "lightblue"
    border.color: "navy"
    border.width: 2
    radius: 10

    Text {
        text: "嵌入的 QML 组件"
        anchors.centerIn: parent
        font.pixelSize: 24
    }
}

 正常运行效果如下:

 如果运行报错

D:\Qttest\qmltest\mainwindow.cpp:11: error: undefined reference to `__imp__ZN12QQuickWidgetC1EP7QWidget'

这个错误是检测到库连接的问题,检查下1.qt有没有安装qtquick模块2..pro文件有没有加上模块并保存3.还是解决不了的话找到项目根目录把build文件删了重新编译基本能解决

如果不想把他放到中心区域就在ui界面拖一个frame什么的组件布好局,用addwidget把qmlwidget加进去就行了

若需 QQuickWidget 背景透明,添加:

qmlWidget->setClearColor(Qt::transparent);
qmlWidget->setAttribute(Qt::WA_AlwaysStackOnTop); // 防止被其他 Widget 遮挡

 

QML 内容适配
在 QML 根组件中启用锚点填充,避免黑边:

// main.qml
Rectangle {
    anchors.fill: parent // 填充 QQuickWidget
    // ...其他内容
}

 

性能优化
嵌入多个 QML 组件时,建议每个 QQuickWidget 独立缓存:

qmlWidget->setGraphicsDevice(QQuickWindow::PersistentGLContext);

 

### Qt WidgetQML 的关系 Qt Widget 是基于 C++ 实现的传统 GUI 开发框架,而 QML 则是一种声明式的脚本语言,主要用于开发现代化、动态的用户界面。两者都属于 Qt 框架的一部分,但在设计理念和技术实现上有显著的区别。 #### 关系概述 尽管它们的设计目标不同,但 Qt 提供了多种机制让 WidgetQML 能够无缝协作。例如,`QWidget::createWindowContainer()` 可以将 `QQuickView` 嵌入到传统的 Widget 应用程序中[^1];同时,`QQuickWidget` 类允许在一个 Widget 容器中嵌套 QML 用户界面[^3]。 --- ### Qt WidgetQML 的主要区别 | **特性** | **Qt Widget** | **QML** | |---------------------|--------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------| | **编程模型** | 面向对象的 C++ 编程 | 声明式脚本语言 | | **灵活性** | 较低,适合静态布局 | 极高,支持动画、过渡效果和复杂交互 | | **性能表现** | 更高效于复杂的传统桌面应用 | 渲染效率较低,尤其在处理大量控件时 | | **学习曲线** | 学习成本较高,需掌握 C++ | 学习成本相对较低,易于快速上手 | | **适用场景** | 经典桌面应用程序 | 移动端应用、现代触摸屏设备以及需要高度定制化的图形界面 | --- ### 如何在 Qt使用 WidgetQML 以下是几种常见的组合方式: #### 1. 使用 `QQuickWidget` 将 QML 嵌入Widget 中 这种方式适用于希望保留大部分现有 Widget 界面的同时引入部分 QML 功能的情况。代码如下所示: ```cpp #include <QApplication> #include <QQuickWidget> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget window; QVBoxLayout layout(&window); QQuickWidget *quickWidget = new QQuickWidget(); quickWidget->setSource(QUrl::fromLocalFile("myqmlfile.qml")); layout.addWidget(quickWidget); window.show(); return app.exec(); } ``` 此方法利用了 `QQuickWidget` 控件来承载 QML 文件的内容[^4]。 #### 2. 使用 `QWidget::createWindowContainer` 将 QML 嵌入Widget 中 当需要更灵活地控制 QML 的显示区域时,可以采用这种方法。具体实现如下: ```cpp #include <QApplication> #include <QMainWindow> #include <QQuickView> int main(int argc, char *argv[]) { QApplication app(argc, argv); QMainWindow mainWindow; QQuickView view; view.setSource(QUrl::fromLocalFile("myqmlfile.qml")); QWidget *container = QWidget::createWindowContainer(&view, &mainWindow); mainWindow.setCentralWidget(container); mainWindow.resize(800, 600); mainWindow.show(); return app.exec(); } ``` 这种技术通过创建窗口容器的方式实现了两者的集成[^1]。 #### 3. 加载 QML 并隐藏 Widget 主界面 对于完全由 QML 构建的应用程序,可以选择仅加载 QML 文件而不展示任何 Widget 界面。示例代码如下: ```cpp #include <QApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/uiQml.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); } ``` 该方案展示了如何借助 `QQmlApplicationEngine` 来运行纯 QML 应用程序[^2]。 --- ### 数据交互与注意事项 无论选择哪种集成方式,在实际开发过程中都需要关注以下几个方面: - **数据传递**: 可以通过绑定属性 (`QObject`) 或信号槽机制完成跨组件通信。 - **性能调优**: 如果混合使用两种渲染引擎,则需要注意潜在的性能瓶颈。 - **资源释放**: 正确销毁所有关联的对象以防发生内存泄露。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值