自定义Qt设计器小部件:包含自定义垂直布局的滚动区域



我想做一些相当简单的事情:向Qt设计器添加一个自定义小部件,它基本上是一个包含自定义垂直布局的scrollArea(我在垂直布局中添加了一些代码,以便为我的项目处理其对象)。这个想法是表示一个垂直菜单,它将在我的屏幕的一侧

到目前为止我做了什么

我创建了自定义插件和自定义布局。

我的自定义小部件代码如下所示:

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

如果我手动添加到布局(在构造函数代码中)一些按钮

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

它确实有效,我可以看到我的滚动区包含一些按钮,这几乎是我想要的。

我想要什么

我希望能够通过Qt设计器直接添加这些按钮:用户首先在主窗口上拖动空的MenuWidget,然后在我的自定义小部件上拖动QPushButtons,就像在常规垂直布局上一样。

这可能吗?我怎么能做这样的事?

谢谢!:)

编辑1

我缺少的是"scrollAreaWidgetContents"小部件,它总是在拖放QScrollArea时创建的。我做了类似的事情,在domXml函数中向我的自定义滚动区域添加了一个小部件(让我们称之为containerWidget),这使我能够像我想做的那样在滚动区域上拖放小部件。

但我还是想不通:我希望containerWidget有一个customLayout(myCustomLayout)。如果我把它添加到domXml函数中,我会在终端中得到以下行:

设计器:不支持布局类型"MyCustomLayout",默认为网格。

所以这意味着我不能告诉设计者使用我的自定义布局来放置我的小部件,这有点可悲:D

这里有什么"作弊"的方法吗?

有两件事需要考虑:

1) 在从QDesignerCustomWidgetInterface派生的类中覆盖要返回true的函数

bool isContainer() const { return true; }

这一消息告诉QtDesigner小部件可以包含子部件。(在Qt中,几乎任何小部件都可以包含任何小部件作为子部件,但QtDesigner试图以合理的方式对其进行限制,例如,您不能在QtDesign中将子部件添加到QLabel中)

2) 实现小部件的childEvent。在您的情况下,它可能会将QtDesigner中添加的小工具添加到布局中。

这是我实现的一个核心来尝试这一点。我在QtCreator中使用"Qt Widget插件"向导创建了一个骨架,并进行了一些修改。

不要忘记构建为版本,对于QtDesigner的编译器/Qt版本,复制\plugins\designer目录中的.dll和.lib文件,并重新启动QtDesign!

verticalplugin.cpp

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

垂直菜单.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

垂直菜单.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 );
        }
    }
}

我希望这将有助于作为一个起点。

Qt4不支持设计器的自定义布局插件,所以我无法实现我想要做的事情。我将使用垂直布局,并尝试在小部件代码中实现自定义布局代码中应该有的附加功能。

最新更新