gpt4 book ai didi

c++ - QWebEngineView 中的内存泄漏

转载 作者:太空宇宙 更新时间:2023-11-03 17:25:50 26 4
gpt4 key购买 nike

我正在尝试使用 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com