• 【小沐学QT】QT学习之Web控件的使用


    1、简介

    1.1 Qt简介

    Qt Creator是跨平台的集成开发环境(IDE),旨在为开发者带来最好的体验。Qt Creator 可在 Windows,Linux 和 macOS 桌面操作系统上运行,并允许开发者在桌面、移动和嵌入式平台上创建软件。
    在这里插入图片描述
    Qt(官方发音 [kju:t],音同 cute)是一个跨平台的 C++ 开发库,主要用来开发图形用户界面(Graphical User Interface,GUI)程序,当然也可以开发不带界面的命令行(Command User Interface,CUI)程序。

    1.2 Qt下载和安装

    Qt5.15开始,无论是开源版还是商业版都采用了在线安装的方式。不再提供离线包。这里下载Qt5.14进行学习。

    1.3 Qt快捷键

    • 基本快捷键
    新建文件或项目(N) :Ctrl + N 
    关闭当前窗口/关闭当前文件 :Ctrl + W
    关闭所有文件:Ctrl + Shfit + W 
    关闭当前文件:(windows) Ctrl + F4
    运行: Ctrl + R 
    返回上一级(返回),常用于 跳转代码: Alt + ←(方向左键) 
    进入下一级(前进),常用于 跳转代码: Alt + →(方向右键)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 常用快捷键
    自动排版对齐代码:Ctrl + I 
    减小字体大小:Ctrl+- (Ctrl+鼠标滚轮向下) 
    增加字体大小:Ctrl++ (Ctrl+鼠标滚轮向上)
    重置字体大小:Ctrl+0
    折叠:Ctrl+< 
    展开:Ctrl+>
    复制行:Ctrl+Ins
    复制到行下:Ctrl+Alt+Down
    复制到行上:Ctrl+Alt+Up
    在当前行上方插入新行:Ctrl+Shift+Enter
    在当前行下方插入新行:Ctrl+Enter
    查看剪切板历史:Ctrl+Shift+V
    剪切行:Shift+Del
    追加行:Ctrl+J
    向下移动当前行:Ctrl+Shift+Down
    向上移动当前行:Ctrl+Shift+Up
    切换函数声明/定义: Ctrl + 鼠标左键/Shift + F2 
    编辑信号和槽:F4
    跳转至以}结尾的块:Ctrl+} 
    跳转至以{开始的块:Ctrl+{
    打开类型层次窗口:Ctrl+Shift+T
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 自定义快捷键

    在这里插入图片描述

    1.4 Qt帮助

    Qt Creator帮助文档在安装包里,在安装Qt时就安在了“安装目录/Qt5.14.2\Docs\Qt-5.14.2”。
    在这里插入图片描述
    点击左侧帮助-》选择下拉“索引”输入QOpenGL,下面会出现匹配的结果记录,点击搜索到的QOpenGLBuffer,在右侧显示出搜索出的帮助文档内容。
    在这里插入图片描述

    2、Qt+Web控件

    使用QT程序可以访问web页面,但不同QT版本中使用的类和方法不同:

    Qt4中使用webkit模块;
    Qt5~Qt5.5使用webkitwidgets模块;
    Qt5.6以上版本使用webenginewidgets模块。
    
    • 1
    • 2
    • 3

    2.1 测试代码1(QApplication)

    新建Console项目如下:
    在这里插入图片描述

    • untitled1.pro
    QT     += core gui widgets webenginewidgets network
    CONFIG += c++11
    DEFINES += QT_DEPRECATED_WARNINGS
    
    SOURCES += \
            main.cpp
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    RESOURCES += \
        html.qrc
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • main.cpp
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QApplication app(argc, argv);
    
        QWidget window;
        QVBoxLayout* layout = new QVBoxLayout(&window);
        QWebEngineView* view = new QWebEngineView(&window);
        QUrl baseUrl = "file:///" + QCoreApplication::applicationDirPath() + "/dist/test.html";
        //view->setUrl(QUrl("https://www.google.com/maps"));
        //view->setUrl(QUrl("https://www.baidu.com"));
        //view->setUrl(QUrl("file:///E:/work/index.html"));
        view->setUrl(QUrl("qrc:/new/prefix1/test.html"));
    
        // 连接页面加载完成信号
        QObject::connect(view, &QWebEngineView::loadFinished, [&view]()
        {
            // 执行一些 JS 代码,例如设置地图中心点和缩放级别
            //QString js = QString("var latLng = new google.maps.LatLng(40.758896, -73.985130);"
            //      "var mapOptions = { center: latLng, zoom: 13 };"
             //     "new google.maps.Map(document.getElementById('map'), mapOptions);");
            //view->page()->runJavaScript(js);
    
            QString jsCode = QString("var map = new Microsoft.Maps.Map('#myMap',{});"
                    "map.setView({center: new Microsoft.Maps.Location(32.027222, 114.0225), zoom: 8});");
            view->page()->runJavaScript(jsCode);
        });
    
        layout->addWidget(view);
        window.resize(700, 500);
        window.show();
    
        return app.exec();
    }
    
    • 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
    • index.html
    DOCTYPE html>
    <html>
    <head>
        <title>title>
        <meta charset="utf-8" />
        
        <script type='text/javascript'
                src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=[your bing key]'
                async defer>script>
        <script type='text/javascript'>
        function GetMap()
        {
            var map = new Microsoft.Maps.Map('#myMap',{});
            //在此添加地图加载代码
        }
        script>
    head>
    <body>
        <div id="myMap" style="position:relative;width:600px;height:400px;">div>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    2.2 测试代码2(QApplication+QWidget)

    新建QWidget项目:
    在这里插入图片描述
    在这里插入图片描述

    • untitled2.pro
    QT       += core gui webenginewidgets
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    CONFIG += c++11
    DEFINES += QT_DEPRECATED_WARNINGS
    
    SOURCES += \
        main.cpp \
        widget.cpp
    
    HEADERS += \
        widget.h
    
    FORMS += \
        widget.ui
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • main.cpp
    #include "widget.h"
    #include 
    
    int main(int argc, char *argv[])
    {
    	QApplication::setAttribute(Qt::AA_UseOpenGLES);
        QApplication a(argc, argv);
        Widget w;
        w.show();
        return a.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • widget.h
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include 
    #include 
    #include 
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class Widget; }
    QT_END_NAMESPACE
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
    
        QWebEngineView    *m_WebView;
        QWebChannel       *m_pWebChannel;
    
    public slots:
        void onLoadFinished();
    
    private:
        Ui::Widget *ui;
    };
    #endif // 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
    • widget.cpp
    #include "widget.h"
    #include "ui_widget.h"
    #include 
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        m_WebView = new QWebEngineView(this);
    //    view->resize(500, 500);
        QVBoxLayout* layout = new QVBoxLayout(this);
        layout->addWidget(m_WebView);
    //    layout->addStretch();
    
        m_pWebChannel = new QWebChannel(this);
    
        m_pWebChannel->registerObject(QString("webobj"), this);
        m_WebView->page()->setWebChannel(m_pWebChannel);
    
        connect(m_WebView, &QWebEngineView::loadFinished, this, &Widget::onLoadFinished);
    
        m_WebView->load(QUrl(QStringLiteral("http://www.baidu.com")));
        //view->showMaximized();
    
    }
    
    Widget::~Widget()
    {
        delete ui;
        delete m_WebView;
    }
    
    void Widget::onLoadFinished()
    {
       QString jsStr = QString("initData('test', 1, 2, 3)");
       m_WebView->page()->runJavaScript("alert('hello world!')");
    }
    
    
    • 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
    • 运行如下:
      在这里插入图片描述

    2.3 测试代码3(QApplication+QMainWindow)

    新建QMainWindow项目如下:
    在这里插入图片描述
    在这里插入图片描述

    • untitled3.pro
    QT       += core gui webenginewidgets
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    CONFIG += c++11
    DEFINES += QT_DEPRECATED_WARNINGS
    
    SOURCES += \
        main.cpp \
        mainwindow.cpp
    
    HEADERS += \
        mainwindow.h
    
    FORMS += \
        mainwindow.ui
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • main.cpp
    #include "mainwindow.h"
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • mainwindow.h:
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • mainwindow.cpp:
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include 
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        QWebEngineView *map=new QWebEngineView(this);
        map->load(QUrl("file:///C:/Users/tomcat/Desktop/test.html"));
        map->resize(700,600);
        map->show();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    运行如下:
    在这里插入图片描述

    2.4 测试代码4(QApplication+QMainWindow+百度地图)

    新建QMainWindow项目后:

    • (1)在pro文件中添加
    QT += webenginewidgets
    
    • 1

    在这里插入图片描述

    • (2)添加显示地图的widget
      鼠标双击文件mainwindow.ui,

    在这里插入图片描述
    界面中间区域显示如下:
    在这里插入图片描述
    在主窗口中添加一个widget控件如上。
    在这里插入图片描述
    将Widget控件提升为QWebEngineView控件。
    在这里插入图片描述
    提升后控件的类名更新为:
    在这里插入图片描述
    在路径D:\Microsoft\Qt\Qt5.14.2\5.14.2\Src\qtwebchannel\examples\webchannel\shared下复制qwebchannel.js文件备用,此文件参与QT程序与JS文件通信。
    在这里插入图片描述

    • untitled3.pro
    QT       += core gui webenginewidgets
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    CONFIG += c++11
    DEFINES += QT_DEPRECATED_WARNINGS
    
    SOURCES += \
        main.cpp \
        mainwindow.cpp
    
    HEADERS += \
        mainwindow.h
    
    FORMS += \
        mainwindow.ui
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • main.cpp
    #include "mainwindow.h"
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • mainwindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
        void on_pushButton_clicked();
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // 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
    • mainwindow.cpp
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include 
    #include 
    #include 
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        QString htmlPath = QCoreApplication::applicationDirPath() + "/html/";
        QString htmlFile = htmlPath + "test.html";
        qDebug() << htmlFile; /* 获取你要显示网页的路径 */
        QFile file(htmlFile);
        if(!file.exists())
            qDebug() << "html file is not exist";
        /* 创建一个与网页交互的通道 */
        QWebChannel *webChannel = new QWebChannel(ui->widget->page());
        ui->widget->page()->setWebChannel(webChannel);
        /* 注册通道,ID 为 JSInterface,其将在JS文件这引用 */
        webChannel->registerObject(QString("JSInterface"), ui->widget);
    
        ui->widget->page()->load(QUrl("file:///" + htmlFile));
    //    ui->widget->page()->load(QUrl("https://www.baidu.com"));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
    //    QString str = ui->lineEdit->text();
    //    QString lon = str.split(",")[0];
    //    QString lat = str.split(",")[1];
    //    QString cmd=QString("myMarker(%1,%2)").arg(lon).arg(lat);
    //    qDebug() << cmd;
    //    ui->widget->page()->runJavaScript(cmd);
    }
    
    • 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
    • test.html
    DOCTYPE html> 
    <html>
    	<head> 
    		<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> 
    		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    		<title>BDMap Sampletitle> 
    		<style type="text/css"> 
    			html{height:100%} 
    			body{height:100%;margin:0px;padding:0px} 
    			#container{height:100%} 
    		style> 
    		<script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=your baidu key">script>
    		<script type="text/javascript" src="qwebchannel.js">script>   
    	head> 
    
    	<body> 
    		<div id="container">div>
    		
    		<script type="text/javascript">
    			var map = new BMapGL.Map("container");           // 创建地图实例 
    			var point = new BMapGL.Point(113.557892,34.8333);   // 创建点坐标 
    			map.centerAndZoom(point, 15);                    // 初始化地图,设置中心点坐标和地图级别 
    			map.enableScrollWheelZoom(true);                 // 设置滚轮缩放
    			// map.setMapType(BMAP_EARTH_MAP);                  // 设置地图样式,地球模式    
    			// 创建标点  
    			var point = new BMapGL.Point(113.557892, 34.8333);   
    			var marker = new BMapGL.Marker(point);        // 创建标注   
    			map.addOverlay(marker);                     // 将标注添加到地图中 
    
    			var opts = {
    				width: 250,     // 信息窗口宽度
    				height: 100,    // 信息窗口高度
    				title: "New Marker"  // 信息窗口标题
    			}
    			var infoWindow = new BMapGL.InfoWindow("Marker", opts);  // 创建信息窗口对象
    			marker.addEventListener("click", function(){                    // 标点添加点击事件
    				map.openInfoWindow(infoWindow, map.getCenter());        // 打开信息窗口
    			});
               /*****************************/
    			// qt交互注册
    			new QWebChannel(qt.webChannelTransport,
    				function(channel){
    					window.JSInterface = channel.objects.JSInterface; // 注册
    				}
    			);
    
    			function addMarker(lng,lat){
    				var newpoint=new BMapGL.Point(lng,lat);
    				var newmarker = new BMapGL.Marker(newpoint);        // 创建标注
    				map.addOverlay(newmarker);
    				alert('ok');
    			};
              /******************************/
    	script> 
    	body> 
    html>
    
    • 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

    网页 demo参考百度的帮助文档.
    https://lbsyun.baidu.com/jsdemo.htm#aCreateMap
    最后运行如下:
    在这里插入图片描述

    结语

    如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
    如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
    如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
    感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

  • 相关阅读:
    学术论文中的Introduction与Background
    Rust 基础(六)
    【UVM】我的 main_phase 都跑完了,为啥 case 无法退出?太不讲道理!
    [BT]BUUCTF刷题第20天(4.22)
    【同源跨域】---解决ajax跨域问题
    怎么复习信息系统项目管理师?
    C++数据传输
    Jmeter测试关联接口
    Spring Cloud Greenwich 正式发布,Hystrix 即将寿终正寝!
    分享|中国大数据区域发展水平评估报告(附PDF)
  • 原文地址:https://blog.csdn.net/hhy321/article/details/136279622