您的位置:首页 > 编程语言 > Qt开发

qt cef嵌入web

2016-06-27 10:53 676 查看

最近项目需要,研究了下libcef库,

Cef(Chromium Embedded Framework)简述

嵌入式Chromium框架(简称CEF) 是一个由Marshall Greenblatt在2008建立的开源项目,它主要目的是开发一个基于Google Chromium的Webbrowser控件。CEF支持一系列的编程语言和操作系统,并且能很容易地整合到新的或已有的工程中去。
它的设计思想政治就是易用且兼顾性能。CEF基本的框架包含C/C++程序接口,通过本地库的接口来实现,而这个库则会隔离宿主程序和Chromium&Webkit的操作细节。它在浏览器控件和宿主程序之间提供紧密的整合,它支持用户插件,协议,javascript对象以及javascript扩展,宿主程序可以随意地控件资源下载,导航和打印等,并且可以跟Google Chrome浏览器一起,支持高性能和Html5 技术。

Cef使用

首先下载cef库的源码,源码有2个大的版本,cef1和cef3,我使用的是cef3,因此cef1我就不过多解释,其实我也不太了解。刚开始使用的时候一定不能怕,可能有些人看了源码之后会发现源码异常的复杂,这个时候我建议网上多差点儿资料,因为我学的时候也是在网上找到了不少好的文章

extern CefRefPtr g_handler;
extern CefRefPtr g_appHandler;

const QString QCefWebView::kUrlBlank = "about:blank";

QCefWebView::QCefWebView(QWidget* parent)
: QWidget(parent),
browser_state_(kNone),
need_resize_(false),
need_load_(false)
{
setAttribute(Qt::WA_NativeWindow);
setAttribute(Qt::WA_DontCreateNativeAncestors);
}

QCefWebView::~QCefWebView()
{
}

void QCefWebView::load(const QUrl& url)
{
url_ = url;
switch (browser_state_)
{
case kNone:
CreateBrowser(size()); break;
case kCreating:
// If resizeEvent()/showEvent() before you load a url, it will
// CreateBrowser() as soon as possible with "about:blank".
need_load_ = true; break;
default:  // The browser should have been created.
BrowserLoadUrl(url);
}
}

void QCefWebView::setHtml(const QString& html, const QUrl& baseUrl)
{
if (GetBrowser().get())
{
QUrl url = baseUrl.isEmpty() ? this->url() : baseUrl;
if (!url.isEmpty())
{
CefRefPtr frame = GetBrowser()->GetMainFrame();
frame->LoadString(CefString(html.toStdWString()),
CefString(url.toString().toStdWString()));
}
}
}

QUrl QCefWebView::url() const {
if (GetBrowser().get())
{
CefString url = GetBrowser()->GetMainFrame()->GetURL();
return QUrl(QString::fromStdWString(url.ToWString()));
}
return QUrl();
}

void QCefWebView::back()
{
CefRefPtr browser = GetBrowser();
if (browser.get())
browser->GoBack();
}

void QCefWebView::forward()
{
CefRefPtr browser = GetBrowser();
if (browser.get())
browser->GoForward();
}

void QCefWebView::reload()
{
CefRefPtr browser = GetBrowser();
if (browser.get())
browser->Reload();
}

void QCefWebView::stop()
{

CefRefPtr browser = GetBrowser();
if (browser.get())
browser->StopLoad();
}

QVariant QCefWebView::evaluateJavaScript(const QString& scriptSource)
{
if (GetBrowser().get())
{
CefString code(scriptSource.toStdWString());
GetBrowser()->GetMainFrame()->ExecuteJavaScript(code, "", 0);
return true;
}
return false;
}

void QCefWebView::resizeEvent(QResizeEvent* e)
{
switch (browser_state_)
{
case kNone:
CreateBrowser(e->size()); break;
case kCreating:
need_resize_ = true; break;
default:
ResizeBrowser(e->size());
}
}

void QCefWebView::closeEvent(QCloseEvent* e)
{
if (g_handler.get() && !g_handler->IsClosing())
{
CefRefPtr browser = g_handler->GetBrowser();
if (browser.get())
{
browser->GetHost()->CloseBrowser(false);
}
}
e->accept();
}

void QCefWebView::showEvent(QShowEvent* e)
{
CreateBrowser(size());
}

void QCefWebView::customEvent(QEvent* e)
{
if (e->type() == MessageEvent::MessageEventType)
{
MessageEvent* event = static_cast(e);
QString name = event->name();
QVariantList args = event->args();
emit jsMessage(name, args);
}
}

void QCefWebView::OnAddressChange(const QString& url)
{
if (url != "about:blank")
{
emit urlChanged(QUrl(url));
}
}

void QCefWebView::OnTitleChange(const QString& title)
{
emit titleChanged(title);
}

void QCefWebView::SetLoading(bool isLoading)
{
if (isLoading)
{
if (!need_load_ && !url_.isEmpty())
emit loadStarted();
}
else
{
if (need_load_)
{
BrowserLoadUrl(url_);
need_load_ = false;
}
else if (!url_.isEmpty())
{
emit loadFinished(true);
}
}
}

void QCefWebView::SetNavState(bool canGoBack, bool canGoForward)
{
emit navStateChanged(canGoBack, canGoForward);
}

void QCefWebView::OnAfterCreated()
{
browser_state_ = kCreated;
if (need_resize_)
{
ResizeBrowser(size());
need_resize_ = false;
}
}

void QCefWebView::OnMessageEvent(MessageEvent* e)
{
QCoreApplication::postEvent(this, e, Qt::HighEventPriority);
}

void QCefWebView::OnWebRequest(const QString & order)
{
emit webRequest(order);
}

bool QCefWebView::CreateBrowser(const QSize& size)
{
if (browser_state_ != kNone || size.isEmpty())
{
return false;
}
mutex_.lock();
if (browser_state_ != kNone)
{
mutex_.unlock();
return false;
}
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = size.width();
rect.bottom = size.height();

CefWindowInfo info;
CefBrowserSettings settings;

info.SetAsChild((HWND)this->winId(), rect);

g_handler->set_listener(this);
g_appHandler->insertMainRenderDelegate(this);

QString url = url_.isEmpty() ? kUrlBlank : url_.toString();
CefBrowserHost::CreateBrowser(info,
g_handler.get(),
CefString(url.toStdWString()),
settings,
NULL);

browser_state_ = kCreating;
mutex_.unlock();
return true;
}

CefRefPtr QCefWebView::GetBrowser() const
{
CefRefPtr browser;
if (g_handler.get())
browser = g_handler->GetBrowser();
return browser;
}

void QCefWebView::ResizeBrowser(const QSize& size)
{
if (g_handler.get() && g_handler->GetBrowser())
{
CefWindowHandle hwnd =
g_handler->GetBrowser()->GetHost()->GetWindowHandle();
if (hwnd)
{
HDWP hdwp = BeginDeferWindowPos(1);
hdwp = DeferWindowPos(hdwp, hwnd, NULL,
0, 0, size.width(), size.height(),
SWP_NOZORDER);
EndDeferWindowPos(hdwp);
}
}
}

bool QCefWebView::BrowserLoadUrl(const QUrl& url)
{
if (!url.isEmpty() && GetBrowser().get())
{
CefString cefurl(url_.toString().toStdWString());
GetBrowser()->GetMainFrame()->LoadURL(cefurl);
return true;
}
return false;
}

void QCefWebView::OnContextCreated(CefRefPtr app
, CefRefPtr browser
, CefRefPtr frame
, CefRefPtr context)
{
CefRefPtr object = context->GetGlobal();

CefRefPtr myV8Acc = new QCefV8Accessor;
CefRefPtr val = CefV8Value::CreateString(L"videoHandler");
CefString cefException;
myV8Acc->Set(L"videoHandler", object, val, cefException);
CefRefPtr pObjApp = CefV8Value::CreateObject(myV8Acc);
object->SetValue(L"videoHandler", pObjApp, V8_PROPERTY_ATTRIBUTE_NONE);

CefRefPtr mapHandler = new CefMapV8Handler(g_appHandler);

CefRefPtr ExecuteRequestOrder =
CefV8Value::CreateFunction("ExecuteRequestOrder", mapHandler);

object->SetValue("ExecuteRequestOrder", ExecuteRequestOrder, V8_PROPERTY_ATTRIBUTE_NONE);
}


View Code

注意:以上代码只提供了一个思路,还有部分处理代码我没有贴出来,但是在论述的时候我都已经提到了,有C++基础的就基本可以搞定了,上述功能完成后就基本可以实现嵌入web的功能了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: