基于QWebView的浏览器Widget

OS : ubuntu 12.04 QT : 4.8.4 //测试时发现QT5的QWebView在加载Flash时会出现黑块,速度也比4.8慢很多。

如果有不能打开网页图片的情况,可能是因为你的QT找不到图片插件,解决方法如下:

export QT_PLUGIN_PATH=/usr/lib/qt4/plugins
cp -av /usr/lib/qt4/plugins/imageformats/   ~/Projects/browser   <----你自己的工程目录

BrowserWidget.pro

#只是一个Demo用以测试QWebView
QT       += core gui webkit webkitwidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = BrowserWidget
TEMPLATE = app

SOURCES += main.cpp \
    MyWebView.cpp \
    MyBrowser.cpp

HEADERS += \
    MyWebView.h \
    MyBrowser.h

MyBrowser.h

#ifndef MYBROWSER_H
#define MYBROWSER_H

#include "MyWebView.h"
#include <QWidget>
#include <QPushButton>

class MyBrowser : public QWidget {
    Q_OBJECT

public:
    explicit MyBrowser(QUrl url, QWidget *parent = 0);
    virtual ~MyBrowser();

private:
    void addButtons();
    void loadWebView(QUrl url, QWidget *parent = 0);

private slots:
    void closeSlot();

private:
    QPushButton *m_btnBack;
    QPushButton *m_btnForward;
    QPushButton *m_btnClose;

    MyWebView *m_webView;

    QUrl m_url;
};

#endif // MYBROWSER_H

MyBrowser.cpp

#include "MyBrowser.h"
#include <QDebug>

MyBrowser::MyBrowser(QUrl url, QWidget *parent) : QWidget(parent) {

    m_url = url;

    loadWebView(m_url, this);
    addButtons();
}

MyBrowser::~MyBrowser() {
    delete m_btnBack;
    delete m_btnClose;
    delete m_btnForward;
    delete m_webView;
}

void MyBrowser::addButtons() {

    m_btnBack = new QPushButton("back", this);
    connect(m_btnBack, SIGNAL(released()), m_webView, SLOT(back()));
    m_btnBack->setGeometry(QRect(700, 0, 100, 30));

    m_btnForward = new QPushButton("Forward", this);
    connect(m_btnForward, SIGNAL(released()), m_webView, SLOT(forward()));
    m_btnForward->setGeometry(QRect(810, 0, 100, 30));

    m_btnClose = new QPushButton("Close", this);
    /* 如果开启下面这条,那么在点击close的时候只是关闭了QWebView, 不会关闭QWidget */
    /* 当把这个Browser嵌入到其他Widget的时候, 这个Browser Wigget还是会显示在界面上 */
    //connect(m_btnClose, SIGNAL(released()), m_webView, SLOT(close()));
    
    /* 调用我们自己的SLOT, 以关闭整个Browser Widget */
    connect(m_btnClose, SIGNAL(released()), this, SLOT(close()));
    m_btnClose->setGeometry(QRect(920, 0, 100, 30));
}

void MyBrowser::loadWebView(QUrl url, QWidget *parent) {
    m_webView = new MyWebView(parent);
    m_webView->load(url);
    m_webView->setGeometry(QRect(0, 0, 1920, 1080));
}

void MyBrowser::closeSlot() {
    close();
}

MyWebView.h

#ifndef MYWEBVIEW_H
#define MYWEBVIEW_H

#include <QtWebKit/QWebView>

class MyWebView : public QWebView {
   Q_OBJECT

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

    QWebView *createWindow(QWebPage::WebWindowType type);

private slots:
    void linkClickedSlot(QUrl url);
};

#endif // MYWEBVIEW_H

MyWebView.cpp

#include "MyWebView.h"
#include <QtNetwork/QtNetwork>
#include <QtNetwork/QHttpRequestHeader>
#include <QDesktopServices>
#include <QtWebKit/QWebPage>

MyWebView::MyWebView(QWidget *parent)
    : QWebView(parent) {
/* 网页缓存机制, 这里没有使用 */
#if 0
    QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    manager = page()->networkAccessManager();
    QString location = QDesktopServices::storageLocation(QDesktopServices::CacheLocation);
    diskCache->setCacheDirectory(location);
    manager->setCache(diskCache);
    qDebug << diskCache->cacheDirectory() << diskCache->cacheSize();
    page()->setNetworkAccessManager(manager);
    page()->settings()->setMaximumPagesInCache(10);
    page()->settings()->setAttribute(QWebSettings::AutoLoadImages, true);
    page()->settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
#endif
    /* 如果需要访问flash网页,就必须开启下面这条,当然前提是你的机器上安装了flashplayer */
    settings()->setAttribute(QWebSettings::PluginsEnabled, true);
    settings()->setAttribute(QWebSettings::JavaEnabled, true);
    settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
    settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
    settings()->setAttribute(QWebSettings::JavascriptCanCloseWindows, true);
    settings()->setFontFamily(QWebSettings::SansSerifFont, "SansSerifFont");
    /* 当页面上的链接被点击的时候,可能会打开一个新窗口也可能是在原窗口中打开   */
    /* 这里我们需要一直在原窗口中打开链接,所以需要我们自己处理点击链接时的动作 */
    /* 设置DelegateAllLinks告知QWebView我们自己处理所有页面点击动作,并且   */
    /* 设置了对应的槽                                                   */
    page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
    connect(this, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClickedSlot(QUrl)));
}

MyWebView::~MyWebView() {

}
/* 当QWebView需要创建新窗口的时候会调用这个函数 */
QWebView *MyWebView::createWindow(QWebPage::WebWindowType type) {
    /* 如果开启下面3条,当页面链接被点击,创建一个新窗口, 原窗口不会消失 */
    //MyWebView *p = new MyWebView();
    //p->setGeometry(this->geometry());
    //p->show();
    /* 这里返回this,即复用当前窗口,不开启新窗口 */
    return this;
}

void MyWebView::linkClickedSlot(QUrl url) {
    load(url);
}

main.cpp

#include "MyBrowser.h"
#include <QApplication>
#include <QTextCodec>
#include <QtWebKit/QWebView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MyBrowser *browser = new MyBrowser(QUrl("http://www.vs.com.cn/"));
    browser->showFullScreen();

    return a.exec();
}