当前位置:   article > 正文

将 QML 与 Qt Widgets 相结合_qml+qwideget

qml+qwideget

作者: 一去、二三里
个人微信号: iwaleon
微信公众号: 高效程序员

在使用 Qt Widgets 时,经常要实现一些比较炫酷的效果(例如:滑动、翻页),这时选择 QML 会显得非常简单。

那么,问题来了:

  • 能不能将 QML 和 Qt Widgets 结合在一起使用?
  • 如果能,都有什么方式?
  • QML 和 Qt Widgets 之间又该如何交互?

一个简单的 QML

创建了一个简单的 QML 文件,用于显示一个绿色的矩形,其中包含一个文本。为了说明 QML 与 Qt Widgets 的交互,在矩形中添加了两个信号:

import QtQuick 2.1

Rectangle {
    id: root
    color: "green"
    width: 200
    height: 200

    // 发送给 Qt Widgets 的信号
    signal qmlSignal
    // 从 Qt Widgets 接收到的信号
    signal cSignal

    Text {
        id: myText
        text: "Click me"
        font.pointSize: 14
        anchors.centerIn: parent
    }

    MouseArea {
        anchors.fill: parent
        onClicked: qmlSignal()
    }

    // 信号处理程序(处理从 Qt Widgets 接收到的信号)
    onCSignal: {
        root.color = "blue"
        myText.text = "Call the qml signal handler"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

如果需要,可以将像往常一样使用 qmlscene 来运行。

加载和显示 QML

要加载和显示 QML,可以使用以下两种方式:

  • QQuickWidget
  • QQuickView

无论使用哪种方式,一旦主源文件的 URL 被指定,都将自动加载和显示 QML 视图。

注意:QML运行环境 中,还介绍了另一种方式 - QQmlEngine + QQmlComponent,但是这种方式不能以 view 的形式加载。

使用 QQuickWidget

QQuickWidget 是 Qt 5.3 中提供的一个类,继承自 QWidget,它是 QQuickWindow 一个很方便的包装器,用于显示 Qt Quick 用户界面。

使用方式:

QQuickWidget *view = new QQuickWidget;
view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
view->show();
  • 1
  • 2
  • 3

使用 QQuickView

QQuickView 是 Qt 5.0 中提供的一个类,继承自 QQuickWindow(继承自 QWindow),用于显示 Qt Quick 用户界面。

使用方式:

QQuickView *view = new QQuickView;
view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
view->show();
  • 1
  • 2
  • 3

可以看到,两者的使用方式几乎没什么区别。但是,QQuickWidget 基于 QWidget,而 QQuickView 基于 QWindow,所以需要将其转换为 QWidget,才能与 Qt Widgets 相结合。

这样,就需要再引入一个函数:

[static] QWidget *QWidget::createWindowContainer(QWindow *window, QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags())

该函数用于创建一个 QWidget,可以将 window 嵌入到基于 QWidget 的应用程序中。

所以,要将 QQuickView 转为 QWidget,可以使用下述方式:

QQuickView *view = new QQuickView();
QWidget *widget = QWidget::createWindowContainer(view, this);
view->setSource(QUrl("qrc:/main.qml"));
  • 1
  • 2
  • 3

将 QML 与 Qt Widgets 相结合

当一切准备就绪,就可以将 QML 与 Qt Widgets 完美结合在一起了:

最终效果:

QML 与 Qt Widgets

源码如下:

#include "widget.h"
#include <QQuickView>
#include <QVBoxLayout>
#include <QQuickWidget>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    resize(300, 300);

    // 方式一
    // QQuickView *pView = new QQuickView();
    // QWidget *pWidget = QWidget::createWindowContainer(pView, this);
    // pView->setResizeMode(QQuickView::SizeRootObjectToView);
    // pView->setSource(QUrl("qrc:/main.qml"));

    // 方式二
    QQuickWidget *pWidget = new QQuickWidget();
    pWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    pWidget->setSource(QUrl("qrc:/main.qml"));

    m_pButton = new QPushButton(this);
    m_pButton->setText("Qt Widgets...");

    QVBoxLayout *pLayout = new QVBoxLayout();
    pLayout->addWidget(pWidget);
    pLayout->addWidget(m_pButton);
    pLayout->setSpacing(10);
    pLayout->setContentsMargins(10, 10, 10, 10);
    setLayout(pLayout);

    // QML 与 Qt Widgets 通信
    // QObject *pRoot = (QObject*)pView->rootObject();
    QObject *pRoot = (QObject*)pWidget->rootObject();
    if (pRoot != NULL) {
        connect(pRoot, SIGNAL(qmlSignal()), this, SLOT(receiveFromQml()));
        connect(m_pButton, SIGNAL(clicked(bool)), pRoot, SIGNAL(cSignal()));
    }
}

void Widget::receiveFromQml()
{
    m_pButton->setText("Call the C++ slot");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

结合之后,少不了通信,这里采用信号槽的方式,通过 QML 的根元素 root 来发送和接收信号。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/831233
推荐阅读
相关标签
  

闽ICP备14008679号