Я борюсь с созданием нового виджета 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;
}