环境:
QT版本:5.6.2
1.前言
QWidget动态增加控件,并且铺满控件。
2.实现原理
void QWidget::setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical)
This is an overloaded function.
Sets the size policy of the widget to horizontal and vertical, with standard stretch and no height-for-width.
将窗口小部件的大小策略设置为水平和垂直,具有标准拉伸,没有高度宽度。
Note: Setter function for property sizePolicy.
QSizePolicy::Preferred
The sizeHint() is best, but the widget can be shrunk and still be useful. The widget can be expanded,
but there is no advantage to it being larger than sizeHint() (the default QWidget policy).
缺省大小是最佳效果,部件允许放大或缩小,但不倾向于扩展比sizeHint()大(QWidget的缺省策略)。
3.代码实现
//pushbutton铺满widget
// QWidget -> QVBoxLayout -> QPushButton->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred)
QWidget * widget = new QWidget(this);
QVBoxLayout * layout = new QVBoxLayout(widget);//铺满布局
QPushButton *btn = new QPushButton();
btn->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);//铺满布局
layout->addWidget(btn);
ui->horizontalLayoutChoose->addWidget(widget);
4.结果
动态增加和动态删除QWidget内控件(有布局和没有布局都有效)(qDeleteAll、delete、deleteLater、findChildren)
在QWidget界面中,不管是否采用了布局,只要是QWidget的子类,则可以用findchild()函数查找所有子类,然后通过指定函数进行删除。下面是博主总结的两种动态删除dget内控件的方法。
一、通过函数qDeleteAll()删除
其中,该函数原型有两个,分别如下:
//第一个原型
template <typename ForwardIterator>
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
{
while (begin != end) {
delete *begin;
++begin;
}
}
//第二个原型
template <typename Container>
inline void qDeleteAll(const Container &c)
{
qDeleteAll(c.begin(), c.end());
}
由上可知,第二个原型是调用第一个原型,其中第一个原型是通过迭代器,用delete来删除指定的控件类。
1.2用法如下
博主要删除指定QWidget界面内所有的QLabel子类,步骤如下
1.2.1新建一个QWidget工程,勾选UI界面,然后在UI界面内随意拖进几个QLabel,如下图所示
1.2.2在按钮槽函数添加如下代码
void Widget::on_pushButton_clicked()
{
qDeleteAll(this->findChildren<QObject *>());
}
该函数的功能是删除QWidget内所有子类QObject和子类QObject的继承类。
1.2.3结果如下图所示
二、通过槽函数deleteLater或者delete删除
2.1思路原理讲解
可以用QWidget::findChildren找到QWidget所有子类,然后用迭代函数遍历QWidget所有子类,选择要删除的控件。该方式的优点是可以选择指定删除的控件和类型,不想删除的可以保留下来。其中,findChildren原型如下:
template<typename T>
inline QList<T> findChildren(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
QList<T> list;
qt_qFindChildren_helper(this, aName, ObjType::staticMetaObject,
reinterpret_cast<QList<void *> *>(&list), options);
return list;
}
通过函数findchildren可以获取QWidget内类型为T的所有子类。
2.2用法示例
接着上面的功能,将上面按钮槽函数的代码替换如下:
void Widget::on_pushButton_clicked()
{
QList<QLabel*> labels = this->findChildren<QLabel*>();
foreach(QLabel* label, labels)
{
if("保留控件" == label->objectName())//不想删除的控件
continue;
label->deleteLater(); //或者用delete wdg;也行
}
update(); //不加好像也可以
}
void Widget::on_pushButton_2_clicked()
{
//在QWidget内动态增加QLabel子控件代码
static int count=1;
QLabel *labelD1=new QLabel(QString("labelD%1").arg(count),this);
labelD1->setFixedSize(100,50);
labelD1->setGeometry(100+count,200+count,100,50);
labelD1->show();
count+=5;
}
2.3结果如下图所示
有结果可知,博主正确增加和删除QWidget内所有子控件QLabel。
参考内容:
https://bbs.csdn.net/topics/390512834(参考:删除所有控件qDeleteAll)
https://blog.csdn.net/qiangzi4646/article/details/97263481(参考:delete删除QWidget内所有子控件QPushbutton)