QWebview - 重新打开关闭的窗口

时间:2013-04-10 15:14:50

标签: qt qtwebkit window.open qwebview

我正在QT5(IDE Qt Creator 2.6.2)中开发基本的网络浏览器。 如果我点击link\anchor target

<a target="newWindow" href="http://stackoverflow.com">Test</a>

或执行打开pop-uponclickonmouseoveronkeydown等)的事件:

<input type="button" value="Test" onclick="window.open('','newWindow');">

然后关闭新打开的窗口,然后我无法重新打开该窗口。我点击,没有任何反应。

以下代码进行测试:

test-qwebview.pro

QT       += webkitwidgets network core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = browserqt
TEMPLATE = app


SOURCES += main.cpp\
        mbrowserqt.cpp

HEADERS  += mbrowserqt.h

FORMS    += mbrowserqt.ui

# install
target.path = $$[QT_INSTALL_EXAMPLES]/webkitwidgets/previewer
INSTALLS += target

mbrowserqt.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>mBROWSERQT</class>
 <widget class="QMainWindow" name="mBROWSERQT">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>640</width>
    <height>320</height>
   </rect>
  </property>
  <property name="sizePolicy">
   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
    <horstretch>0</horstretch>
    <verstretch>0</verstretch>
   </sizepolicy>
  </property>
  <property name="baseSize">
   <size>
    <width>0</width>
    <height>0</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Browser QT5</string>
  </property>
  <property name="layoutDirection">
   <enum>Qt::LeftToRight</enum>
  </property>
  <property name="autoFillBackground">
   <bool>false</bool>
  </property>
  <property name="documentMode">
   <bool>false</bool>
  </property>
  <property name="tabShape">
   <enum>QTabWidget::Rounded</enum>
  </property>
  <widget class="QWidget" name="centralWidget">
   <property name="sizePolicy">
    <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
     <horstretch>0</horstretch>
     <verstretch>0</verstretch>
    </sizepolicy>
   </property>
   <property name="minimumSize">
    <size>
     <width>50</width>
     <height>50</height>
    </size>
   </property>
   <property name="baseSize">
    <size>
     <width>0</width>
     <height>0</height>
    </size>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <property name="spacing">
     <number>0</number>
    </property>
    <property name="sizeConstraint">
     <enum>QLayout::SetMaximumSize</enum>
    </property>
    <property name="leftMargin">
     <number>0</number>
    </property>
    <property name="topMargin">
     <number>0</number>
    </property>
    <property name="rightMargin">
     <number>0</number>
    </property>
    <property name="bottomMargin">
     <number>0</number>
    </property>
    <item>
     <widget class="QWebView" name="mybrowsertest">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="minimumSize">
       <size>
        <width>50</width>
        <height>50</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
        <width>16777215</width>
        <height>16777215</height>
       </size>
      </property>
      <property name="baseSize">
       <size>
        <width>0</width>
        <height>0</height>
       </size>
      </property>
      <property name="contextMenuPolicy">
       <enum>Qt::DefaultContextMenu</enum>
      </property>
      <property name="acceptDrops">
       <bool>true</bool>
      </property>
      <property name="layoutDirection">
       <enum>Qt::LeftToRight</enum>
      </property>
      <property name="autoFillBackground">
       <bool>false</bool>
      </property>
      <property name="url">
       <url>
        <string>about:blank</string>
       </url>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <layoutdefault spacing="0" margin="0"/>
 <customwidgets>
  <customwidget>
   <class>QWebView</class>
   <extends>QWidget</extends>
   <header>QtWebKitWidgets/QWebView</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

mbrowserqt.h

#ifndef mBROWSERQT_H
#define mBROWSERQT_H

#include <QMainWindow>

namespace Ui {
    class mBROWSERQT;
}

class mBROWSERQT : public QMainWindow
{
    Q_OBJECT

public:
    explicit mBROWSERQT(QWidget *parent = 0, bool q = false);
    ~mBROWSERQT();

private:
    Ui::mBROWSERQT *ui;

//adicionado
public slots:
    void closeMyWindow();
    void resizeMyWindow(const QRect & geom);
};
#endif // mBROWSERQT_H

mbrowserqt.cpp

#include "mbrowserqt.h"
#include "ui_mbrowserqt.h"
#include <QtNetwork>

QWebSettings *settings;

class myWebPage : public QWebPage
{
    bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type){
        url = request.url();
        return QWebPage::acceptNavigationRequest(frame,request,type);
    }

    virtual QWebPage * createWindow(QWebPage::WebWindowType type) {
        Q_UNUSED(type);
        QMainWindow *wx = new mBROWSERQT(NULL,true);
        QWebView *wv = wx->findChild<QWebView*>("mybrowsertest");

        //Test
        connect(wv->page(), SIGNAL(windowCloseRequested()), wx, SLOT(deleteLater()));

        wx->showNormal();
        return wv->page();
    }

    private:
        QUrl url;
};

mBROWSERQT::mBROWSERQT(QWidget *parent, bool q) :
    QMainWindow(parent),
    ui(new Ui::mBROWSERQT)
{
    ui->setupUi(this);

    ui->mybrowsertest->setPage(new myWebPage());
    settings = QWebSettings::globalSettings();

    settings->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls,true);
    settings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled,true);
    settings->setAttribute(QWebSettings::LocalContentCanAccessFileUrls,true);
    settings->setAttribute(QWebSettings::JavascriptCanOpenWindows,true);
    settings->setAttribute(QWebSettings::JavascriptCanCloseWindows,true);
    settings->setAttribute(QWebSettings::JavascriptEnabled,true);
    settings->setAttribute(QWebSettings::PluginsEnabled,true);

    connect(ui->mybrowsertest->page(), SIGNAL(windowCloseRequested()), this, SLOT(closeMyWindow()));
    connect(ui->mybrowsertest->page(), SIGNAL(geometryChangeRequested(const QRect)),
            this, SLOT(resizeMyWindow(const QRect)));

    qDebug() << "new Page (target or window.open): " << q;
    if(q==false){
        QString fPage = "<!DOCTYPE html>";
                fPage.append("<html>\n");
                fPage.append("<head>\n");
                fPage.append("<script>\n");
                fPage.append("function openWin(q){\n");
                fPage.append("try{\n");
                fPage.append("var myWindow=window.open('','test','width=200,height=100,top=50,left=50');\n");
                fPage.append("  myWindow.document.write(\"<p>This is 'myWindow'</p>\");\n");
                fPage.append("} catch (ee){ alert(ee); } }\n");
                fPage.append("</script>\n");
                fPage.append("</head>\n");
                fPage.append("<body>\n");
                fPage.append("<p><input type=\"button\" value=\"Test window.open\" onclick=\"openWin();\"></p>\n");
                fPage.append("<p><a target=\"newWindow\" href=\"http://stackoverflow.com\">Test target</a></p>\n");
                fPage.append("</body>\n");
                fPage.append("</html>");
        ui->mybrowsertest->setHtml(fPage);
    }
}

void mBROWSERQT::resizeMyWindow(const QRect & geom){
    qDebug() << "geometry: " << geom;
    this->setGeometry(geom);
}

void mBROWSERQT::closeMyWindow(){
    qDebug() << "closeMyWindow/webView::stop...";
    ui->mybrowsertest->stop();
    qDebug() << "closeMyWindow/webView::page::view::close()...";
    ui->mybrowsertest->page()->view()->close();
    qDebug() << "closeMyWindow/webView::page::view::deleteLater()...";
    ui->mybrowsertest->page()->view()->deleteLater();
    qDebug() << "closeMyWindow/webView::close()...";
    ui->mybrowsertest->close();
    qDebug() << "closeMyWindow/MainWindow::close()...";
    close();//close widget
    deleteLater();//close Object
}

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

的main.cpp

#include "mbrowserqt.h"
#include <QApplication>
#include <QtWebKitWidgets/QWebView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);    
    mBROWSERQT w;
    w.show();
    return a.exec();
}

1 个答案:

答案 0 :(得分:1)

我删除了closeMyWindow

添加虚拟功能:QMainWindow::closeEvent(QCloseEvent *event)

使用QWebFrame::evaluateJavaScript我运行一个使用javascript发送close命令的javascript:

添加属性QWEBVIEW->setAttribute(Qt::WA_DeleteOnClose, true);

完全固定来源

<强> mbrowserqt.h

#ifndef mBROWSERQT_H
#define mBROWSERQT_H

#include <QMainWindow>

namespace Ui {
    class mBROWSERQT;
}

class mBROWSERQT : public QMainWindow
{
    Q_OBJECT

public:
    explicit mBROWSERQT(QWidget *parent = 0, bool q = false);
    ~mBROWSERQT();

private:
    Ui::mBROWSERQT *ui;

//adicionado
public slots:
    void closeEvent(QCloseEvent *event);
    void resizeMyWindow(const QRect & geom);
};
#endif // mBROWSERQT_H

<强> mbrowserqt.cpp

#include "mbrowserqt.h"
#include "ui_mbrowserqt.h"
#include <QtNetwork>
#include <QWebFrame>

QWebSettings *settings;

class myWebPage : public QWebPage
{
    bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type){
        url = request.url();
        return QWebPage::acceptNavigationRequest(frame,request,type);
    }

    virtual QWebPage * createWindow(QWebPage::WebWindowType type) {
        Q_UNUSED(type);
        QMainWindow *wx = new mBROWSERQT(NULL,true);
        QWebView *wv = wx->findChild<QWebView*>("mybrowsertest");
        wv->setAttribute(Qt::WA_DeleteOnClose, true);
        wx->showNormal();
        return wv->page();
    }

    private:
        QUrl url;
};

mBROWSERQT::mBROWSERQT(QWidget *parent, bool q) :
    QMainWindow(parent),
    ui(new Ui::mBROWSERQT)
{
    ui->setupUi(this);

    ui->mybrowsertest->setAttribute(Qt::WA_DeleteOnClose, true);
    ui->mybrowsertest->setPage(new myWebPage());
    settings = QWebSettings::globalSettings();

    settings->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls,true);
    settings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled,true);
    settings->setAttribute(QWebSettings::LocalContentCanAccessFileUrls,true);
    settings->setAttribute(QWebSettings::JavascriptCanOpenWindows,true);
    settings->setAttribute(QWebSettings::JavascriptCanCloseWindows,true);
    settings->setAttribute(QWebSettings::JavascriptEnabled,true);
    settings->setAttribute(QWebSettings::PluginsEnabled,true);

    connect(ui->mybrowsertest->page(), SIGNAL(windowCloseRequested()), this, SLOT(closeMyWindow()));
    connect(ui->mybrowsertest->page(), SIGNAL(geometryChangeRequested(const QRect)),
            this, SLOT(resizeMyWindow(const QRect)));

    qDebug() << "new Page (target or window.open): " << q;
    if(q==false){
        QString fPage = "<!DOCTYPE html>";
                fPage.append("<html>\n");
                fPage.append("<head>\n");
                fPage.append("<script>\n");
                fPage.append("function openWin(q){\n");
                fPage.append("try{\n");
                fPage.append("var myWindow=window.open('','test','width=200,height=100,top=50,left=50');\n");
                fPage.append("  myWindow.document.write(\"<p>This is 'myWindow'</p>\");\n");
                fPage.append("} catch (ee){ alert(ee); } }\n");
                fPage.append("</script>\n");
                fPage.append("</head>\n");
                fPage.append("<body>\n");
                fPage.append("<p><input type=\"button\" value=\"Test window.open\" onclick=\"openWin();\"></p>\n");
                fPage.append("<p><a target=\"newWindow\" href=\"http://stackoverflow.com\">Test target</a></p>\n");
                fPage.append("</body>\n");
                fPage.append("</html>");
        ui->mybrowsertest->setHtml(fPage);
    }
}

void mBROWSERQT::resizeMyWindow(const QRect & geom){
    qDebug() << "geometry: " << geom;
    this->setGeometry(geom);
}

void mBROWSERQT::closeEvent(QCloseEvent *event) {
    Q_UNUSED(event);

    ui->mybrowsertest->close();
}

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