• QML代码生成


    目录

    1  QML代码生成

    2  注册机制的含义

    3   QWidgetInQml  QML里面集成widget

    4 QML_OSR_EXP  将Qt Widgets嵌入到QML界面中的一种示范

    5  参考链接


    QML代码生成

    1. /******************************************************************************
    2. * QSkinny - Copyright (C) 2016 Uwe Rathmann
    3. * This file may be used under the terms of the 3-clause BSD License
    4. *****************************************************************************/
    5. #pragma once
    6. #include "GridAccessor.h"
    7. #include
    8. class QGraphicsGridLayout;
    9. class GridQuick : public QQuickWidget, public GridAccessor
    10. {
    11. public:
    12. GridQuick( QWidget* parent = nullptr );
    13. ~GridQuick() override;
    14. void insert( const QByteArray& colorName,
    15. int row, int column, int rowSpan, int columnSpan ) override;
    16. void setSpacing( Qt::Orientations, int spacing ) override;
    17. void setStretchFactor( int pos, Qt::Orientation, int stretch ) override;
    18. void setSizeHint( int pos, Qt::Orientation, Qt::SizeHint, int hint ) override;
    19. void setSizeHintAt( int index, Qt::Orientation, Qt::SizeHint, int hint ) override;
    20. void setSizePolicyAt( int index, Qt::Orientation, int policy ) override;
    21. void setAlignmentAt( int index, Qt::Alignment ) override;
    22. void setRetainSizeWhenHiddenAt( int index, bool on ) override;
    23. void setVisibleAt( int index, bool on ) override;
    24. QSize preferredSize() const override;
    25. protected:
    26. void resizeEvent( QResizeEvent* ) override;
    27. private:
    28. QQuickItem* m_grid;
    29. };

    1. /******************************************************************************
    2. * QSkinny - Copyright (C) 2016 Uwe Rathmann
    3. * This file may be used under the terms of the 3-clause BSD License
    4. *****************************************************************************/
    5. #include "GridQuick.h"
    6. #include
    7. #include
    8. #include
    9. static QQuickItem* createQml( const char* qmlCode )
    10. {
    11. QQmlEngine engine( nullptr );
    12. QQmlComponent component( &engine );
    13. component.setData( qmlCode, QUrl() );
    14. if ( component.status() != QQmlComponent::Ready )
    15. qWarning() << component.errorString();
    16. return qobject_cast< QQuickItem* >( component.create() );
    17. }
    18. static QQuickItem* itemAt( const QQuickItem* grid, int index )
    19. {
    20. const auto children = grid->childItems();
    21. if ( ( index >= 0 ) && ( index < children.count() ) )
    22. return children.at( index );
    23. return nullptr;
    24. }
    25. static QObject* attachedProperties( const QQuickItem* item )
    26. {
    27. for ( auto child : item->children() )
    28. {
    29. if ( child->inherits( "QQuickLayoutAttached" ) )
    30. return child;
    31. }
    32. return nullptr;
    33. }
    34. static QObject* attachedPropertiesAt( const QQuickItem* grid, int index )
    35. {
    36. if ( auto item = itemAt( grid, index ) )
    37. return attachedProperties( item );
    38. return nullptr;
    39. }
    40. GridQuick::GridQuick( QWidget* parent )
    41. : QQuickWidget( parent )
    42. {
    43. setContentsMargins( QMargins() );
    44. setResizeMode( QQuickWidget::SizeRootObjectToView );
    45. auto contentItem =
    46. createQml( "import QtQuick 2.0\nimport QtQuick.Layouts 1.1\nItem { GridLayout {} }" );
    47. setContent( QUrl(), nullptr, contentItem );
    48. m_grid = contentItem->childItems().constFirst();
    49. m_grid->setProperty( "rowSpacing", 5 );
    50. m_grid->setProperty( "columnSpacing", 5 );
    51. }
    52. GridQuick::~GridQuick()
    53. {
    54. }
    55. void GridQuick::insert( const QByteArray& colorName,
    56. int row, int column, int rowSpan, int columnSpan )
    57. {
    58. /*
    59. We need to create a temporary layout in QML, so that the
    60. object for the attachedProperties is created early
    61. */
    62. auto layout = createQml( "import QtQuick 2.0\nimport QtQuick.Layouts 1.15\nGridLayout { Rectangle {} }" );
    63. auto rectangle = layout->childItems().constFirst();
    64. rectangle->setParent( nullptr );
    65. delete layout;
    66. rectangle->setParent( m_grid );
    67. rectangle->setParentItem( m_grid );
    68. rectangle->setImplicitWidth( 50 );
    69. rectangle->setImplicitHeight( 50 );
    70. rectangle->setProperty( "color", QColor( colorName.constData() ) );
    71. if ( auto props = attachedProperties( rectangle ) )
    72. {
    73. props->setProperty( "row", row );
    74. props->setProperty( "column", column );
    75. props->setProperty( "rowSpan", rowSpan );
    76. props->setProperty( "columnSpan", columnSpan );
    77. props->setProperty( "fillWidth", true );
    78. props->setProperty( "fillHeight", true );
    79. }
    80. }
    81. void GridQuick::setSpacing( Qt::Orientations orientations, int spacing )
    82. {
    83. if ( orientations & Qt::Vertical )
    84. m_grid->setProperty( "rowSpacing", spacing );
    85. if ( orientations & Qt::Horizontal )
    86. m_grid->setProperty( "columnSpacing", spacing );
    87. }
    88. void GridQuick::setSizeHint( int, Qt::Orientation, Qt::SizeHint, int )
    89. {
    90. qWarning() << "setSizeHint is not supported by Quick Layouts.";
    91. }
    92. void GridQuick::setStretchFactor( int, Qt::Orientation, int )
    93. {
    94. qWarning() << "setStretchFactor is not supported by Quick Layouts.";
    95. }
    96. void GridQuick::setSizeHintAt( int index, Qt::Orientation orientation,
    97. Qt::SizeHint which, int hint )
    98. {
    99. if ( auto props = attachedPropertiesAt( m_grid, index ) )
    100. {
    101. const qreal size = hint;
    102. switch( static_cast< int >( which ) )
    103. {
    104. case Qt::MinimumSize:
    105. {
    106. if ( orientation == Qt::Horizontal )
    107. props->setProperty( "minimumWidth", size );
    108. else
    109. props->setProperty( "minimumHeight", size );
    110. break;
    111. }
    112. case Qt::PreferredSize:
    113. {
    114. if ( orientation == Qt::Horizontal )
    115. props->setProperty( "preferredWidth", size );
    116. else
    117. props->setProperty( "preferredHeight", size );
    118. break;
    119. }
    120. case Qt::MaximumSize:
    121. {
    122. if ( orientation == Qt::Horizontal )
    123. props->setProperty( "maximumWidth", size );
    124. else
    125. props->setProperty( "maximumHeight", size );
    126. break;
    127. }
    128. }
    129. }
    130. }
    131. void GridQuick::setSizePolicyAt(
    132. int index, Qt::Orientation orientation, int policy )
    133. {
    134. const auto qPolicy = static_cast< QSizePolicy::Policy >( policy & 0xF );
    135. #if 0
    136. const bool isConstrained = policy & ( 1 << 4 );
    137. #endif
    138. const bool doFill = ( qPolicy & QSizePolicy::GrowFlag )
    139. || ( qPolicy & QSizePolicy::ExpandFlag );
    140. if ( auto props = attachedPropertiesAt( m_grid, index ) )
    141. {
    142. if ( orientation == Qt::Horizontal )
    143. props->setProperty( "fillWidth", doFill );
    144. else
    145. props->setProperty( "fillHeight", doFill );
    146. }
    147. }
    148. void GridQuick::setAlignmentAt( int index, Qt::Alignment alignment )
    149. {
    150. if ( auto props = attachedPropertiesAt( m_grid, index ) )
    151. props->setProperty( "alignment", QVariant::fromValue( alignment ) );
    152. }
    153. void GridQuick::setRetainSizeWhenHiddenAt( int, bool )
    154. {
    155. qWarning() << "setRetainSizeWhenHidden is not supported by Quick Layouts.";
    156. }
    157. void GridQuick::setVisibleAt( int index, bool on )
    158. {
    159. if ( auto item = itemAt( m_grid, index ) )
    160. item->setVisible( on );
    161. }
    162. static const qreal margin = 10.0;
    163. QSize GridQuick::preferredSize() const
    164. {
    165. return QSize(
    166. m_grid->implicitWidth() + 2 * margin,
    167. m_grid->implicitHeight() + 2 * margin );
    168. }
    169. void GridQuick::resizeEvent( QResizeEvent* event )
    170. {
    171. QQuickWidget::resizeEvent( event );
    172. m_grid->setX( margin );
    173. m_grid->setY( margin );
    174. m_grid->setWidth( width() - 2 * margin );
    175. m_grid->setHeight( height() - 2 * margin );
    176. }

    2  注册机制的含义

    1. #include "QskQuickItem.h"
    2. #include "QskQuickItemPrivate.h"
    3. #include "QskQuick.h"
    4. #include "QskEvent.h"
    5. #include "QskSetup.h"
    6. #include "QskSkin.h"
    7. #include "QskDirtyItemFilter.h"
    8. #include
    9. #include
    10. #if defined( QT_DEBUG )
    11. QSK_QT_PRIVATE_BEGIN
    12. #if QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 )
    13. #ifndef emit
    14. #define emit
    15. #include
    16. #undef emit
    17. #endif
    18. #endif
    19. #include
    20. QSK_QT_PRIVATE_END
    21. #endif
    22. #include
    23. static inline void qskSendEventTo( QObject* object, QEvent::Type type )
    24. {
    25. QEvent event( type );
    26. QCoreApplication::sendEvent( object, &event );
    27. }
    28. static inline void qskApplyUpdateFlags(
    29. QskQuickItem::UpdateFlags flags, QskQuickItem* item )
    30. {
    31. auto d = static_cast< QskQuickItemPrivate* >( QskQuickItemPrivate::get( item ) );
    32. d->applyUpdateFlags( flags );
    33. }
    34. static inline void qskFilterWindow( QQuickWindow* window )
    35. {
    36. if ( window == nullptr )
    37. return;
    38. static QskDirtyItemFilter itemFilter;
    39. itemFilter.addWindow( window );
    40. }
    41. namespace
    42. {
    43. class QskQuickItemRegistry
    44. {
    45. public:
    46. QskQuickItemRegistry()
    47. {
    48. /*
    49. Its faster and saves some memory to have this registry instead
    50. of setting up direct connections between qskSetup and each control
    51. */
    52. QObject::connect( qskSetup, &QskSetup::itemUpdateFlagsChanged,
    53. qskSetup, [ this ] { updateControlFlags(); } );
    54. /*
    55. We would also need to send QEvent::StyleChange, when
    56. a window has a new skin. TODO ...
    57. */
    58. QObject::connect( qskSetup, &QskSetup::skinChanged,
    59. qskSetup, [ this ] { updateSkin(); } );
    60. }
    61. inline void insert( QskQuickItem* item )
    62. {
    63. m_items.insert( item );
    64. }
    65. inline void remove( QskQuickItem* item )
    66. {
    67. m_items.erase( item );
    68. }
    69. void updateControlFlags()
    70. {
    71. const auto flags = qskSetup->itemUpdateFlags();
    72. for ( auto item : m_items )
    73. qskApplyUpdateFlags( flags, item );
    74. }
    75. void updateSkin()
    76. {
    77. QEvent event( QEvent::StyleChange );
    78. for ( auto item : m_items )
    79. {
    80. event.setAccepted( true );
    81. QCoreApplication::sendEvent( item, &event );
    82. }
    83. }
    84. private:
    85. std::unordered_set< QskQuickItem* > m_items;
    86. };
    87. }
    88. namespace
    89. {
    90. /*
    91. A helper class to store the released window to be able to
    92. put it later into the WindowChange event.
    93. */
    94. class QskWindowStore
    95. {
    96. public:
    97. QskWindowStore()
    98. : m_refCount( 0 )
    99. , m_window( nullptr )
    100. {
    101. }
    102. void setWindow( QQuickWindow* window )
    103. {
    104. if ( m_window != window )
    105. {
    106. m_window = window;
    107. m_refCount = 0;
    108. }
    109. if ( m_window )
    110. m_refCount++;
    111. }
    112. QQuickWindow* window()
    113. {
    114. QQuickWindow* w = m_window;
    115. if ( m_window )
    116. {
    117. if ( --m_refCount == 0 )
    118. m_window = nullptr;
    119. }
    120. return w;
    121. }
    122. private:
    123. int m_refCount;
    124. QQuickWindow* m_window;
    125. };
    126. }
    127. Q_GLOBAL_STATIC( QskQuickItemRegistry, qskRegistry )
    128. Q_GLOBAL_STATIC( QskWindowStore, qskReleasedWindowCounter )
    129. QskQuickItem::QskQuickItem( QskQuickItemPrivate& dd, QQuickItem* parent )
    130. : QQuickItem( dd, parent )
    131. {
    132. setFlag( QQuickItem::ItemHasContents, true );
    133. if ( dd.updateFlags & QskQuickItem::DeferredUpdate )
    134. qskFilterWindow( window() );
    135. qskRegistry->insert( this );
    136. }
    137. QskQuickItem::~QskQuickItem()
    138. {
    139. /*
    140. We set componentComplete to false, so that operations
    141. that are triggered by detaching the item from its parent
    142. can be aware of the about-to-delete state.
    143. */
    144. d_func()->componentComplete = false;
    145. if ( qskRegistry )
    146. qskRegistry->remove( this );
    147. }
    148. const char* QskQuickItem::className() const
    149. {
    150. return metaObject()->className();
    151. }
    152. void QskQuickItem::classBegin()
    153. {
    154. Inherited::classBegin();
    155. }

    3   QWidgetInQml  QML里面集成widget

    1. bool QMLInteract::initUI()
    2. {
    3. m_engin.rootContext()->setContextProperty("QMLInteractObj", this);
    4. m_engin.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
    5. if (m_engin.rootObjects().isEmpty())
    6. {
    7. return false;
    8. }
    9. QObject* obj = m_engin.rootObjects().at(0);
    10. basewindowobj.setWndBaseInfo(obj);
    11. basewindowobj.setWndSplitType();
    12. m_engin.load(QUrl(QStringLiteral("qrc:/qml/CalibTwoPage.qml")));
    13. QObject* obj1 = m_engin.rootObjects().at(1);
    14. return true;
    15. }
    16. void BaseWindowContainer::setWndBaseInfo(QObject* obj)
    17. {
    18. QWindow * mainWindow = qobject_cast(obj);
    19. if (obj)
    20. {
    21. WId proc2Window_HWND = mainWindow->winId();
    22. m_widget->setProperty("_q_embedded_native_parent_handle", QVariant(proc2Window_HWND));
    23. m_widget->setWindowFlags(Qt::Widget|Qt::FramelessWindowHint);
    24. m_widget->winId();
    25. m_widget->setStyleSheet("background-color: rgb(46,138,201)");
    26. m_widget->windowHandle()->setParent(mainWindow);
    27. m_delegateObj = obj;
    28. }
    29. }

    4 QML_OSR_EXP  将Qt Widgets嵌入到QML界面中的一种示范

    1. bool WidgetOSRItem::sendEventToOSRWidget(QEvent *e)
    2. {
    3. QWindow* wHandle = mOSRWidget->windowHandle();
    4. bool res = false;
    5. if(wHandle)
    6. {
    7. res = qApp->sendEvent(wHandle, e);
    8. }
    9. return res;
    10. }

    1. #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
    2. bool WidgetOSRItem::eventFilter(QObject *obj, QEvent *e)
    3. {
    4. QWindow* pw = (QWindow*)(window());
    5. bool res = QQuickPaintedItem::eventFilter(obj, e);
    6. if(obj == mOSRWidget)
    7. {
    8. switch(e->type())
    9. {
    10. case QEvent::Paint: //当OsrWidget paint的时候也触发自己paint
    11. {
    12. QPaintEvent* pe = (QPaintEvent*)e;
    13. this->update(pe->rect());
    14. }
    15. break;
    16. }
    17. }
    18. else if(obj == pw)
    19. {
    20. //* 如果是鼠标等(有鼠标坐标信息的事件。)的话我们得计算一下偏移量并修正一下,这里就只处理QMouseEvent和QWheelEvent作为示例
    21. //* 如果有其他类似的也需要修正,不然可能坐标偏移
    22. switch(e->type())
    23. {
    24. case QEvent::MouseButtonDblClick :
    25. case QEvent::MouseButtonPress :
    26. case QEvent::MouseButtonRelease :
    27. case QEvent::MouseMove :
    28. case QEvent::MouseTrackingChange :
    29. case QEvent::Move :
    30. {
    31. QMouseEvent *me = (QMouseEvent*)e;
    32. QEvent::Type type = me->type();
    33. QPointF localPosF(QPointF(0,0));
    34. // QPointF localPosF = me->position();
    35. Qt::MouseButton mouseButton = me->button();
    36. Qt::MouseButtons mouseButtons = me->buttons();
    37. Qt::KeyboardModifiers modifiers = me->modifiers();
    38. //修正一下localpos
    39. QPointF offsetF = mapToScene(QPoint(0,0));
    40. QPointF diffPosF = localPosF - offsetF;
    41. QMouseEvent tme(type, diffPosF, mouseButton, mouseButtons, modifiers);
    42. sendEventToOSRWidget(&tme);
    43. }
    44. break;
    45. case QEvent::Wheel:
    46. {
    47. QWheelEvent *we = (QWheelEvent*)e;
    48. QPointF localPosF = we->position();
    49. QPointF gloabalPosF = we->globalPosition();
    50. QPoint pixelDelta = we->pixelDelta();
    51. QPoint angleDelta = we->angleDelta();
    52. Qt::MouseButtons mouseButtons = we->buttons();
    53. Qt::KeyboardModifiers modifiers = we->modifiers();
    54. //修正一下localpos
    55. QPointF offsetF = mapToScene(QPoint(0,0));
    56. QPointF diffPosF = localPosF - offsetF;
    57. QWheelEvent twe(diffPosF, gloabalPosF, pixelDelta, angleDelta,
    58. mouseButtons, modifiers, Qt::ScrollBegin, false);
    59. sendEventToOSRWidget(&twe);
    60. }
    61. break;
    62. default:
    63. {
    64. sendEventToOSRWidget(e);
    65. }
    66. break;
    67. }
    68. }
    69. return res;
    70. }
    71. void WidgetOSRItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
    72. {
    73. QQuickPaintedItem::geometryChange(newGeometry, oldGeometry);
    74. if(mOSRWidget)
    75. {
    76. mOSRWidget->setGeometry(newGeometry.toRect());
    77. }
    78. }
    79. #else
    80. bool WidgetOSRItem::eventFilter(QObject *obj, QEvent *e)
    81. {
    82. QWindow* pw = (QWindow*)(window());
    83. bool res = QQuickPaintedItem::eventFilter(obj, e);
    84. if(obj == mOSRWidget)
    85. {
    86. switch(e->type())
    87. {
    88. case QEvent::Paint: //当OsrWidget paint的时候也触发自己paint
    89. {
    90. QPaintEvent* pe = (QPaintEvent*)e;
    91. this->update(pe->rect());
    92. }
    93. break;
    94. }
    95. }
    96. else if(obj == pw)
    97. {
    98. //* 如果是鼠标等(有鼠标坐标信息的事件。)的话我们得计算一下偏移量并修正一下,这里就只处理QMouseEvent和QWheelEvent作为示例
    99. //* 如果有其他类似的也需要修正,不然可能坐标偏移
    100. switch(e->type())
    101. {
    102. case QEvent::MouseButtonDblClick :
    103. case QEvent::MouseButtonPress :
    104. case QEvent::MouseButtonRelease :
    105. case QEvent::MouseMove :
    106. case QEvent::MouseTrackingChange :
    107. case QEvent::Move :
    108. {
    109. QMouseEvent *me = (QMouseEvent*)e;
    110. QEvent::Type type = me->type();
    111. QPointF localPosF = me->localPos();
    112. Qt::MouseButton mouseButton = me->button();
    113. Qt::MouseButtons mouseButtons = me->buttons();
    114. Qt::KeyboardModifiers modifiers = me->modifiers();
    115. //修正一下localpos
    116. QPointF offsetF = mapToScene(QPoint(0,0));
    117. QPointF diffPosF = localPosF - offsetF;
    118. QMouseEvent tme(type, diffPosF, mouseButton, mouseButtons, modifiers);
    119. sendEventToOSRWidget(&tme);
    120. }
    121. break;
    122. case QEvent::Wheel:
    123. {
    124. QWheelEvent *we = (QWheelEvent*)e;
    125. QPointF localPosF = we->posF();
    126. QPointF gloabalPosF = we->globalPosF();
    127. QPoint pixelDelta = we->pixelDelta();
    128. QPoint angleDelta = we->angleDelta();
    129. int qt4Delta = we->delta();
    130. Qt::Orientation orientation = we->orientation();
    131. Qt::MouseButtons mouseButtons = we->buttons();
    132. Qt::KeyboardModifiers modifiers = we->modifiers();
    133. //修正一下localpos
    134. QPointF offsetF = mapToScene(QPoint(0,0));
    135. QPointF diffPosF = localPosF - offsetF;
    136. QWheelEvent twe(diffPosF, gloabalPosF, pixelDelta, angleDelta, qt4Delta, orientation, mouseButtons, modifiers);
    137. sendEventToOSRWidget(&twe);
    138. }
    139. break;
    140. default:
    141. {
    142. sendEventToOSRWidget(e);
    143. }
    144. break;
    145. }
    146. }
    147. return res;
    148. }
    149. void WidgetOSRItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
    150. {
    151. QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry);
    152. if(mOSRWidget)
    153. {
    154. mOSRWidget->setGeometry(newGeometry.toRect());
    155. }
    156. }
    157. #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

  • 相关阅读:
    驱动开发:内核中实现Dump进程转储
    【flask进阶】手把手带你搭建可扩展的flask项目脚手架
    手撕《现代信号处理》——通俗易懂的现代信号处理章节详解集合
    解决:unknow or unsupported command install
    HTML5期末考核大作业,网站——旅游景点。 学生旅行 游玩 主题住宿网页
    智能门禁刷脸照片格式gif、bmp,png转换,转换base64
    青云1000------华为昇腾310
    商品分类,汉码批发进销存管理软件
    java数据库开发与实战应用,2022最值得加入的互联网公司有哪些
    搞懂这些关键指标,数据分析起码少费一半力
  • 原文地址:https://blog.csdn.net/yantuguiguziPGJ/article/details/128024974