c++ - QWebEngineView 中的内存泄漏

标签 c++ qt

我正在尝试使用 QWebEngineView 创建一个窗口,并在窗口关闭后删除 QWebEngineView。但是,QWebEngineView 似乎永远不会被删除,并且会继续运行我加载的任何 QUrl(例如 YouTube 视频)。在我的程序中,我有一个带有行编辑器和按钮的 QMainWindow,它创建了一个窗口来加载用户输入的 URL。这是我的代码:

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "subwindow.h"


namespace Ui
{
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    void init();
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    SubWindow *sub;

};

#endif // MAINWINDOW_H

子窗口.h

#ifndef SUBWINDOW_H
#define SUBWINDOW_H

#include <QMainWindow>

#include <QtWebEngineWidgets/qwebengineview.h>
#include <QTimer>

namespace Ui
{
class SubWindow;
}

class SubWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit SubWindow(QWidget *parent = 0);
    void doWeb(QString link);
    ~SubWindow();

private:
    Ui::SubWindow *ui;
    QWebEngineView *web;

private slots:
    void on_pushButton_clicked();

};

#endif // SUBWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

void MainWindow::init()
{
    this->showMaximized();

    sub = new SubWindow(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    sub->doWeb(ui->lineEdit->text());
}

子窗口.cpp

#include "subwindow.h"
#include "ui_subwindow.h"

SubWindow::SubWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::SubWindow)
{
    ui->setupUi(this);
}

void SubWindow::doWeb(QString link)
{
    this->show();
    web = new QWebEngineView(this);

    ui->verticalLayout->addWidget(web);

    web->load(QUrl(link, QUrl::TolerantMode));
    web->show();
}

SubWindow::~SubWindow()
{
    delete web; //Doesn't seem to work, since memory is still allocated in task manager
    delete ui;
}

void SubWindow::on_pushButton_clicked()
{
    this->close(); //Artifact for testing purposes.
}

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.init();

    return a.exec();
}

我也试过使用“web->close();” (我把它放在我有测试工件的那一行)与
一起 “web->setAttribute(Qt::WA_DeleteOnClose);” (我把它放在“web = new QWebEngineView(this);”之后),但这也没有解决我的问题。有人知道我做错了什么吗?

最佳答案

您正在使用父级“this”(所有者)创建 QWebEngineView,因此您不必自己删除它,它会在父级删除时自动删除。请参阅有关内存管理的 Qt 文档:

http://doc.qt.io/qt-5/objecttrees.html

这样做也很危险,因为如果您不使用 doWeb(QString link) 创建 QWebEngineView 对象,您将尝试删除不存在的内容,因此它可能导致您出现未定义的行为。

从你的析构函数中移除delete web,看看你是否总是遇到这个问题。

编辑: 它未被销毁的原因:您没有销毁 SubWindow 对象(QWebEngineView 对象的所有者)。您可以通过在析构函数中打印一些内容来自己验证。 如果您正在销毁 SubWindow 对象,则在您第二次按下 MainWindow 中的按钮时,您的应用程序将会崩溃。因为您不是在函数 on_push_button 内创建 SubWindow 对象,而是在 MainWindow::init 内。您的 SubWindow 对象仅被隐藏而未被破坏。只有当您关闭 MainWindow 时它才会被销毁。每次显示子(子窗口对象)时,您还创建了一个 QWebEngineview 实例,因此如果您显示子 3 次,您的子窗口中将有 3 个 QWebEngineView。

我将对代码进行的更改:

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

ma​​inWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "subwindow.h"

namespace Ui
{
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    SubWindow* sub;
};
#endif

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow), sub(new SubWindow(this))
{
    ui->setupUi(this);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::on_pushButton_clicked()
{
    sub->show();
    sub->doWeb(ui->lineEdit->text());
}

子窗口.h

#ifndef SUBWINDOW_H
#define SUBWINDOW_H

#include <QMainWindow>

#include <QtWebEngineWidgets/qwebengineview.h>
#include <QTimer>

namespace Ui
{
class SubWindow;
}

class SubWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit SubWindow(QWidget *parent = 0);
    void doWeb(QString link);
    ~SubWindow();

private:
    Ui::SubWindow *ui;
    QWebEngineView *web;

private slots:
    void on_pushButton_clicked();

};

#endif // SUBWINDOW_H

子窗口.cpp

#include "subwindow.h"
#include "ui_subwindow.h"

SubWindow::SubWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::SubWindow),
    web(new QWebEngineView(this))
{
    ui->setupUi(this);
    ui->verticalLayout->addWidget(web);
}
void SubWindow::doWeb(QString link)
{
    web->load(QUrl(link, QUrl::TolerantMode));
}
SubWindow::~SubWindow()
{
    delete ui;
}
void SubWindow::on_pushButton_clicked()
{
    this->close(); //Artifact for testing purposes.
}

请注意,我也没有破坏 subWindow 对象,但我没有在每次调用方法 SubWindow::doWeb(String) 时创建 QWebView。 如果由我决定,我会使用不是 MainWindow 成员的子类对话框,该对象将在 MainWindow::on_pushButton_clicked() 中创建,并在我使用完后销毁。

关于c++ - QWebEngineView 中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42463581/

相关文章:

python - 连续 keydown 事件 Pyqt

c++ - 电路可满足性求解器中的访问冲突读取位置 NULL

c++ - 当我在同一范围内多次初始化同名局部变量时,为什么 C++11 编译器不报错?

qt - QObjectPicker 不适用于自定义几何网格和渲染器

c++ - 我的 OpenGL QQuickItem 没有我想要的大小

c++ - 将 Qt .ui 文件的一部分提取到其自己的 .ui 文件中

c++ - c++ 中的 cout<<cout 和 cout<<&cout 有什么区别?

c++ - 将子 vector 与 qsort 一起使用

c++ - 为什么这不是正确的生产者消费者模型,以及在我使用 STL 队列时导致错误的原因是什么?

c++ - QThread线程池