• Qt窗体自动销毁


    Qt中通过对象树的方式,实现了窗体自动析构,只要我们使用得当,就能免去自己去释放窗体对象的内存,但是我们得清楚Qt窗体自动析构的机制,什么情况下能够自动析构,什么情况不能。操作不当的情况可能造成内存泄漏,甚至会出现程序崩溃问题。

    下面通过一系列示例进行探究。

    设置父窗体

    这种情况规则最简单,在创建窗体或控件时,指定其parent对象,当parent对象销毁时,则会析构该窗体。

    QComboBox* cbx=new QComboBox(this);//this窗体被析构时,cbx自动析构

    Qt中如果一个widget创建时没有指定parent,但是被其他窗体设置为centerWidget()后
    其他窗体析构时,该窗体能正常析构

    1. MainWindow::MainWindow(QWidget *parent)
    2. : QMainWindow(parent)
    3. {
    4. MyWidget* w=new MyWidget();
    5. //MainWindow将成为w的父窗体
    6. this->setCentralWidget(w);
    7. }
    设置窗体关闭时自动销毁

    Qt中如果一个widget没有指定parent,但设置setAttribute(Qt::WA_DeleteOnClose);
    该窗口关闭时析构

    1. MainWindow::MainWindow(QWidget *parent)
    2. : QMainWindow(parent)
    3. , ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6. //w作为一个独立的窗体展示,点击关闭按钮后,窗体自动析构
    7. MyWidget* w=new MyWidget();
    8. w->show();
    9. w->setAttribute(Qt::WA_DeleteOnClose);
    10. // this->setCentralWidget(w);
    11. }

    Qt中如果一个widget没有指定parent,且没有设置setAttribute(Qt::WA_DeleteOnClose);
    该窗口关闭时不会析构,主窗口关闭后,该窗口也不会析构

    1. MainWindow::MainWindow(QWidget *parent)
    2. : QMainWindow(parent)
    3. , ui(new Ui::MainWindow)
    4. {
    5. ui->setupUi(this);
    6. //w作为一个独立的窗体展示,关闭后,并不会销毁
    7. MyWidget* w=new MyWidget();
    8. w->show();
    9. }
    放入父窗体的布局之中

    如果一个控件在new时没有指定parent,但是放在了一个另窗体的布局中,该窗体关闭时
    该控件将析构。将控件放入一个窗体的布局中时,将自动设置该窗体为控件的父窗体。
     

    1. MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
    2. {
    3.     MyLineEdit* edit=new MyLineEdit();//没有指定parent
    4.     QVBoxLayout* layout=new QVBoxLayout();
    5.     layout->addWidget(edit);//放在一个widget的布局中
    6.     this->setLayout(layout);
    7. //当放入到当前窗体的布局中时,当前窗体将成为edit的父窗体
    8. }
    指定父窗体,又放入布局

    Qt中,如果一个控件指定了widget1作为parent,但是又放在了widget2的布局中
    在widget2被析构的时候,该控件将被析构
     

    1. MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
    2. {
    3.     MyLineEdit* edit=new MyLineEdit(parent);//指定widget1作为parent
    4.     QVBoxLayout* layout=new QVBoxLayout();
    5.     layout->addWidget(edit);//edit的实际parent已经更改为widget2( this, MyWidget*)
    6.     this->setLayout(layout);
    7. }

    其他设置父窗体的场景
    控件放入表格中

    Qt中,将一个编辑框放置在一个表格中,当表格被析构的时候,编辑框也被析构

    1. MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
    2. {
    3.     MyLineEdit* edit=new MyLineEdit(parent);
    4.     QTableWidget* table=new QTableWidget(this);
    5.     table->setColumnCount(2);
    6.     table->setRowCount(2);
    7.     table->setCellWidget(0,0,edit);
    8. //表格table析构时,edit也被析构
    9.     QVBoxLayout* layout=new QVBoxLayout();
    10.     layout->addWidget(table);
    11.     this->setLayout(layout);
    12. }

  • 相关阅读:
    【大数据】基于 Flink CDC 高效构建入湖通道
    使用聚类(K-means)分析方法对骑手进行分类标签定义
    考研408深度分析+全年规划
    在两个进程间进行通信的小demo
    CVE-2021-4034 polkit提权漏洞复现
    怎样在电脑上设置路由器的WiFi密码
    竹云产品入选《2023年度上海市网络安全产业创新攻关成果目录》
    Windows 下使用 nmap ncat 命令测试 UDP 端口连接
    Window Trigger的设计与实现
    6. 抽象类和接口
  • 原文地址:https://blog.csdn.net/xiyangxiaoguo/article/details/134242728