FlowLayout doesn't show QWidgets added at runtime
-
I have a very strange problem, maybe someone can help me out with this. I've implemented a FlowLayout using "this example.":http://qt-project.org/doc/qt-5.0/qtwidgets/layouts-flowlayout.html However, I have run into a strange problem where widgets that are added at runtime are not showing up.
Basically, I have a QWidget that uses the FlowLayout as it's layout. In the constructor of that widget, I am able to add widgets to the layout and they show up just fine.
I want to be able to add widgets to the layout at the users command. My issue is, when the user performs the command that adds a widget to the layout, the item doesn't get shown. The caveat is, if I have 3 widgets added to the layout in the constructor, the user added widgets show up as expected. If there are < 3 widgets added in the constructor, the user added widgets don't get laid out properly (only appear in the top corner, as it's minimum size). If there are 0 widgets added in the constructor, the user added widgets don't appear at all.
Also note that I get this same behavior when using QPushButton in place of my custom widgets.
Where I am trying to add the widget:
@
AssetList::AssetList(QWidget *parent)
: QWidget(parent), mSelectedItem(nullptr) {mLayout = new FlowLayout(this); setLayout(mLayout);// If I add a widget to the layout here
// It shows up as expected
}QSize AssetList::itemSize() const {
return QSize(128, 128);
}void AssetList::addItem(AssetListItem *item) {
// If I add a widget after the constructor has run
// using this method, the widget does not show up.
// If 3 widgets were added in the constructor, the
// widgets added using this method by the user
// show up as expected.
item->setVisible(true);
mLayout->addWidget(item);connect(item, SIGNAL(selected(AssetListItem*)), this, SLOT(itemSelected(AssetListItem*)));}
@FlowLayout implementation:
@
#include "FlowLayout.h"
#include <QWidget>FlowLayout::FlowLayout(QWidget *parent)
: QLayout(parent) {}
FlowLayout::~FlowLayout() {
QLayoutItem *item;
while((item == takeAt(0))) {
delete item;
}
}void FlowLayout::addItem(QLayoutItem *item) {
mItemList.append(item);
}int FlowLayout::horizontalSpacing() const {
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
}int FlowLayout::verticalSpacing() const {
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}int FlowLayout::count() const {
return mItemList.size();
}QLayoutItem* FlowLayout::itemAt(int index) const {
return mItemList.value(index);
}QLayoutItem* FlowLayout::takeAt(int index) {
if(index >= 0 && index < mItemList.size()) {
return mItemList.takeAt(index);
} else {
return nullptr;
}
}Qt::Orientations FlowLayout::expandingDirections() const {
return Qt::Vertical;
}void FlowLayout::setGeometry(const QRect &rect) {
QLayout::setGeometry(rect);
doLayout(rect, false);
}QSize FlowLayout::sizeHint() const {
return minimumSize();
}QSize FlowLayout::minimumSize() const {
QSize size;
QLayoutItem *item;
// Fancy qt, eh?
foreach(item, mItemList) {
size += size.expandedTo(item->sizeHint());
}size += QSize(2*margin(), 2*margin()); return size;}
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const {
// Calculate the available area
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;// Layout the items QLayoutItem *item; foreach(item, mItemList) { QWidget *widget = item->widget(); int spaceX = horizontalSpacing(); int spaceY = verticalSpacing(); // Guess the size policty if(spaceX == -1) { spaceX = widget->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); } if(spaceY == -1) { spaceY = widget->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); } // if the widget can't fit on the current line int nextX = x + widget->sizeHint().width() + spaceX; if(nextX - spaceX > effectiveRect.right() && lineHeight > 0) { x = effectiveRect.x(); y = y + lineHeight + spaceY; nextX = x + item->sizeHint().width() + spaceX; lineHeight = 0; } // Layout the item if(!testOnly) item->setGeometry(QRect(QPoint(x, y), widget->sizeHint())); x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); } return y + lineHeight - rect.y() + bottom;}
int FlowLayout::smartSpacing(QStyle::PixelMetric pixelMetric) const {
QObject parent = this->parent();
if(!parent) {
return -1;
} else if(parent->isWidgetType()) {
QWidget parentWidget = static_cast<QWidget>(parent);
return parentWidget->style()->pixelMetric(pixelMetric, 0,
parentWidget);
} else {
return static_cast<QLayout>(parent)->spacing();
}
}@