目录
4 QML_OSR_EXP 将Qt Widgets嵌入到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
-
- 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
- #include
- #include
-
- 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 the
- object 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 );
- else
- props->setProperty( "minimumHeight", size );
-
- break;
- }
- case Qt::PreferredSize:
- {
- if ( orientation == Qt::Horizontal )
- props->setProperty( "preferredWidth", size );
- else
- props->setProperty( "preferredHeight", size );
-
- break;
- }
- case Qt::MaximumSize:
- {
- if ( orientation == Qt::Horizontal )
- props->setProperty( "maximumWidth", size );
- else
- props->setProperty( "maximumHeight", size );
-
- break;
- }
- }
- }
- }
-
- void GridQuick::setSizePolicyAt(
- int index, Qt::Orientation orientation, int policy )
- {
- const auto qPolicy = static_cast< QSizePolicy::Policy >( policy & 0xF );
-
- #if 0
- const bool isConstrained = policy & ( 1 << 4 );
- #endif
-
- const bool doFill = ( qPolicy & QSizePolicy::GrowFlag )
- || ( qPolicy & QSizePolicy::ExpandFlag );
-
- if ( auto props = attachedPropertiesAt( m_grid, index ) )
- {
- if ( orientation == Qt::Horizontal )
- props->setProperty( "fillWidth", doFill );
- else
- props->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 );
- }
-
-
- #include "QskQuickItem.h"
- #include "QskQuickItemPrivate.h"
- #include "QskQuick.h"
- #include "QskEvent.h"
- #include "QskSetup.h"
- #include "QskSkin.h"
- #include "QskDirtyItemFilter.h"
-
- #include
- #include
-
- #if defined( QT_DEBUG )
-
- QSK_QT_PRIVATE_BEGIN
-
- #if QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 )
- #ifndef emit
- #define emit
- #include
- #undef emit
- #endif
- #endif
-
- #include
-
- QSK_QT_PRIVATE_END
-
- #endif
-
- #include
-
- 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 instead
- of 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, when
- a 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 to
- put 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 operations
- that are triggered by detaching the item from its parent
- can 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();
- }
-
- 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
(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;
- }
- }
-
- 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();
-
- //修正一下localpos
- QPointF 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();
-
- //修正一下localpos
- QPointF 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());
- }
- }
-
- #else
-
-
- 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 = me->localPos();
- Qt::MouseButton mouseButton = me->button();
- Qt::MouseButtons mouseButtons = me->buttons();
- Qt::KeyboardModifiers modifiers = me->modifiers();
-
- //修正一下localpos
- QPointF 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();
-
- //修正一下localpos
- QPointF 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
(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