Windows下Qt Creator中使用cef的一个学习例子

Posted 我来乔23

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows下Qt Creator中使用cef的一个学习例子相关的知识,希望对你有一定的参考价值。

参考:https://blog.csdn.net/qq_31683775/article/details/84025025


qt中集成cef浏览器例子qtCefBrowser
参考上上篇文章,vs2017编译生成:libcef_dll_wrapper.lib(静态库,debug-MDd,release-MD)

 

qtCefBrowser工程结构如下:

qt代码如下:

 

qtCefBrowser.pro 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 
#-------------------------------------------------
#
# Project created by QtCreator 2020-01-08T09:18:32
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 
4): QT += widgets

TARGET = cefBrowser
TEMPLATE = app

# The following define makes your compiler emit warnings 
if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS


SOURCES += main.cpp\\
    simple_app.cc \\
    simple_handler.cc \\
    widget.cpp

HEADERS  += simple_app.h \\
    simple_handler.h \\
    widget.h

CONFIG += debug_and_release

FORMS    += widget.ui

INCLUDEPATH+=$$PWD/cef/

LIBS += shell32.lib \\
kernel32.lib \\
user32.lib \\
ole32.lib \\
oleaut32.lib \\
gdi32.lib

CONFIG(debug, debug|release) {
    LIBS += $$PWD/cef/lib/debug/libcef.lib              \\
            $$PWD/cef/lib/debug/libcef_dll_wrapper.lib  \\
}
else{
    LIBS += $$PWD/cef/lib/release/libcef.lib              \\
            $$PWD/cef/lib/release/libcef_dll_wrapper.lib  \\
}

RC_FILE += icon.rc
simple_app.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#ifndef CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_
#define CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_

#include "include/cef_app.h"

// Implement application-level callbacks for the browser process.
class SimpleApp : public CefApp,
                  
public CefBrowserProcessHandler {
 
public:
   SimpleApp();

  
// CefApp methods:
  virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()
      OVERRIDE { 
return this; }

  
// CefBrowserProcessHandler methods:
  virtual void OnContextInitialized() OVERRIDE;
  
void OnBeforeCommandLineProcessing(const CefString & process_type, CefRefPtr<CefCommandLine> command_line);
 
private:
  
// Include the default reference counting implementation.
  IMPLEMENT_REFCOUNTING(SimpleApp);
};

#endif  // CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_
simple_app.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "simple_app.h"

#include <string>

#include "simple_handler.h"
#include "include/cef_browser.h"
#include "include/cef_command_line.h"
#include "include/wrapper/cef_helpers.h"

SimpleApp::SimpleApp()
{
}

void SimpleApp::OnContextInitialized()
{
    CEF_REQUIRE_UI_THREAD();

}
void SimpleApp::OnBeforeCommandLineProcessing(const CefString &process_type, CefRefPtr<CefCommandLine> command_line)
{
    
//加载flash插件
    command_line->AppendSwitch("--enable-npapi");
    command_line->AppendSwitchWithValue(
"--ppapi-flash-path""ppflash/pepflashplayer32_32_0_0_303.dll");
    
//manifest.json中的version
    command_line->AppendSwitchWithValue("--ppapi-flash-version""32.0.0.303");
    command_line->AppendSwitch(
"--disable-extensions");
}
 simple_handler.h 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
 
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#ifndef CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_
#define CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_

#include "include/cef_client.h"
#include <list>
// List of existing browser windows. Only accessed on the CEF UI thread.
typedef std::list<CefRefPtr<CefBrowser> > BrowserList;
class Widget;
class SimpleHandler : public CefClient,
    
public CefDisplayHandler,
    
public CefLifeSpanHandler,
    
public CefLoadHandler
{
public:
    SimpleHandler(Widget *widget);
    ~SimpleHandler();

    
// Provide access to the single global instance of this object.
    static SimpleHandler *GetInstance();

    
// CefClient methods:
    virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE
    {
        
return this;
    }
    
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE
    {
        
return this;
    }
    
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE
    {
        
return this;
    }


    
// CefLifeSpanHandler methods:
    virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
    
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
    
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;

    
// CefLoadHandler methods:
    virtual void OnLoadError(CefRefPtr<CefBrowser> browser,
                             CefRefPtr<CefFrame> frame,
                             ErrorCode errorCode,
                             
const CefString &errorText,
                             
const CefString &failedUrl) OVERRIDE;

    
// Request that all existing browser windows close.
    void CloseAllBrowsers(bool force_close);

    
bool IsClosing() const
    {
        
return is_closing_;
    }
    BrowserList GetBrowserList()
    {
        
return browser_list_;
    }
private:
    BrowserList browser_list_;
    Widget *widget;

    
bool is_closing_;

    
// Include the default reference counting implementation.
    IMPLEMENT_REFCOUNTING(SimpleHandler);
};

#endif  // CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_
 simple_handler.cc 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "simple_handler.h"

#include <sstream>
#include <string>

#include "include/base/cef_bind.h"
#include "include/cef_app.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_helpers.h"
#include "widget.h"
namespace
{
    SimpleHandler *g_instance = 
NULL;
}  
// namespace

SimpleHandler::SimpleHandler(Widget *w)
    : is_closing_(
false)
{
    DCHECK(!g_instance);
    g_instance = 
this;
    
this->widget = w;
}

SimpleHandler::~SimpleHandler()
{
    g_instance = 
NULL;
}

// static
SimpleHandler *SimpleHandler::GetInstance()
{
    
return g_instance;
}

void SimpleHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
    CEF_REQUIRE_UI_THREAD();

    
// Add to the list of existing browsers.
    browser_list_.push_back(browser);
    
int
 nID = browser->GetIdentifier();
    widget->browserId = nID;
}

bool SimpleHandler::DoClose(CefRefPtr<CefBrowser> browser)
{
    CEF_REQUIRE_UI_THREAD();

    
// Closing the main window requires special handling. See the DoClose()
    // documentation in the CEF header for a detailed destription of this
    // process.
    if (browser_list_.size() == 1)
    {
        
// Set a flag to indicate that the window close should be allowed.
        is_closing_ = true;
    }

    
// Allow the close. For windowed browsers this will result in the OS close
    // event being sent.
    return false;
}

void SimpleHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
    CEF_REQUIRE_UI_THREAD();

    
// Remove from the list of existing browsers.
    BrowserList::iterator bit = browser_list_.begin();
    
for (; bit != browser_list_.end(); ++bit)
    {
        
if ((*bit)->IsSame(browser))
        {
            browser_list_.erase(bit);
            
break;
        }
    }

    
if (browser_list_.empty())
    {
        
// All browser windows have closed. Quit the application message loop.
        CefQuitMessageLoop();
    }
}

void SimpleHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                ErrorCode errorCode,
                                
const CefString &errorText,
                                
const CefString &failedUrl)
{
    CEF_REQUIRE_UI_THREAD();

    
// Don\'t display an error for downloaded files.
    if (errorCode == ERR_ABORTED)
        
return;

    
// Display a load error message.
    std::stringstream ss;
    ss << 
"<html><body bgcolor=\\"white\\">"
       
"<h2>Failed to load URL " << std::string(failedUrl) <<
       
" with error " << std::string(errorText) << " (" << errorCode <<
       
").</h2></body></html>";
    frame->LoadString(ss.str(), failedUrl);
}

void SimpleHandler::CloseAllBrowsers(bool force_close)
{
    
if (!CefCurrentlyOn(TID_UI))
    {
        
// Execute on the UI thread.
        CefPostTask(TID_UI,
                    base::Bind(&SimpleHandler::CloseAllBrowsers, 
this, force_close));
        
return;
    }

    
if (browser_list_.empty())
        
return;

    BrowserList::const_iterator it = browser_list_.begin();
    
for (; it != browser_list_.end(); ++it)
        (*it)->GetHost()->CloseBrowser(force_close);
}
 widget.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "simple_handler.h"
namespace Ui
{
    
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
public:
    
explicit Widget(QWidget *parent = nullptr);
    ~Widget();
    
int browserId;

private:
    Ui::Widget *ui;
    CefRefPtr<SimpleHandler> m_browserEvent;
    CefRefPtr<CefBrowser> GetBrowserByID(
int nWebBrowserID);

public slots:
    
void onUrl();

};

#endif // WIDGET_H
 widget.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 
#include "widget.h"
#include "ui_widget.h"
#include <QDesktopWidget>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(
new Ui::Widget)
{
    ui->setupUi(
this);
    HWND wnd = (HWND)ui->widget->winId();

    CefWindowInfo cefWndInfo;
    QString strUrl = 
"https://www.baidu.com";
    RECT winRect;

    QDesktopWidget *pDeskTop = QApplication::desktop();
    QRect qtRect = pDeskTop->screenGeometry();
    winRect.left = qtRect.left();
    winRect.top = qtRect.top();
    winRect.right = qtRect.right();
    winRect.bottom = qtRect.bottom();

    
//将cef界面嵌入qt界面中
    cefWndInfo.SetAsChild(wnd, winRect);

    CefBrowserSettings cefBrowSetting;
    m_browserEvent = CefRefPtr<SimpleHandler>(
new SimpleHandler(this));
    
bool browser = CefBrowserHost::CreateBrowser(cefWndInfo, m_browserEvent, strUrl.toStdString(), cefBrowSetting, NULL);
    connect(ui->goButton, SIGNAL(clicked()), 
this, SLOT(onUrl()));
    showMaximized();
}

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

CefRefPtr<CefBrowser> Widget::GetBrowserByID(
int nWebBrowserID)
{
    BrowserList browserList = m_browserEvent->GetBrowserList();
    
for (auto it = browserList.begin();
            it != browserList.end();
            ++it)
    {
        
if (nWebBrowserID == it->get()->GetIdentifier())
        {
            
return it->get();
        }
    }

    
return nullptr;
}

void Widget::onUrl()
{
    CefRefPtr<CefBrowser> brower = GetBrowserByID(browserId);
    
if (nullptr != brower)
    {
        brower->GetMainFrame()->LoadURL(ui->lineEdit->text().toStdString());
    }
}
widget.ui 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
 
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>711</width>
    <height>371</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>qt cef browser</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <property name="spacing">
    <number>0</number>
   </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="QWidget" name="toolbar" native="true">
     <property name="minimumSize">
      <size>
       <width>0</width>
       <height>40</height>
      </size>
     </property>
     <property name="maximumSize">
      <size>
       <width>16777215</width>
       <height>40</height>
      </size>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <property name="spacing">
       <number>0</number>
      </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="QLineEdit" name="lineEdit">
        <property name="minimumSize">
         <size>
          <width>0</width>
          <height>40</height>
         </size>
        </property>
        <property name="maximumSize">
         <size>
          <width>16777215</width>
          <height>40</height>
         </size>
        </property>
        <property name="styleSheet">
         <string notr="true">font-size:16px;</string>
        </property>
        <property name="text">
         <string>http://www.baidu.com</string>
        </property>
        <property name="placeholderText">
         <string>Please input URL...</string>
        </property>
        <property name="clearButtonEnabled">
         <bool>true</bool>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="goButton">
        <property name="minimumSize">
         <size>
          <width>0</width>
          <height>40</height>
         </size>
        </property>
        <property name="maximumSize">
         <size>
          <width>16777215</width>
          <height>40</height>
         </size>
        </property>
        <property name="styleSheet">
         <string notr="true">font-size:15px;
font: 16pt "Arial";</string>
        </property>
        <property name="text">
         <string>Go</string>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
   </item>
   <item>
    <widget class="QWidget" name="widget" native="true"/>
   </item>
  </layout>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

 构建运行:

 

以上是关于Windows下Qt Creator中使用cef的一个学习例子的主要内容,如果未能解决你的问题,请参考以下文章

在 Qt Creator (Windows) 中构建 Qt 库的问题

关于windows下QT以及QT creator的安装

在windows下用qt写的程序的中文注释在Ubuntu下qt creator显示乱码

在 Mac OS 下使用 Qt-creator 调试时如何进入 Qt 的源代码

如何向 Qt Creator 添加新工具包

QT creator+OpenCV2.4.2+MinGW 在windows下开发环境配置