C++生成QML代码与QML里面集成QWidget
目录
1 QML代码生成
2 注册机制的含义
3 QWidgetInQml QML里面集成widget
4 QML_OSR_EXP 将Qt Widgets嵌入到QML界面中的一种示范
5 参考链接
1 QML代码生成
/******************************************************************************* QSkinny - Copyright (C) 2016 Uwe Rathmann* This file may be used under the terms of the 3-clause BSD License*****************************************************************************/#pragma once#include "GridAccessor.h"
#include <QQuickWidget>class QGraphicsGridLayout;class GridQuick : public QQuickWidget, public GridAccessor
{public:GridQuick( QWidget* parent = nullptr );~GridQuick() override;void insert( const QByteArray& colorName,int row, int column, int rowSpan, int columnSpan ) override;void setSpacing( Qt::Orientations, int spacing ) override;void setStretchFactor( int pos, Qt::Orientation, int stretch ) override;void setSizeHint( int pos, Qt::Orientation, Qt::SizeHint, int hint ) override;void setSizeHintAt( int index, Qt::Orientation, Qt::SizeHint, int hint ) override;void setSizePolicyAt( int index, Qt::Orientation, int policy ) override;void setAlignmentAt( int index, Qt::Alignment ) override;void setRetainSizeWhenHiddenAt( int index, bool on ) override;void setVisibleAt( int index, bool on ) override;QSize preferredSize() const override;protected:void resizeEvent( QResizeEvent* ) override;private:QQuickItem* m_grid;
};
/******************************************************************************* QSkinny - Copyright (C) 2016 Uwe Rathmann* This file may be used under the terms of the 3-clause BSD License*****************************************************************************/#include "GridQuick.h"
#include <QQuickItem>
#include <QtQml>
#include <QDebug>static QQuickItem* createQml( const char* qmlCode )
{QQmlEngine engine( nullptr );QQmlComponent component( &engine );component.setData( qmlCode, QUrl() );if ( component.status() != QQmlComponent::Ready )qWarning() << component.errorString();return qobject_cast< QQuickItem* >( component.create() );
}static QQuickItem* itemAt( const QQuickItem* grid, int index )
{const auto children = grid->childItems();if ( ( index >= 0 ) && ( index < children.count() ) )return children.at( index );return nullptr;
}static QObject* attachedProperties( const QQuickItem* item )
{for ( auto child : item->children() ){if ( child->inherits( "QQuickLayoutAttached" ) )return child;}return nullptr;
}static QObject* attachedPropertiesAt( const QQuickItem* grid, int index )
{if ( auto item = itemAt( grid, index ) )return attachedProperties( item );return nullptr;
}GridQuick::GridQuick( QWidget* parent ): QQuickWidget( parent )
{setContentsMargins( QMargins() );setResizeMode( QQuickWidget::SizeRootObjectToView );auto contentItem =createQml( "import QtQuick 2.0\nimport QtQuick.Layouts 1.1\nItem { GridLayout {} }" );setContent( QUrl(), nullptr, contentItem );m_grid = contentItem->childItems().constFirst();m_grid->setProperty( "rowSpacing", 5 );m_grid->setProperty( "columnSpacing", 5 );
}GridQuick::~GridQuick()
{
}void GridQuick::insert( const QByteArray& colorName,int row, int column, int rowSpan, int columnSpan )
{/*We need to create a temporary layout in QML, so that theobject for the attachedProperties is created early*/auto layout = createQml( "import QtQuick 2.0\nimport QtQuick.Layouts 1.15\nGridLayout { Rectangle {} }" );auto rectangle = layout->childItems().constFirst();rectangle->setParent( nullptr );delete layout;rectangle->setParent( m_grid );rectangle->setParentItem( m_grid );rectangle->setImplicitWidth( 50 );rectangle->setImplicitHeight( 50 );rectangle->setProperty( "color", QColor( colorName.constData() ) );if ( auto props = attachedProperties( rectangle ) ){props->setProperty( "row", row );props->setProperty( "column", column );props->setProperty( "rowSpan", rowSpan );props->setProperty( "columnSpan", columnSpan );props->setProperty( "fillWidth", true );props->setProperty( "fillHeight", true );}
}void GridQuick::setSpacing( Qt::Orientations orientations, int spacing )
{if ( orientations & Qt::Vertical )m_grid->setProperty( "rowSpacing", spacing );if ( orientations & Qt::Horizontal )m_grid->setProperty( "columnSpacing", spacing );
}void GridQuick::setSizeHint( int, Qt::Orientation, Qt::SizeHint, int )
{qWarning() << "setSizeHint is not supported by Quick Layouts.";
}void GridQuick::setStretchFactor( int, Qt::Orientation, int )
{qWarning() << "setStretchFactor is not supported by Quick Layouts.";
}void GridQuick::setSizeHintAt( int index, Qt::Orientation orientation,Qt::SizeHint which, int hint )
{if ( auto props = attachedPropertiesAt( m_grid, index ) ){const qreal size = hint;switch( static_cast< int >( which ) ){case Qt::MinimumSize:{if ( orientation == Qt::Horizontal )props->setProperty( "minimumWidth", size );elseprops->setProperty( "minimumHeight", size );break;}case Qt::PreferredSize:{if ( orientation == Qt::Horizontal )props->setProperty( "preferredWidth", size );elseprops->setProperty( "preferredHeight", size );break;}case Qt::MaximumSize:{if ( orientation == Qt::Horizontal )props->setProperty( "maximumWidth", size );elseprops->setProperty( "maximumHeight", size );break;}}}
}void GridQuick::setSizePolicyAt(int index, Qt::Orientation orientation, int policy )
{const auto qPolicy = static_cast< QSizePolicy::Policy >( policy & 0xF );#if 0const bool isConstrained = policy & ( 1 << 4 );
#endifconst bool doFill = ( qPolicy & QSizePolicy::GrowFlag )|| ( qPolicy & QSizePolicy::ExpandFlag );if ( auto props = attachedPropertiesAt( m_grid, index ) ){if ( orientation == Qt::Horizontal )props->setProperty( "fillWidth", doFill );elseprops->setProperty( "fillHeight", doFill );}
}void GridQuick::setAlignmentAt( int index, Qt::Alignment alignment )
{if ( auto props = attachedPropertiesAt( m_grid, index ) )props->setProperty( "alignment", QVariant::fromValue( alignment ) );
}void GridQuick::setRetainSizeWhenHiddenAt( int, bool )
{qWarning() << "setRetainSizeWhenHidden is not supported by Quick Layouts.";
}void GridQuick::setVisibleAt( int index, bool on )
{if ( auto item = itemAt( m_grid, index ) )item->setVisible( on );
}static const qreal margin = 10.0;QSize GridQuick::preferredSize() const
{return QSize(m_grid->implicitWidth() + 2 * margin,m_grid->implicitHeight() + 2 * margin );
}void GridQuick::resizeEvent( QResizeEvent* event )
{QQuickWidget::resizeEvent( event );m_grid->setX( margin );m_grid->setY( margin );m_grid->setWidth( width() - 2 * margin );m_grid->setHeight( height() - 2 * margin );
}
2 注册机制的含义
#include "QskQuickItem.h"
#include "QskQuickItemPrivate.h"
#include "QskQuick.h"
#include "QskEvent.h"
#include "QskSetup.h"
#include "QskSkin.h"
#include "QskDirtyItemFilter.h"#include <qglobalstatic.h>
#include <qquickwindow.h>#if defined( QT_DEBUG )QSK_QT_PRIVATE_BEGIN#if QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 )#ifndef emit#define emit#include <private/qabstractanimation_p.h>#undef emit#endif
#endif#include <private/qquickpositioners_p.h>QSK_QT_PRIVATE_END#endif#include <unordered_set>static inline void qskSendEventTo( QObject* object, QEvent::Type type )
{QEvent event( type );QCoreApplication::sendEvent( object, &event );
}static inline void qskApplyUpdateFlags(QskQuickItem::UpdateFlags flags, QskQuickItem* item )
{auto d = static_cast< QskQuickItemPrivate* >( QskQuickItemPrivate::get( item ) );d->applyUpdateFlags( flags );
}static inline void qskFilterWindow( QQuickWindow* window )
{if ( window == nullptr )return;static QskDirtyItemFilter itemFilter;itemFilter.addWindow( window );
}namespace
{class QskQuickItemRegistry{public:QskQuickItemRegistry(){/*Its faster and saves some memory to have this registry insteadof setting up direct connections between qskSetup and each control*/QObject::connect( qskSetup, &QskSetup::itemUpdateFlagsChanged,qskSetup, [ this ] { updateControlFlags(); } );/*We would also need to send QEvent::StyleChange, whena window has a new skin. TODO ...*/QObject::connect( qskSetup, &QskSetup::skinChanged,qskSetup, [ this ] { updateSkin(); } );}inline void insert( QskQuickItem* item ){m_items.insert( item );}inline void remove( QskQuickItem* item ){m_items.erase( item );}void updateControlFlags(){const auto flags = qskSetup->itemUpdateFlags();for ( auto item : m_items )qskApplyUpdateFlags( flags, item );}void updateSkin(){QEvent event( QEvent::StyleChange );for ( auto item : m_items ){event.setAccepted( true );QCoreApplication::sendEvent( item, &event );}}private:std::unordered_set< QskQuickItem* > m_items;};
}namespace
{/*A helper class to store the released window to be able toput it later into the WindowChange event.*/class QskWindowStore{public:QskWindowStore(): m_refCount( 0 ), m_window( nullptr ){}void setWindow( QQuickWindow* window ){if ( m_window != window ){m_window = window;m_refCount = 0;}if ( m_window )m_refCount++;}QQuickWindow* window(){QQuickWindow* w = m_window;if ( m_window ){if ( --m_refCount == 0 )m_window = nullptr;}return w;}private:int m_refCount;QQuickWindow* m_window;};
}Q_GLOBAL_STATIC( QskQuickItemRegistry, qskRegistry )
Q_GLOBAL_STATIC( QskWindowStore, qskReleasedWindowCounter )QskQuickItem::QskQuickItem( QskQuickItemPrivate& dd, QQuickItem* parent ): QQuickItem( dd, parent )
{setFlag( QQuickItem::ItemHasContents, true );if ( dd.updateFlags & QskQuickItem::DeferredUpdate )qskFilterWindow( window() );qskRegistry->insert( this );
}QskQuickItem::~QskQuickItem()
{/*We set componentComplete to false, so that operationsthat are triggered by detaching the item from its parentcan be aware of the about-to-delete state.*/d_func()->componentComplete = false;if ( qskRegistry )qskRegistry->remove( this );
}const char* QskQuickItem::className() const
{return metaObject()->className();
}void QskQuickItem::classBegin()
{Inherited::classBegin();
}
3 QWidgetInQml QML里面集成widget
bool QMLInteract::initUI()
{m_engin.rootContext()->setContextProperty("QMLInteractObj", this);m_engin.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));if (m_engin.rootObjects().isEmpty()){return false;}QObject* obj = m_engin.rootObjects().at(0);basewindowobj.setWndBaseInfo(obj);basewindowobj.setWndSplitType();m_engin.load(QUrl(QStringLiteral("qrc:/qml/CalibTwoPage.qml")));QObject* obj1 = m_engin.rootObjects().at(1);return true;
}void BaseWindowContainer::setWndBaseInfo(QObject* obj)
{QWindow * mainWindow = qobject_cast<QWindow*>(obj);if (obj){WId proc2Window_HWND = mainWindow->winId();m_widget->setProperty("_q_embedded_native_parent_handle", QVariant(proc2Window_HWND));m_widget->setWindowFlags(Qt::Widget|Qt::FramelessWindowHint);m_widget->winId();m_widget->setStyleSheet("background-color: rgb(46,138,201)");m_widget->windowHandle()->setParent(mainWindow);m_delegateObj = obj;}
}
4 QML_OSR_EXP 将Qt Widgets嵌入到QML界面中的一种示范
bool WidgetOSRItem::sendEventToOSRWidget(QEvent *e)
{QWindow* wHandle = mOSRWidget->windowHandle();bool res = false;if(wHandle){res = qApp->sendEvent(wHandle, e);}return res;
}
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))bool WidgetOSRItem::eventFilter(QObject *obj, QEvent *e)
{QWindow* pw = (QWindow*)(window());bool res = QQuickPaintedItem::eventFilter(obj, e);if(obj == mOSRWidget){switch(e->type()){case QEvent::Paint: //当OsrWidget paint的时候也触发自己paint{QPaintEvent* pe = (QPaintEvent*)e;this->update(pe->rect());}break;}}else if(obj == pw){//* 如果是鼠标等(有鼠标坐标信息的事件。)的话我们得计算一下偏移量并修正一下,这里就只处理QMouseEvent和QWheelEvent作为示例//* 如果有其他类似的也需要修正,不然可能坐标偏移switch(e->type()){case QEvent::MouseButtonDblClick :case QEvent::MouseButtonPress :case QEvent::MouseButtonRelease :case QEvent::MouseMove :case QEvent::MouseTrackingChange :case QEvent::Move :{QMouseEvent *me = (QMouseEvent*)e;QEvent::Type type = me->type();QPointF localPosF(QPointF(0,0));
// QPointF localPosF = me->position();Qt::MouseButton mouseButton = me->button();Qt::MouseButtons mouseButtons = me->buttons();Qt::KeyboardModifiers modifiers = me->modifiers();//修正一下localposQPointF offsetF = mapToScene(QPoint(0,0));QPointF diffPosF = localPosF - offsetF;QMouseEvent tme(type, diffPosF, mouseButton, mouseButtons, modifiers);sendEventToOSRWidget(&tme);}break;case QEvent::Wheel:{QWheelEvent *we = (QWheelEvent*)e;QPointF localPosF = we->position();QPointF gloabalPosF = we->globalPosition();QPoint pixelDelta = we->pixelDelta();QPoint angleDelta = we->angleDelta();Qt::MouseButtons mouseButtons = we->buttons();Qt::KeyboardModifiers modifiers = we->modifiers();//修正一下localposQPointF offsetF = mapToScene(QPoint(0,0));QPointF diffPosF = localPosF - offsetF;QWheelEvent twe(diffPosF, gloabalPosF, pixelDelta, angleDelta,mouseButtons, modifiers, Qt::ScrollBegin, false);sendEventToOSRWidget(&twe);}break;default:{sendEventToOSRWidget(e);}break;}}return res;
}void WidgetOSRItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{QQuickPaintedItem::geometryChange(newGeometry, oldGeometry);if(mOSRWidget){mOSRWidget->setGeometry(newGeometry.toRect());}
}#elsebool WidgetOSRItem::eventFilter(QObject *obj, QEvent *e)
{QWindow* pw = (QWindow*)(window());bool res = QQuickPaintedItem::eventFilter(obj, e);if(obj == mOSRWidget){switch(e->type()){case QEvent::Paint: //当OsrWidget paint的时候也触发自己paint{QPaintEvent* pe = (QPaintEvent*)e;this->update(pe->rect());}break;}}else if(obj == pw){//* 如果是鼠标等(有鼠标坐标信息的事件。)的话我们得计算一下偏移量并修正一下,这里就只处理QMouseEvent和QWheelEvent作为示例//* 如果有其他类似的也需要修正,不然可能坐标偏移switch(e->type()){case QEvent::MouseButtonDblClick :case QEvent::MouseButtonPress :case QEvent::MouseButtonRelease :case QEvent::MouseMove :case QEvent::MouseTrackingChange :case QEvent::Move :{QMouseEvent *me = (QMouseEvent*)e;QEvent::Type type = me->type();QPointF localPosF = me->localPos();Qt::MouseButton mouseButton = me->button();Qt::MouseButtons mouseButtons = me->buttons();Qt::KeyboardModifiers modifiers = me->modifiers();//修正一下localposQPointF offsetF = mapToScene(QPoint(0,0));QPointF diffPosF = localPosF - offsetF;QMouseEvent tme(type, diffPosF, mouseButton, mouseButtons, modifiers);sendEventToOSRWidget(&tme);}break;case QEvent::Wheel:{QWheelEvent *we = (QWheelEvent*)e;QPointF localPosF = we->posF();QPointF gloabalPosF = we->globalPosF();QPoint pixelDelta = we->pixelDelta();QPoint angleDelta = we->angleDelta();int qt4Delta = we->delta();Qt::Orientation orientation = we->orientation();Qt::MouseButtons mouseButtons = we->buttons();Qt::KeyboardModifiers modifiers = we->modifiers();//修正一下localposQPointF offsetF = mapToScene(QPoint(0,0));QPointF diffPosF = localPosF - offsetF;QWheelEvent twe(diffPosF, gloabalPosF, pixelDelta, angleDelta, qt4Delta, orientation, mouseButtons, modifiers);sendEventToOSRWidget(&twe);}break;default:{sendEventToOSRWidget(e);}break;}}return res;
}void WidgetOSRItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry);if(mOSRWidget){mOSRWidget->setGeometry(newGeometry.toRect());}
}#endif
5 参考链接
uwerat/qskinny: A lightweight framework on top of the Qt scene graph and only few classes from Qt/Quick. It is usable from C++ and/or QML. (github.com)
Skycoder42/QtMvvm: A mvvm oriented library for Qt, to create Projects for Widgets and Quick in parallel (github.com)
(177条消息) qwidget嵌入qml最完整代码_qml嵌入widget,qml嵌入qwidget-C++文档类资源-CSDN文库
(177条消息) 如何获取指定objectName的QObject_qyvlik的博客-CSDN博客
pengguanjun/UseQtWidgetInQML: 在qt widget中使用qml很容易,那怎么在qml中使用qt widget控件呢 (github.com)
(175条消息) QWidget嵌入QML窗口中_Eosin_Sky的博客-CSDN博客_qwidget放到qml
(175条消息) 将Qt Widgets嵌入到QML界面中的一种示范_Eosin_Sky的博客-CSDN博客_widgetosritem
(176条消息) 在Qt中将QWindow或者QWidget嵌入到别的进程中的窗口中(windows)_Eosin_Sky的博客-CSDN博客_qwindow
C++生成QML代码与QML里面集成QWidget相关推荐
- 1.豆豆项目搭建之springboot集成mybatis-plus(包含mybatis-plus自动生成基础代码)
1.项目版本说明 组件 版本 说明 springboot 2.4.2 是为了后面集成cloud2020.0.0 和 cloud-alibaba2021.1 版本 mybatis-plus 3.4.3. ...
- QML笔记:QML基本概念及使用
QML笔记:QML基本概念及使用 Qt5中的Qt Qml和Qt Quick架构 Qt Qml模块本身并没有涉及图形显示,所有的图形处理都由Qt Quick模块完成. Qt Quick 以QPA(Qt ...
- Jenkins 在 Tomcat 中的部署及代码静态检查工具集成
Jenkins 的简单部署 在安装了 Jenkins 运行所需的依赖(主要是 JDK)之后,可以通过如下步骤简单快速地部署 Jenkins: 下载 Jenkins. 打开终端并切换至下载目录. 运行命 ...
- 前端开发者的福音!通过拖拽就可生成Vue代码的平台来了!
Vue组件代码生成平台 Vue组件代码生成平台是一款面向Vue开发者的拖拽式组件代码生成工具.通过它可以快速搭建Vue组件的代码骨架结构.开发者可在此基础上进行二次开发. 目前该平台非常适合快速搭建一 ...
- Protobuf生成Java代码(命令行)
1.说明 本文介绍Protobuf生成Java代码的方法, 下载必须的Protobuf工具, 然后通过命令行, 把.proto文件生成Java代码. 2.准备Protobuf工具 2.1.获取prot ...
- Protobuf生成Java代码(Maven)
1.说明 本文介绍Protobuf生成Java代码的方法, 配置对应的Maven插件, 把.proto文件生成Java代码. 2.插件配置 创建Maven工程grpc-compile, 修改pom.x ...
- [QML开发笔记]-QML滑屏效果
[QML开发笔记]-QML滑屏效果 QML的SwipeView滑屏控件.PageIndicator翻页指示器控件的功能介绍和使用方法.同样的功能我通过QWidget也进行了实现,可以参考QWidget ...
- MATLAB/SIMULINK生成嵌入式代码的步骤
昨天参加了Mathworks公司在东南大学举办的关于MATLAB的培训,内容是关于MATLAB/SIMULINK的嵌入式代码生成以及物理建模,在这里把代码生成的步骤及一些相关内容总结一下. 嵌入式代码 ...
- matlab如何将代码生成模型,为模型生成 C 代码
为模型生成 C 代码 要从 Simulink® 模型.Stateflow® 图和 MATLAB® 函数生成 C 或 C++ 代码,请使用 Simulink Coder™ 产品.将生成的代码用于仿真加速 ...
最新文章
- 干货:五分钟带你看懂NestedScrolling嵌套滑动机制
- linux shell 替换字符串的几种方法,变量替换${},sed,awk
- js简单的下拉选中效果
- iOS开发- 相机(摄像头)获取到的图片自动旋转90度解决办法
- lodash源码分析之compact中的遍历
- Linux基本目录结构
- 云原生实时数仓首次在2020双11核心数据场景落地
- 有没有用逆向算法恢复马赛克的可能性?
- Macaca简单入门
- CSS基础——简单的文字样式
- 数据分析之参数检验与非参数检验
- accurately Buy Diesel watches how you can suitably
- faker假数据php,php faker 伪造数据
- 阿里面试题 ——输入一个字符串,输出所有的排列
- 联想笔记本G50-70无线网卡问题
- IPv4地址、IPv6地址和Mac地址的位数
- 数据库模型设计——历史表与版本号设计
- 算法与数据结构实验题 10.23 寡人的难题——Kurskal算法
- 词向量化 Vector Representation of Words 方法汇总
- 史上最强《Java 开发手册》泰山版王者归来!