Плагин дизайнера с контейнерным виджетом - PullRequest
0 голосов
/ 23 апреля 2020

Я борюсь с созданием нового виджета Designer с контейнером в нем для Qt 5.14.1. Я следую учебным пособиям и некоторым другим указаниям, чтобы заставить это работать, и у меня фактически есть мой виджет в Qt-дизайнере. Мой виджет происходит от QWidget, содержит несколько макетов, рамку и метку. А также QWidget, предназначенный для использования в качестве контейнера для других виджетов от дизайнера.

Моя проблема в том, как указать виджет контейнера для конструктора?

Я пытаюсь решить эту проблему с помощью QDesignerContainerExtension (хотя в документации говорится, что это не предназначено для этого), так как большинство сообщений на форуме указывают на это направление (но никогда с рабочим примером). Я заставляю его иметь 1 страницу, и для этой страницы я возвращаю свой контейнерный виджет обратно.

Виджет появляется в конструкторе, но когда я перетаскиваю в него другой виджет, например кнопку, кнопка не становится помещенный в контейнерный виджет, он даже не отображается в дереве виджетов. Кажется, кнопка прикреплена к пользовательскому виджету, а не к контейнеру. Кроме того, я не могу указать макет для него.

Не могли бы вы помочь мне сделать эту работу?

Вот что у меня сейчас:

PluginInterface.h

#pragma once

#include <QDesignerCustomWidgetInterface>
#include <QExtensionFactory>
#include <QDesignerContainerExtension>

class RibbonGroup;

class RibbonGroupPlugin : public QObject, public QDesignerCustomWidgetInterface
{
    Q_OBJECT
    Q_INTERFACES(QDesignerCustomWidgetInterface)
#if QT_VERSION >= 0x050000
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")
#endif // QT_VERSION >= 0x050000

public:
    RibbonGroupPlugin( QObject* parent = nullptr );

    bool isContainer() const;
    bool isInitialized() const;
    QIcon icon() const;
    QString domXml() const;
    QString group() const;
    QString includeFile() const;
    QString name() const;
    QString toolTip() const;
    QString whatsThis() const;
    QWidget *createWidget( QWidget* parent );
    void initialize( QDesignerFormEditorInterface* core );

private:
    bool m_initialized = false;
};

class RibbonGroupExtensionsFactory : public QExtensionFactory
{
    Q_OBJECT

public:
    explicit RibbonGroupExtensionsFactory( QExtensionManager* parent = nullptr );

protected:
    QObject* createExtension( QObject* object, const QString& iid, QObject* parent ) const override;
};

class RibbonGroupContainerExtension : public QObject, public QDesignerContainerExtension
{
    Q_OBJECT
    Q_INTERFACES( QDesignerContainerExtension )

public:
    explicit RibbonGroupContainerExtension( RibbonGroup* widget, QObject* parent );

    void addWidget( QWidget* widget ) override;
    int count() const override;
    int currentIndex() const override;
    void insertWidget( int index, QWidget* widget ) override;
    void remove( int index ) override;
    void setCurrentIndex( int index ) override;
    QWidget* widget( int index ) const override;

private:
    RibbonGroup* myWidget;
};

PluginInterface. cpp

#include "RibbonGroup.h"
#include "ribbonwidgetsplugin.h"

#include <QtPlugin>
#include <QDesignerFormEditorInterface>
#include <QExtensionManager>
#include <QLayout>

#include <QMessageBox>

RibbonGroupPlugin::RibbonGroupPlugin( QObject* parent )
: QObject( parent )
{
}

void RibbonGroupPlugin::initialize( QDesignerFormEditorInterface* fromEditor )
{
    if (m_initialized)
        return;

    auto manager = fromEditor->extensionManager();
    Q_ASSERT( manager );

    auto factory = new RibbonGroupExtensionsFactory( manager );

    manager->registerExtensions( factory, Q_TYPEID( QDesignerContainerExtension ) );

    m_initialized = true;
}

bool RibbonGroupPlugin::isInitialized() const
{
    return m_initialized;
}

QWidget *RibbonGroupPlugin::createWidget( QWidget* parent )
{
    return new RibbonGroup( parent );
}

QString RibbonGroupPlugin::name() const
{
    return QLatin1String( "RibbonGroup" );
}

QString RibbonGroupPlugin::group() const
{
    return QLatin1String( "Ribbon" );
}

QIcon RibbonGroupPlugin::icon() const
{
    return QIcon();
}

QString RibbonGroupPlugin::toolTip() const
{
    return QLatin1String();
}

QString RibbonGroupPlugin::whatsThis() const
{
    return QLatin1String();
}

bool RibbonGroupPlugin::isContainer() const
{
    return true;
}

QString RibbonGroupPlugin::domXml() const
{
    return QLatin1String( R"(
<ui language="c++">
    <widget class="RibbonGroup" name="ribbonGroup">
        <widget class="QWidget" name="container" />
    </widget>
    <customwidgets>
        <customwidget>
            <class>RibbonGroup</class>
            <extends>RibbonGroup</extends>
        </customwidget>
    </customwidgets>
</ui> )" );
}

QString RibbonGroupPlugin::includeFile() const
{
    return QLatin1String( "RibbonGroup.h" );
}

RibbonGroupExtensionsFactory::RibbonGroupExtensionsFactory( QExtensionManager* parent )
: QExtensionFactory( parent )
{
}

QObject* RibbonGroupExtensionsFactory::createExtension( QObject* object, const QString& iid, QObject* parent ) const
{
    auto widget = qobject_cast< RibbonGroup* >( object );

    if ( widget && ( iid == Q_TYPEID( QDesignerContainerExtension ) ) )
        return new RibbonGroupContainerExtension( widget, parent );

    return nullptr;
}

RibbonGroupContainerExtension::RibbonGroupContainerExtension( RibbonGroup* widget, QObject* parent )
: QObject( parent )
, myWidget( widget )
{
}

void RibbonGroupContainerExtension::addWidget( QWidget* /*widget*/ )
{
}

int RibbonGroupContainerExtension::count() const
{
    return 1;
}

int RibbonGroupContainerExtension::currentIndex() const
{
    return 0;
}

void RibbonGroupContainerExtension::insertWidget( int /*index*/, QWidget* /*widget*/ )
{
}

void RibbonGroupContainerExtension::remove( int /*index*/ )
{
}

void RibbonGroupContainerExtension::setCurrentIndex( int /*index*/ )
{
}

QWidget* RibbonGroupContainerExtension::widget( int /*index*/ ) const
{
    return myWidget->containerWidget();
}

Widget.h

#pragma once

#include <QWidget>
#include <QtUiPlugin/QDesignerExportWidget>

class QLabel;

class QDESIGNER_WIDGET_EXPORT RibbonGroup : public QWidget
{
    Q_OBJECT
    Q_PROPERTY( QString title READ title WRITE setTitle )

public:
    RibbonGroup( QWidget* parent = nullptr );

    QString title() const;
    void setTitle( const QString& text );

    QWidget* containerWidget();

private:
    QLabel*  label     = nullptr;
    QWidget* container = nullptr;
};

Виджет. cpp

#include "RibbonGroup.h"

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFrame>
#include <QLabel>

RibbonGroup::RibbonGroup( QWidget* parent )
: QWidget( parent )
{
    auto horizontalLayout = new QHBoxLayout( this );
    auto verticalLayout   = new QVBoxLayout( this );
    auto line             = new QFrame( this );
    label                 = new QLabel( this );
    container             = new QWidget( this );

    line->setFrameShape( QFrame::VLine );

    label->setAlignment( Qt::AlignmentFlag::AlignHCenter | Qt::AlignmentFlag::AlignCenter );
    label->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
    label->setAutoFillBackground( true );
    label->setText( "Ribbon group" );

    container->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
    container->setObjectName( "container" );

    horizontalLayout->addLayout( verticalLayout );
    horizontalLayout->addWidget( line );

    verticalLayout->addWidget( container );
    verticalLayout->addWidget( label );

    setLayout( horizontalLayout );
}

QString RibbonGroup::title() const
{
    return label->text();
}

void RibbonGroup::setTitle( const QString &text )
{
    label->setText( text );
}

QWidget* RibbonGroup::containerWidget()
{
    return container;
}
...