QML与C++交互详解(二)

QML与C++交互详解(二)

QML中连接C++ 的信号

  • 话不多说:
/**
 * @file BaseQmlWidget.h
 * @author shijiaobing (503876187@qq.com)
 * @brief   QQuickWidget loaded Qml File  to embed C++ QWidget
 * @version 0.1
 * @date 2022-09-21
 *
 * @copyright Copyright (c) 2022
 *
 */
#ifndef _BASE_QML_WIDGET_H_
#define _BASE_QML_WIDGET_H_
#include <QQuickWidget>
#include "Ui_Export_Dll.h"
#include <QQuickItem>

class UIDLLEXPORT BaseQmlWidget : public QWidget
{
    Q_OBJECT
public:
    /**
     * @brief Construct a new Base Qml Widget object
     *
     * @param url
     * @param parent
     */
    BaseQmlWidget(const QUrl &url, QWidget *parent = nullptr);
    /**
     * @brief Destroy the Base Qml Widget object
     *
     */
    virtual ~BaseQmlWidget();
    /**
     * @brief get QQuickWidget
     *
     * @return QQuickWidget*
     */
    QQuickWidget *quickWidget();

protected:
    /**
     * @brief Create a Qml Widget object
     *
     */
    virtual void createQmlWidget();

    /**
     * @brief init layout
     *
     */
    virtual void initLayout();
    /**
     * @brief Set the Context Property object
     *
     */
    virtual void setContextProperty() = 0;
    /**
     * @brief init baseQmlWidget
     *
     */
    virtual void initBaseQmlWidget();
    QQuickWidget *m_item = nullptr;
    QUrl m_url;
};
#endif

#include "BaseQmlWidget.h"
#include <QUrl>
#include <QWidget>
#include <QHBoxLayout>
#include "FileHelper.h"
BaseQmlWidget::BaseQmlWidget(const QUrl &url, QWidget *parent)
    :QWidget(parent),m_url(url)
{
    
}
BaseQmlWidget::~BaseQmlWidget() {

}
void BaseQmlWidget::initBaseQmlWidget()
{
    createQmlWidget();

    setContextProperty();

    initLayout();
}

QQuickWidget* BaseQmlWidget::quickWidget() {
    return m_item;
}


void BaseQmlWidget::createQmlWidget(){
   
    m_item = new QQuickWidget();
    m_item->quickWindow()->setPersistentOpenGLContext(true);
    m_item->quickWindow()->setClearBeforeRendering(true);
    m_item->setWindowFlag(Qt::FramelessWindowHint);
    m_item->setClearColor(QColor(Qt::transparent));
    m_item->setResizeMode(QQuickWidget::SizeRootObjectToView);
    m_item->setParent(parentWidget());
}


void BaseQmlWidget::initLayout() {
    m_item->setSource(m_url);
    QHBoxLayout* layout = new QHBoxLayout();
    layout->setSpacing(0);
    layout->setMargin(0);
    layout->addWidget(reinterpret_cast<QWidget*>(m_item));
    this->setLayout(layout);
}

/**
 * @file TitleBar.h
 * @author shijiaobing (503876187@qq.com)
 * @brief 标题栏
 * @version 0.1
 * @date 2022-09-21
 *
 * @copyright Copyright (c) 2022
 *
 */
#ifndef _TITLE_BAR_H_
#define _TITLE_BAR_H_
#include "BaseQmlWidget.h"

class TitleBarData;
class UIDLLEXPORT TitleBar : public BaseQmlWidget
{
    Q_OBJECT
    Q_PROPERTY(bool maxWindowFlag READ maxWindowFlag WRITE setMaxWindowFlag NOTIFY maxWindowFlagChanged)
public:
    /**
     * @brief Construct a new Title Bar object
     *
     * @param url
     * @param parent
     */
    explicit TitleBar(const QUrl &url, QWidget *parent = nullptr);
    ~TitleBar();
    /**
     * @brief 获取qml对象
     *
     * @return QList<QQuickItem *>
     */
    QList<QQuickItem *> items();
    /**
     * @brief qml调用方法
     *
     * @return bool
     */
    Q_INVOKABLE bool maxWindowFlag() const;
    /**
     * @brief Set the Max Window Flag object
     *
     * @param flag
     */
    void setMaxWindowFlag(bool flag);
signals:
    /**
     * @brief 最大化通知界面
     *
     * @param flag
     */
    void maxWindowFlagChanged(bool flag);

protected:
    /**
     * @brief Set the Context Property object
     *
     */
    virtual void setContextProperty() override;

private:
    void initConnect();
    bool m_maxWindowFlag = false;
    QList<QQuickItem *> m_items;
};

#endif

#include "TitleBar.h"
#include <QQmlContext>
#include <QQmlEngine>

TitleBar::TitleBar(const QUrl &url, QWidget *parent)
    : BaseQmlWidget(url, parent)
{
    initBaseQmlWidget();
    initConnect();
}

TitleBar::~TitleBar()
{

}

QList<QQuickItem*> TitleBar::items()
{
    return m_items;
}
void TitleBar::setContextProperty() {
    m_item->rootContext()->setContextProperty("titleBarData",this);

   
}
void TitleBar::initConnect()
{
    auto items = m_item->rootObject()->childItems();
    foreach(auto item, items) {
        if (item->objectName() == "row") {
            m_items.append(item);
        }
    }
}

void TitleBar::setMaxWindowFlag(bool flag) {
    if (m_maxWindowFlag != flag) {
        m_maxWindowFlag = flag;
        emit  maxWindowFlagChanged(m_maxWindowFlag);
    }
}


bool TitleBar::maxWindowFlag()const {

    return m_maxWindowFlag;
}

import QtQuick 2.14
import QtQml 2.14
import "./Controls"
Rectangle {
    id: root
    property bool isMaxWindow: false
    objectName: "TitleBar"
    signal closeBtnClick()
    signal maxBtnClick()
    signal minBtnClick()
    signal restoreBtnClick()
    signal menuBtnClick()
    signal registerBtnClick()
    signal buyBtnClick()

    radius:root.isMaxWindow?0:10
    color: "#2E2F30"

    Text {
        id: product_name_text
        anchors.verticalCenter: parent.verticalCenter
        anchors.left: parent.left
        anchors.leftMargin: 12
        height:root.height
        verticalAlignment: Text.AlignVCenter
        font.pixelSize: 14
        color: "#FFFFFF"
        text: "123123213123"
    }

    Row {
        spacing: 12
        anchors.right: parent.right
        anchors.rightMargin: 12
        anchors.verticalCenter: parent.verticalCenter
        objectName: "row"
       // verticalAlignment:Row.AlignVCenter
        TitleButton {
            id: registerBtn

            objectName: "registerBtn"
            imageUrlNomal: "qrc:/image/registerBtn_nomal.png"
            imageUrlHover: "qrc:/image/registerBtn_hover.png"
            imageUrlPressed: "qrc:/image/registerBtn_pressed.png"
            onBtnClick: {
                registerBtnClick()
            }
        }

        TitleButton {
            id: buyBtn
            objectName: "buyBtn"
            imageUrlNomal: "qrc:/image/buyBtn_nomal.png"
            imageUrlHover: "qrc:/image/buyBtn_hover.png"
            imageUrlPressed: "qrc:/image/buyBtn_pressed.png"
            onBtnClick: {
                buyBtnClick()
            }
        }

        TitleButton {
            id: menuBtn
            objectName: "menuBtn"
            imageUrlNomal: "qrc:/image/menuBtn_nomal.png"
            imageUrlHover: "qrc:/image/menuBtn_hover.png"
            imageUrlPressed: "qrc:/image/menuBtn_pressed.png"
            onBtnClick: {
                menuBtnClick()
            }
        }

        TitleButton {
            id: minBtn
            objectName: "minBtn"
            imageUrlNomal: "qrc:/image/minBtn_nomal.png"
            imageUrlHover: "qrc:/image/minBtn_hover.png"
            imageUrlPressed: "qrc:/image/minBtn_pressed.png"
            onBtnClick: {
                minBtnClick()
            }
        }

        TitleButton {
            id: maxBtn
            objectName: "maxBtn"
            imageUrlNomal: root.isMaxWindow ? "qrc:/image/restoreBtn_nomal.png" : "qrc:/image/maxBtn_nomal.png"
            imageUrlHover: root.isMaxWindow ? "qrc:/image/restoreBtn_hover.png" : "qrc:/image/maxBtn_hover.png"
            imageUrlPressed: root.isMaxWindow ? "qrc:/image/restoreBtn_pressed.png" : "qrc:/image/maxBtn_pressed.png"
            onBtnClick: {
                console.log("maxBtn"+titleBarData.maxWindowFlag)
                if (root.isMaxWindow)
                    restoreBtnClick()
                else
                    maxBtnClick()
            }
        }

        TitleButton {
            id: closeBtn
            objectName: "closeBtn"
            imageUrlNomal: "qrc:/image/closeBtn_nomal.png"
            imageUrlHover: "qrc:/image/closeBtn_hover.png"
            imageUrlPressed: "qrc:/image/closeBtn_pressed.png"
            onBtnClick: {
                
                closeBtnClick()
            }
        }

    }

    Rectangle {
        id: background_left_bottom_rect

        width: 10
        height: 10
        anchors.left: parent.left
        anchors.bottom: parent.bottom
        color: "#2E2F30"
    }

    Rectangle {
        id: background_right_bottom_rect

        width: 10
        height: 10
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        color: "#2E2F30"
    }
    Connections{
        target: titleBarData
        function onMaxWindowFlagChanged(value){
            console.log("onMaxWindowFlagChanged"+value)
            root.isMaxWindow=value
        }
    }
}

void MainWindow::initConnect() {

    connect(m_helper, &FramelessHelper::maximizedChanged, m_titileBar, &TitleBar::setMaxWindowFlag);

    connect(m_titileBar->quickWidget()->rootObject(), SIGNAL(buyBtnClick()), this, SLOT(onBuyBtnClicked()));

    connect(m_titileBar->quickWidget()->rootObject(), SIGNAL(menuBtnClick()), this, SLOT(onMenuBtnClicked()));
    
    connect(m_titileBar->quickWidget()->rootObject(), SIGNAL(registerBtnClick()), this, SLOT(onRegisterBtnClicked()));

    connect(m_titileBar->quickWidget()->rootObject(), SIGNAL(minBtnClick()), m_helper, SLOT(triggerMinimizeButtonAction()));

    connect(m_titileBar->quickWidget()->rootObject(), SIGNAL(maxBtnClick()), m_helper, SLOT(triggerMaximizeButtonAction()));

    connect(m_titileBar->quickWidget()->rootObject(), SIGNAL(closeBtnClick()), m_helper, SLOT(triggerCloseButtonAction()));

    connect(m_titileBar->quickWidget()->rootObject(), SIGNAL(restoreBtnClick()), m_helper, SLOT(triggerMaximizeButtonAction()));

}

可以看出C++ 获取qml嵌入的quickwidget中的rootObject()方法获取到QQuickItem对象为qml 中的root,
此时由于qml 是支持qt 的原对象系统的,qml 文件在经过moc 编译后会含有信号函数,此时可以直接连接qml 中得信号。而C++ 中的对象也是同样的,这样我们就可以实现qml 与C++ 的通信啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值