C++ Qt:在默认浏览器中打开带有目标的链接,而不泄漏内存
通过互联网搜索,我遇到了很多方法,大多是非功能性的、非特定的或部分功能性的,用C++ Qt:在默认浏览器中打开带有目标的链接,而不泄漏内存,c++,qt,memory-leaks,qwebview,C++,Qt,Memory Leaks,Qwebview,通过互联网搜索,我遇到了很多方法,大多是非功能性的、非特定的或部分功能性的,用QWebView和打开URL来做各种事情 在多次咒骂之后,我终于找到了一个例子来做我想做的事情,那就是正常打开普通链接,并在外部浏览器中打开任何请求新窗口的内容;然而,有一个障碍。它会泄漏内存,因为我创建了一堆额外的webview,在进程退出之前不会清理这些视图。如何在不泄漏内存的情况下执行此操作 请原谅我对Qt的二年级理解。目前我只使用了几个小时 SSCCE: test.hpp 编译并运行 由于这是内置函数,因此不应
QWebView
和打开URL来做各种事情
在多次咒骂之后,我终于找到了一个例子来做我想做的事情,那就是正常打开普通链接,并在外部浏览器中打开任何请求新窗口的内容;然而,有一个障碍。它会泄漏内存,因为我创建了一堆额外的webview
,在进程退出之前不会清理这些视图。如何在不泄漏内存的情况下执行此操作
请原谅我对Qt的二年级理解。目前我只使用了几个小时
SSCCE:
test.hpp
编译并运行
由于这是内置函数,因此不应存在任何内存泄漏。在外部浏览器中呈现页面后,视图似乎变得无用。 您可以使用deleteLater()将ExternalWebView安排为删除: 稍后删除测试:
Window
ExternWebView
1 ExternWebView: 68
ExternWebPage
2 ExternWebView: 74
3 ExternWebView: 75
1 ExternWebPage: 43
2 ExternWebPage: 43
3 ExternWebPage: 43
4 ExternWebPage: 43
5 ExternWebPage: 43
Destroy Window
ExternWebView
1 ExternWebView: 68
ExternWebPage
2 ExternWebView: 74
3 ExternWebView: 75
4 ExternWebView: 52
Destroy ExternWebView
Destroy ExternWebPage
Destroy Window
程序中没有泄漏,因为qt内存管理系统将处理堆上创建的对象 首先,要使视图对象成为页面对象的父对象。这意味着当视图对象被销毁时,页面对象将被删除 其次,由于视图没有父视图,因此始终会得到一个窗口。当您关闭窗口或结束程序时,它将被释放。这就是为什么我说它将由qt的内存管理系统来处理
现在,当您使用内存探查器程序(如valgrind)运行您的程序时,可能会出现泄漏,这可能是真实的泄漏,也可能不是真实的泄漏。你需要识别并过滤掉它们。你怎么知道有泄漏?我不知道!我只是怀疑。我不太明白Qt是如何工作的,但我正在更新一个对象,然后把它扔掉。如果答案是“没有泄漏,别傻了。”你可以用某种方式备份,那么我会接受。你有没有尝试过查找内存泄漏,比如valgring(如果你在linux下)?不管怎么说,m_web是这样做的,它永远不会被删除。您应该在构造函数中指定父级。@Jepessen,我假设在valgrind中永远不会将内存标记为泄漏,因为Qt的库仍然保留在它们上面。保留指向它们的指针,然后手动请求删除它们会向控制台发出非致命错误。我只是不太明白如何正确地去除它们,或者是否有更好的方法来避免问题的发生。抱歉,如果不清楚,这不是我认为它正在泄漏内存的原因。我认为它会泄漏内存的原因是我正在创建一个QWebView并应用一个QWebPage,返回它们,然后不使用或显示它们,拒绝了导航请求。因此,对于我在应用程序中单击的每一个新链接,该程序只会保存另一个不可见的QWebView副本。谢谢。我想这正是我需要的。我以前尝试过类似的事情,但遇到了一个问题,它给了我一个错误。我今天无法测试,但明天下午,我会试一试,接受这个答案,如果可行的话,申请赏金。更新一下,最近事情对我来说太疯狂了,我今天要试试这个。抱歉耽搁了。呃,我实际上还没有机会测试这个,但我没有欺骗你,而是继续奖励了你。我相信它会起作用的。
QT += core gui network webkitwidgets widgets
TEMPLATE = app
TARGET = test
INCLUDEPATH += .
CONFIG += c++11
# Input
SOURCES += test.cpp
HEADERS += test.hpp
qmake test.pro
make
./test
QDesktopServices::openUrl(QUrl("http://stackoverflow.com/"));
#include <iostream>
#include <QApplication>
#include <QGridLayout>
#include <QNetworkRequest>
#include <QDesktopServices>
#include <QEvent>
#include <QMainWindow>
#include <QWebView>
class ExternWebPage : public QWebPage {
//Q_OBJECT
public:
ExternWebPage(QObject* parent = 0)
: QWebPage(parent)
{
std::cout << "ExternWebPage" << std::endl;
}
~ExternWebPage() {
std::cout << "Destroy ExternWebPage" << std::endl;
}
virtual bool event(QEvent *e) {
static unsigned counter;
std::cout << ++counter << " ExternWebPage: " << e->type() << std::endl;
return QWebPage::event(e);
}
bool acceptNavigationRequest(QWebFrame *, const QNetworkRequest &request, NavigationType) {
QDesktopServices::openUrl(request.url());
return false;
}
};
class ExternWebView : public QWebView {
//Q_OBJECT
public:
ExternWebView(QWidget* parent = 0)
: QWebView(parent)
{
std::cout << "ExternWebView" << std::endl;
}
~ExternWebView() { std::cout << "Destroy ExternWebView" << std::endl; }
virtual bool event(QEvent *e) {
static unsigned counter;
std::cout << ++counter << " ExternWebView: " << e->type() << std::endl;
return QWebView::event(e);
}
};
class InternalWebView : public QWebView {
//Q_OBJECT
public:
InternalWebView(QWidget* parent = 0)
: QWebView(parent)
{}
QWebView* createWindow(QWebPage::WebWindowType) {
auto res = new ExternWebView();
res->setPage(new ExternWebPage(res));
res->deleteLater();
return res;
}
};
class Window : public QMainWindow {
//Q_OBJECT
public:
Window()
: QMainWindow()
{
std::cout << "Window" << std::endl;
auto web = new InternalWebView(this);
web->setHtml("<div align=\"center\"><a href=\"http://www.google.com/\">Same Window</a> <a href=\"http://www.google.com/\" target=\"_blank\">New Window</a></div>");
setCentralWidget(web);
}
~Window() { std::cout << "Destroy Window" << std::endl; }
};
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
Window w;
w.show();
return a.exec();
}
Window
ExternWebView
1 ExternWebView: 68
ExternWebPage
2 ExternWebView: 74
3 ExternWebView: 75
1 ExternWebPage: 43
2 ExternWebPage: 43
3 ExternWebPage: 43
4 ExternWebPage: 43
5 ExternWebPage: 43
Destroy Window
ExternWebView
1 ExternWebView: 68
ExternWebPage
2 ExternWebView: 74
3 ExternWebView: 75
4 ExternWebView: 52
Destroy ExternWebView
Destroy ExternWebPage
Destroy Window