通过互联网搜索,我遇到了很多方法,主要是非功能性,非特定功能或部分功能,可以使用QWebView和打开URL进行各种操作.
经过多次咒骂和诅咒之后,我设法得到了一个例子来做我想要的,通常是开放的普通链接,并打开任何在外部浏览器中请求新窗口的内容;然而,有一个障碍.它泄漏了内存,因为我制作了一堆额外的WebView,直到进程退出时才清理它们.如何在不泄漏记忆的情况下做到这一点?
请提前原谅我对Qt的二年级理解.在这一点上我只用了几个小时.
SSCCE:
test.hpp
#include <QMainWindow> #include <QWebView> class Window : public QMainWindow { Q_OBJECT public: Window(); private: QWebView* m_web; private slots: }; class WebPage : public QWebPage { Q_OBJECT public: bool acceptNavigationRequest(QWebFrame *frame,const QNetworkRequest &request,NavigationType type); }; class WebView : public QWebView { Q_OBJECT public: QWebView* createWindow(QWebPage::WebWindowType type); };
TEST.CPP
#include <QApplication> #include <QGridLayout> #include <QNetworkRequest> #include <QDesktopServices> #include "test.hpp" Window::Window() : QMainWindow() { m_web = new WebView; m_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(m_web); } bool WebPage::acceptNavigationRequest(QWebFrame*,QNetworkRequest const& request,NavigationType) { QDesktopServices::openUrl(request.url()); return false; } QWebView* WebView::createWindow(QWebPage::WebWindowType) { auto res = new WebView; auto page = new WebPage; res->setPage(page); return res; } int main(int argc,char *argv[]) { QApplication a(argc,argv); Window w; w.show(); return a.exec(); }
test.pro
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
解决方法
在extern浏览器中呈现页面后,视图似乎变得无用.
您可以使用deleteLater()安排ExternalWebView删除:
您可以使用deleteLater()安排ExternalWebView删除:
#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 *,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,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