QcefView:一个集成了CEF的Qt Widget

QcefView:一个集成了CEF的Qt Widget

官方网址:http://tishion.github.io/QCefView/
Github地址:https://github.com/tishion/QCefView
QCefView是一个与Chromium Embedded Framework集成的Qt小部件。 
您可以使用QCefView而无需编写任何与CEF代码相关的代码。 
这个Qt小部件是分布在二进制模块和LGPL许可的。
现在您可以尝试使用QCefView来开发您的应用程序,像使用其他QWidgets一样使用它。 QCefView小部件提供了几种方法来在本地C ++代码和Web代码之间进行通信。 
您不需要编写通信业务逻辑。
首先将cef_binary_3.2704.1414.g185cd6c_windows64(或其他版本)解压再dep目录下
使用Cmake-gui工具配置生成sln工程文件
使用对应的VS打开sln进行编译构建,QCefView.lib以及QCefView.dll最后生成在out对应的目录下

QcefView:一个集成了CEF的Qt Widget

详情请参考官方文档以及之前的文章。 
基于QCefView的浏览器应用程序例子代码:Qt Creator工程
在工程目录下新建文件夹QCefViewSDK,将QCefView-master/out/QCefView下的include文件夹和lib文件夹拷贝在CefViewSDK目录下。
MSVC2017 64bit构建工程,将QCefView-master/out/QCefView/bin中对应配置的文件全部拷贝到输出目录中,在其中新建web文件夹,拷贝QCefViewTestPage.html到其中。

 qtCefView 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = qtCefView
TEMPLATE = app


SOURCES += main.cpp
        mainwindow.cpp 
        qtcefview.cpp

HEADERS  += mainwindow.h 
        qtcefview.h

FORMS    += mainwindow.ui

LIBS += user32.lib

# lib qcefview
win32: LIBS += -L$$PWD/QCefViewSDK/lib/Release/ -lQCefView

INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
 QtCefView.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
 
#ifndef MYCEFVIEW_H
#define MYCEFVIEW_H

#include <QtCore>
#include <QtGui>
#include "QCefViewSDK/include/QCefView.h"

class QtCefView : public QCefView
{
public:
    QtCefView(const QString url, QWidget *parent = nullptr);

    // QCefView interface
protected slots:
    void onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward) override;
    void onLoadStart() override;
    void onLoadEnd(int httpStatusCode) override;
    void onLoadError(int errorCode, const QString &errorMsg, const QString &failedUrl) override;
    void onQCefUrlRequest(const QString &url) override;
    void onQCefQueryRequest(const QCefQuery &query) override;
    void onInvokeMethodNotify(int browserId, int frameId, const QString &method, const QVariantList &arguments) override;
};

#endif // MYCEFVIEW_H
 QtCefView.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 
#include "QtCefView.h"
#include "Windows.h"

QtCefView::QtCefView(const QString url, QWidget *parent):
    QCefView(url, parent)
{

}

void QtCefView::onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward)
{
    qDebug() << "isLoading:" << isLoading << "canGoBack" << canGoBack << "canGoForward" << canGoForward;
}

void QtCefView::onLoadStart()
{
    qDebug() << "onLoadStart";
}

void QtCefView::onLoadEnd(int httpStatusCode)
{
    qDebug() << "onLoadEnd" << httpStatusCode;
}

void QtCefView::onLoadError(int errorCode, const QString &errorMsg, const QString &failedUrl)
{
    qDebug() << "onLoadError" << errorCode << errorMsg << failedUrl;
}

void QtCefView::onQCefUrlRequest(const QString &url)
{
    qDebug() << "onQCefUrlRequest" << url;
}

void QtCefView::onQCefQueryRequest(const QCefQuery &query)
{
    qDebug() << "onQCefQueryRequest" << query.id() << query.reqeust();

    QString text = QString(
                       "Current Msg From: mycefview main thread "
                       "Query: %1").arg(query.reqeust());

    query.setResponseResult(true, text);
    responseQCefQuery(query);
}

void QtCefView::onInvokeMethodNotify(int browserId, int frameId, const QString &method, const QVariantList &arguments)
{
    qDebug() << "onInvokeMethodNotify" << browserId << frameId << method << arguments;

    if (0 == method.compare("onDragAreaMouseDown"))
    {
        HWND hWnd = ::GetAncestor((HWND)getCefWinId(), GA_ROOT);

        // get current mouse cursor position
        POINT pt;
        ::GetCursorPos(&pt);

        // in case the mouse is being captured, try to release it
        ::ReleaseCapture();

        // simulate that the mouse left button is down on the title area
        ::SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, POINTTOPOINTS(pt));
        return;
    }

    QString title("QCef InvokeMethod Notify");
    QString text = QString(
                       "Current Thread: mycefview main thread "
                       "Method: %1 "
                       "Arguments: ...")
                   .arg(method);

    QMessageBox::information(this->window(), title, text);
}
 mainwindow.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
 
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtCore>
#include <QtGui>
#include "QtCefView.h"
#include <QLineEdit>
#include <QPushButton>

namespace Ui
{
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void slot_btn_go();

private slots:
    void on_actionTest_triggered();

private:
    Ui::MainWindow      *ui;
    QtCefView           *m_pCefView;
    QLineEdit           *m_pEditUrl;
    QPushButton         *m_pBtnGo;

};

#endif // MAINWINDOW_H
 mainwindow.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
 
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // add url
    m_pEditUrl = new QLineEdit("http://www.baidu.com", this);
    ui->mainToolBar->addWidget(m_pEditUrl);
    // add go button
    m_pBtnGo = new QPushButton("Go", this);
    ui->mainToolBar->addWidget(m_pBtnGo);
    connect(m_pBtnGo, SIGNAL(clicked(bool)), this, SLOT(slot_btn_go()));
    // add cef view
    QDir dir = QCoreApplication::applicationDirPath();
    QString uri = QDir::toNativeSeparators(dir.filePath("web\QCefViewTestPage.html"));
    m_pEditUrl->setText(uri);
    m_pCefView = new QtCefView(uri, this);
    ui->centralLayout->addWidget(m_pCefView);
}

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

void MainWindow::slot_btn_go()
{
    QString strUrl = m_pEditUrl->text();
    QUrl urlCheck(strUrl);
    if(urlCheck.isValid())
    {
        m_pCefView->navigateToUrl(strUrl);
    }
    else
    {
        qDebug() << strUrl << "is unvalid!";
    }
}

void MainWindow::on_actionTest_triggered()
{
    qsrand(::GetTickCount());
    QColor color(qrand());

    QCefEvent event("colorChangedEvent");
    event.setStringProperty("color", color.name());
    m_pCefView->broadcastEvent("colorChange", event);
}
 mainwindow.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
 
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <property name="styleSheet">
   <string notr="true"/>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="centralLayout">
    <property name="spacing">
     <number>0</number>
    </property>
    <property name="leftMargin">
     <number>1</number>
    </property>
    <property name="topMargin">
     <number>1</number>
    </property>
    <property name="rightMargin">
     <number>1</number>
    </property>
    <property name="bottomMargin">
     <number>1</number>
    </property>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>23</height>
    </rect>
   </property>
   <widget class="QMenu" name="menu">
    <property name="title">
     <string>菜单</string>
    </property>
    <addaction name="actionTest"/>
   </widget>
   <addaction name="menu"/>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <action name="actionTest">
   <property name="text">
    <string>改变颜色</string>
   </property>
   <property name="toolTip">
    <string>测试的Tip</string>
   </property>
  </action>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>
 main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
 
#include "mainwindow.h"
#include <QApplication>

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

    MainWindow w;
    w.show();

    return a.exec();
}

 运行展示:

QcefView:一个集成了CEF的Qt Widget

希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯分享时的吝啬。

官方网址:http://tishion.github.io/QCefView/
Github地址:https://github.com/tishion/QCefView
QCefView是一个与Chromium Embedded Framework集成的Qt小部件。 
您可以使用QCefView而无需编写任何与CEF代码相关的代码。 
这个Qt小部件是分布在二进制模块和LGPL许可的。
现在您可以尝试使用QCefView来开发您的应用程序,像使用其他QWidgets一样使用它。 QCefView小部件提供了几种方法来在本地C ++代码和Web代码之间进行通信。 
您不需要编写通信业务逻辑。
首先将cef_binary_3.2704.1414.g185cd6c_windows64(或其他版本)解压再dep目录下
使用Cmake-gui工具配置生成sln工程文件
使用对应的VS打开sln进行编译构建,QCefView.lib以及QCefView.dll最后生成在out对应的目录下

QcefView:一个集成了CEF的Qt Widget

详情请参考官方文档以及之前的文章。 
基于QCefView的浏览器应用程序例子代码:Qt Creator工程
在工程目录下新建文件夹QCefViewSDK,将QCefView-master/out/QCefView下的include文件夹和lib文件夹拷贝在CefViewSDK目录下。
MSVC2017 64bit构建工程,将QCefView-master/out/QCefView/bin中对应配置的文件全部拷贝到输出目录中,在其中新建web文件夹,拷贝QCefViewTestPage.html到其中。

 qtCefView 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = qtCefView
TEMPLATE = app


SOURCES += main.cpp
        mainwindow.cpp 
        qtcefview.cpp

HEADERS  += mainwindow.h 
        qtcefview.h

FORMS    += mainwindow.ui

LIBS += user32.lib

# lib qcefview
win32: LIBS += -L$$PWD/QCefViewSDK/lib/Release/ -lQCefView

INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
 QtCefView.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
 
#ifndef MYCEFVIEW_H
#define MYCEFVIEW_H

#include <QtCore>
#include <QtGui>
#include "QCefViewSDK/include/QCefView.h"

class QtCefView : public QCefView
{
public:
    QtCefView(const QString url, QWidget *parent = nullptr);

    // QCefView interface
protected slots:
    void onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward) override;
    void onLoadStart() override;
    void onLoadEnd(int httpStatusCode) override;
    void onLoadError(int errorCode, const QString &errorMsg, const QString &failedUrl) override;
    void onQCefUrlRequest(const QString &url) override;
    void onQCefQueryRequest(const QCefQuery &query) override;
    void onInvokeMethodNotify(int browserId, int frameId, const QString &method, const QVariantList &arguments) override;
};

#endif // MYCEFVIEW_H
 QtCefView.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 
#include "QtCefView.h"
#include "Windows.h"

QtCefView::QtCefView(const QString url, QWidget *parent):
    QCefView(url, parent)
{

}

void QtCefView::onLoadingStateChanged(bool isLoading, bool canGoBack, bool canGoForward)
{
    qDebug() << "isLoading:" << isLoading << "canGoBack" << canGoBack << "canGoForward" << canGoForward;
}

void QtCefView::onLoadStart()
{
    qDebug() << "onLoadStart";
}

void QtCefView::onLoadEnd(int httpStatusCode)
{
    qDebug() << "onLoadEnd" << httpStatusCode;
}

void QtCefView::onLoadError(int errorCode, const QString &errorMsg, const QString &failedUrl)
{
    qDebug() << "onLoadError" << errorCode << errorMsg << failedUrl;
}

void QtCefView::onQCefUrlRequest(const QString &url)
{
    qDebug() << "onQCefUrlRequest" << url;
}

void QtCefView::onQCefQueryRequest(const QCefQuery &query)
{
    qDebug() << "onQCefQueryRequest" << query.id() << query.reqeust();

    QString text = QString(
                       "Current Msg From: mycefview main thread "
                       "Query: %1").arg(query.reqeust());

    query.setResponseResult(true, text);
    responseQCefQuery(query);
}

void QtCefView::onInvokeMethodNotify(int browserId, int frameId, const QString &method, const QVariantList &arguments)
{
    qDebug() << "onInvokeMethodNotify" << browserId << frameId << method << arguments;

    if (0 == method.compare("onDragAreaMouseDown"))
    {
        HWND hWnd = ::GetAncestor((HWND)getCefWinId(), GA_ROOT);

        // get current mouse cursor position
        POINT pt;
        ::GetCursorPos(&pt);

        // in case the mouse is being captured, try to release it
        ::ReleaseCapture();

        // simulate that the mouse left button is down on the title area
        ::SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, POINTTOPOINTS(pt));
        return;
    }

    QString title("QCef InvokeMethod Notify");
    QString text = QString(
                       "Current Thread: mycefview main thread "
                       "Method: %1 "
                       "Arguments: ...")
                   .arg(method);

    QMessageBox::information(this->window(), title, text);
}
 mainwindow.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
 
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtCore>
#include <QtGui>
#include "QtCefView.h"
#include <QLineEdit>
#include <QPushButton>

namespace Ui
{
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void slot_btn_go();

private slots:
    void on_actionTest_triggered();

private:
    Ui::MainWindow      *ui;
    QtCefView           *m_pCefView;
    QLineEdit           *m_pEditUrl;
    QPushButton         *m_pBtnGo;

};

#endif // MAINWINDOW_H
 mainwindow.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
 
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // add url
    m_pEditUrl = new QLineEdit("http://www.baidu.com", this);
    ui->mainToolBar->addWidget(m_pEditUrl);
    // add go button
    m_pBtnGo = new QPushButton("Go", this);
    ui->mainToolBar->addWidget(m_pBtnGo);
    connect(m_pBtnGo, SIGNAL(clicked(bool)), this, SLOT(slot_btn_go()));
    // add cef view
    QDir dir = QCoreApplication::applicationDirPath();
    QString uri = QDir::toNativeSeparators(dir.filePath("web\QCefViewTestPage.html"));
    m_pEditUrl->setText(uri);
    m_pCefView = new QtCefView(uri, this);
    ui->centralLayout->addWidget(m_pCefView);
}

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

void MainWindow::slot_btn_go()
{
    QString strUrl = m_pEditUrl->text();
    QUrl urlCheck(strUrl);
    if(urlCheck.isValid())
    {
        m_pCefView->navigateToUrl(strUrl);
    }
    else
    {
        qDebug() << strUrl << "is unvalid!";
    }
}

void MainWindow::on_actionTest_triggered()
{
    qsrand(::GetTickCount());
    QColor color(qrand());

    QCefEvent event("colorChangedEvent");
    event.setStringProperty("color", color.name());
    m_pCefView->broadcastEvent("colorChange", event);
}
 mainwindow.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
 
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <property name="styleSheet">
   <string notr="true"/>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="centralLayout">
    <property name="spacing">
     <number>0</number>
    </property>
    <property name="leftMargin">
     <number>1</number>
    </property>
    <property name="topMargin">
     <number>1</number>
    </property>
    <property name="rightMargin">
     <number>1</number>
    </property>
    <property name="bottomMargin">
     <number>1</number>
    </property>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>23</height>
    </rect>
   </property>
   <widget class="QMenu" name="menu">
    <property name="title">
     <string>菜单</string>
    </property>
    <addaction name="actionTest"/>
   </widget>
   <addaction name="menu"/>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <action name="actionTest">
   <property name="text">
    <string>改变颜色</string>
   </property>
   <property name="toolTip">
    <string>测试的Tip</string>
   </property>
  </action>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>
 main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
 
#include "mainwindow.h"
#include <QApplication>

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

    MainWindow w;
    w.show();

    return a.exec();
}

 运行展示:

QcefView:一个集成了CEF的Qt Widget