QML代码生成

Posted yantuguiguziPGJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QML代码生成相关的知识,希望对你有一定的参考价值。

目录

1  QML代码生成

2  注册机制的含义

3   QWidgetInQml  qml里面集成widget

4  参考链接


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 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 );


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 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();

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  参考链接

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博客

以上是关于QML代码生成的主要内容,如果未能解决你的问题,请参考以下文章

Qt/QML - 在 C++ 中注册 QML 类型会使 QML 代码不起作用

QML 文件包括 - 还是一个整体文件(结构 QML 代码)?

从 QML 生成 KeyEvent

在 Qml 代码中编辑 C++ QList<Object*> 模型的问题和一些 Qml 警告

QML - 不支持命令式代码

如何使用CMake项目生成提前的QML缓存?