在油管上看到一篇关于Qt的视频:[How to Add & Remove Qt Widgets Dynamically at Runtime](https://www.youtube.com/watch?v=fNTnU7mMgK4)
作者是Velcode
In this video I show you how to add any widget or layouts containing widgets to another widow or another layout.
Code repository: [VelazcoJD/QtDynamicWidgets](https://github.com/VelazcoJD/QtDynamicWidgets)
Qt Widgets Theme: [https://youtu.be/zjWfDEUsobQ](https://youtu.be/zjWfDEUsobQ)
我使用的系统是Windows10系统,首先使用Qt Creator创建一个基于QMainWindows的Qt GUI窗体程序,界面如下图所示:
## 源代码
main.cpp文件源代码如下:
代码语言:javascript复制#include "dynamicwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DynamicWidget w;
w.show();
return a.exec();
}
dynamicwidget.h头文件如下图所示:
代码语言:javascript复制#ifndef DYNAMICWIDGET_H
#define DYNAMICWIDGET_H
#include <QMainWindow>
#include <QHash>
#include <QPushButton>
#include <QHBoxLayout>
QT_BEGIN_NAMESPACE
namespace Ui { class DynamicWidget; }
QT_END_NAMESPACE
class DynamicWidget : public QMainWindow
{
Q_OBJECT
public:
/// @brief Construcotr.
DynamicWidget(QWidget *parent = nullptr);
/// @brief Destructor.
~DynamicWidget();
/// @brief Handles user clicking on "add widget" button.
void onAddWidget();
/// @brief Handles user clicking on a remove widget button.
void onRemoveWidget();
private:
Ui::DynamicWidget *ui;
QHash<QPushButton*, QHBoxLayout*> mButtonToLayoutMap;
};
#endif // DYNAMICWIDGET_H
dynamicwidget.cpp源文件如下图所示:
代码语言:javascript复制#include "dynamicwidget.h"
#include "ui_dynamicwidget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QCheckBox>
DynamicWidget::DynamicWidget(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::DynamicWidget)
{
ui->setupUi(this);
QObject::connect(ui->addWidget_button, &QPushButton::clicked,
this, &DynamicWidget::onAddWidget);
}
DynamicWidget::~DynamicWidget()
{
delete ui;
}
void DynamicWidget::onAddWidget()
{
QVBoxLayout* layout = qobject_cast<QVBoxLayout*>(ui->widget_frame->layout());
if (layout == nullptr)
{
return;
}
QHBoxLayout* newLayout = new QHBoxLayout(ui->widget_frame);
QString buttonText = tr("Button: #%1").arg(layout->count());
QPushButton* button = new QPushButton(buttonText, ui->widget_frame);
//layout->insertWidget(0, button);
newLayout->addWidget(button);
mButtonToLayoutMap.insert(button, newLayout);
QCheckBox* checkBox = new QCheckBox("Check me!", ui->widget_frame);
newLayout->addWidget(checkBox);
layout->insertLayout(0, newLayout);
QObject::connect(button, &QPushButton::clicked,
this, &DynamicWidget::onRemoveWidget);
}
void DynamicWidget::onRemoveWidget()
{
// QPushButton* button = qobject_cast<QPushButton*>(sender());
// if (button)
// {
// delete button;
// }
QPushButton* button = qobject_cast<QPushButton*>(sender());
QHBoxLayout* layout = mButtonToLayoutMap.value(button);
while (layout->count() != 0)
{
QLayoutItem* item = layout->takeAt(0);
if (item)
{
delete item->widget();
delete item;
}
}
delete layout;
}
程序运行结果如下图所示:
点击【Click to Add Widget!】按钮,下面的widget_frame窗体会增加一个QPushButton和QCheckBox,如下图所示:
点击某一行的按钮,会删除该行对应的水平布局以及其中的QPushButton、QCheckBox控件。