遇到这样的提示,通常都是在一个已经设置 Layout的widget上面再次设置它的Layout,这样就会触发QT的提示
代码演示
ui->setupUi(this);
//关键 如果在new 一个QLayout对象时,指明了一个QWidget的对象作为父对象,那么就相当于将这个Layout设置到父对象上
//去掉this则没有问题。并且这样并不影响QT的对象树进行资源的释放。
QVBoxLayout *vbox = new QVBoxLayout(this);
QWidget *sonWidget = new QWidget;
sonWidget->setObjectName("sonWidget");
sonWidget->setStyleSheet("#sonWidget{background-color:pink;}");
QLabel *label = new QLabel;
label->setText("Hello World");
//通过 setLayout sonWidget 将成为 vbox里所有一级 widget 的父对象
sonWidget->setLayout(vbox);
vbox->addWidget(label);
ui->verticalLayout->addWidget(sonWidget);
相关的一些QT源码
/*!
Constructs a new top-level QLayout, with parent \a parent.
\a parent may not be 0.
There can be only one top-level layout for a widget. It is
returned by QWidget::layout().
*/
QLayout::QLayout(QWidget *parent)
: QObject(*new QLayoutPrivate, parent)
{
if (!parent)
return;
parent->setLayout(this);
}
void QWidget::setLayout(QLayout *l)
{
if (Q_UNLIKELY(!l)) {
qWarning("QWidget::setLayout: Cannot set layout to 0");
return;
}
if (layout()) {
if (Q_UNLIKELY(layout() != l))
qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", which already has a"
" layout", l->objectName().toLocal8Bit().data(), metaObject()->className(),
objectName().toLocal8Bit().data());
return;
}
QObject *oldParent = l->parent();
if (oldParent && oldParent != this) {
if (oldParent->isWidgetType()) {
// Steal the layout off a widget parent. Takes effect when
// morphing laid-out container widgets in Designer.
QWidget *oldParentWidget = static_cast<QWidget *>(oldParent);
oldParentWidget->takeLayout();
} else {
qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent",
l->objectName().toLocal8Bit().data(), metaObject()->className(),
objectName().toLocal8Bit().data());
return;
}
}
Q_D(QWidget);
l->d_func()->topLevel = true;
d->layout = l;
if (oldParent != this) {
l->setParent(this);
//通过 reparentChildWidgets 将 Layout 里面的一级的 QWidget 变为调用此函数的对象。
l->d_func()->reparentChildWidgets(this);
l->invalidate();
}
if (isWindow() && d->maybeTopData())
d->topData()->sizeAdjusted = false;
}
其它关于 UI方面的一些点
- 在通过页面进行UI配置的时候,在一个Widget没有子Widget时我们不能为它添加一个主要的Layout。但是我们可以通过添加子控件在添加Layout,在删除子控件。来达到效果。
- 对于从UI界面拖出来的 QTabWIdget。是自带了两个 Tab 页的。想要给这两个 Tab 页加上不同的布局,选中对应的tab添加是不行的,需要通过 QTabWidget 添加,那个 tab页是QTabWidget的当前tab页此时布局就将添加到那个tab页上,打破布局也是同理。