2
votes

I want to do something fairly simple : add a custom widget to Qt designer that would basically be a scrollArea containing a custom vertical layout(I added some code to the vertical layout in order to handle its objects for my projects). The idea would be to represent a vertical menu that would be on the side of my screen

What I have done so far

I created the custom widget plugin and my custom layout.

My custom widget codes looks like this:

#include "menuwidget.h"

MenuWidget::MenuWidget(QWidget *parent) :
        QScrollArea(parent)
{
    this->setWidgetResizable(true);
    QWidget* layoutHoldingWidget= new QWidget(this);
    layout= new MenuLayout();
    layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
    layout->addStretch(1);
    layoutHoldingWidget->setLayout(layout);
    this->setWidget(layoutHoldingWidget);
}

If I add manually to the layout (in the constructor code) some buttons

for(int i =0;i<20;i++)
    layout->addWidget(new QPushButton(this));

It does work and I can see my scrollArea containing some buttons, which is almost what I want.

What I want

I would like to be able to add these buttons directly via Qt designer: the user would first drag the empty MenuWidget on the main window, then would drag QPushButtons on my custom widget exactly like he would do on a regular vertical layout.

Is that possible?How could I do such a thing?

Thank you ! :)

Edit 1

What I was missing was the "scrollAreaWidgetContents" widget that is always created when you drag and drop a QScrollArea. I did a similar thing by adding a widget (let's call it containerWidget) to my custom scrollArea in its domXml function, which enables me to drag and drop widgets on my scroll Area like I wanted to do.

BUT there's still something I can't figure out : I want the containerWidget to have a customLayout (myCustomLayout) . If I add it in the domXml function, I get the following line in the terminal :

Designer:The layout type 'MyCustomLayout' is not supported, defaulting to grid.

So it means that I can't tell designer to use my custom layout to place my widgets, which is kind of sad :D

Is there any way to "cheat" here?

2
I've read about this and I don't see how it could help me. My question is pretty specific, I think.psykhi
The given link and documentation linked there explain how to extend qt designer with own widget and widget pluginsSebastian Lange
Thanks, but I have read this doc countless times. I need some some help about this specific problem...psykhi
I use the given option for subclassed widget and use qt-project.org/doc/qt-4.8/designer-creating-custom-widgets.html or qt-project.org/doc/qt-4.8/qtdesigner.html guide for creating plugins for QtDesigner. All steps should be mentioned in there. From your description you did not yet create a complete plugin but just a replacement. Your next step would be to reimplement the given virutal functions mentioned in the guide. As far as i can tell almost everything is covered in there, so eventually read those links another time.Sebastian Lange

2 Answers

3
votes

There are two things to consider:

1) Overwrite in the class you derive from QDesignerCustomWidgetInterface the function to return true

bool isContainer() const { return true; }

This tells QtDesigner that the widget can contain children. (In Qt nearly any Widget can contain any widget as child, but QtDesigner tries to restrict it in a sensible way - e.g. you cant add children to a QLabel in QtDesigner)

2) Implement childEvent of your Widget. Probably in your case it would add Widgets added in QtDesigner to a layout.

Here is a core I've implemented to try this out. I've created a skeleton using "Qt Widget Plugin" Wizard in QtCreator and modified a little bit.

Don't forget to build as release, for the compiler/Qt-version of your QtDesigner , to copy the .dll and .lib files in \plugins\designer directory and to restart QtDesigner!

verticalplugin.cpp

//all other functions remained as created by QtCreator wizard
bool VerticalMenuPlugin::isContainer() const
{
    return true;
}

VerticalMenu.h

#ifndef VERTICALMENU_H
#define VERTICALMENU_H

#include <QtGui/QWidget>
#include <QtGui/QVBoxLayout>

class VerticalMenu : public QWidget
{
    Q_OBJECT

protected:
    virtual void childEvent ( QChildEvent * event );
public:
    VerticalMenu(QWidget *parent = 0);
};

#endif

VerticalMenu.cpp

#include "verticalmenu.h"
#include <QChildEvent>

VerticalMenu::VerticalMenu(QWidget *parent) :
    QWidget(parent)
{
    setLayout (new QVBoxLayout);
}

void VerticalMenu::childEvent ( QChildEvent * event )
{
    if ( event->added() )
    {
        QWidget * newChild = qobject_cast<QWidget *>(event->child());
        if ( newChild )
        {
            layout()->addWidget( newChild );
        }
    }
}

I hope' it would help as a starting point.

1
votes

Qt 4 does not support custom layout plugins for designer, so I couldn't achieve what I wanted to do. I will instead use a Vertical Layout and try to implement the additional features that were supposed to be in the custom layout code in the widget code.