首页 前端知识 QT通过QWebChannel模块实现与HTML通信(web端),获取高德地图中某个点位的经纬度坐标。

QT通过QWebChannel模块实现与HTML通信(web端),获取高德地图中某个点位的经纬度坐标。

2024-05-24 08:05:23 前端知识 前端哥 733 399 我要收藏

基于我个人的上一篇内容,通过调用高德API创建了地图,链接如下。“QT6 调用高德地图API创建地图(初学者级)”

        本篇根据上一篇所实现的内容基础上,使用QT中的webchannel方法实现与HTML交互,在HTML中使用了Javascript代码实现。实现鼠标左键点击某个位置即可获得该地点的经纬度坐标,效果如下:

1.项目结构如下:

        .pro文件和main.cpp文件除了在.pro文件中加入几个模块以外,没有其他改动,因此直接放入代码

240505.pro

QT       += core gui webenginewidgets webenginecore webchannel
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    maplistener.cpp \
    widget.cpp

HEADERS += \
    maplistener.h \
    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

main.cpp

#include "widget.h"

#include <QApplication>

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

    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
2.创建一个c++的类,用于实现QT和HTML中的通信。代码如下

maplistener.h

#ifndef MAPLISTENER_H
#define MAPLISTENER_H
#include<QDebug>
#include <QObject>

class MapListener : public QObject
{
    Q_OBJECT
public:
    explicit MapListener(QObject *parent = nullptr);

signals:
    void positionUpdated(const QString &position); // 声明一个信号
public slots:
    void updatePosition(const QString &position) {
        // 在这里处理接收到的经纬度数据
        qDebug() << "Received position:" << position;
        emit positionUpdated(position); // 发出信号
    }
};

#endif // MAPLISTENER_H

maplistener.cpp

#include "maplistener.h"

MapListener::MapListener(QObject *parent)
    : QObject{parent}
{}
3.编写widget函数

        在头文件中,只需要进行一个槽的声明即可(槽需要有函数实现,而信号不用)。这里面声明的槽跟maplistener.h中声明的信号后面组成一对。

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QtWidgets>
#include <QWebEngineView>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;

private slots:
    void onPositionUpdated(const QString &position); // 声明一个槽来更新 QTextEdit

};
#endif // WIDGET_H

        在对应的cpp文件中,首先头文件声明的槽函数实现一下,可以根据自己的需要更改。我这里是把经纬度分别分开,然后显示在不同的textedit控件中。

        在connect中,按照正常逻辑是在maplistener中直接放置控件,例如QWebEngineView的某个对象即可,例如名为web_widget的QWebEngineView控件。但是由于是web端,所以没有办法直接通信,因此我们需要通过QT给我们的webchannel方法来实现。

        在使用方法中,new一个QWebChannel对象,并且指向自己创建的窗口。

        其中下方这两行代码是非常重要的,并且QStringLiteral("maplistener")这个“maplistener”名称就是对应的要连接的html中到时候要使用的javascript的名称,通过这个名称可以调用maplistener中的成员。

    QWebChannel *channel = new QWebChannel(ui->web_widget->page());
    channel->registerObject(QStringLiteral("maplistener"), maplistener);

        下面是在html中javascript调用的方法。

channel.objects.maplistener.updatePosition(lnglat);  

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QWebEngineView>
#include <QWebChannel>
#include <QObject>
#include"maplistener.h"


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->web_widget->setUrl(QUrl("http://localhost:8000/获取经纬度坐标(实验).html"));
    MapListener *maplistener = new MapListener(this);
    QWebChannel *channel = new QWebChannel(ui->web_widget->page());
    channel->registerObject(QStringLiteral("maplistener"), maplistener);
    ui->web_widget->page()->setWebChannel(channel);
    connect(maplistener,&MapListener::positionUpdated,this,&Widget::onPositionUpdated);
}

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

void Widget::onPositionUpdated(const QString &position)
{
    // 使用逗号作为分隔符来分割字符串
    QStringList parts = position.split(",");

    // 检查是否至少有两个部分
    if (parts.size() >= 2) {
        // 移除可能的空格或换行符,并转换为浮点数(如果需要的话)
        QString part1 = parts[0].trimmed();
        QString part2 = parts[1].trimmed();

        // 将分割后的部分设置到对应的QTextEdit中
        ui->textEdit1->setText(part1);
        ui->textEdit2->setText(part2);
    } else {
        // 如果字符串没有按预期分割,可以设置一些默认值或显示错误信息
        ui->textEdit1->setText("Invalid position (part 1)");
        ui->textEdit2->setText("Invalid position (part 2)");
    }
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QtWidgets>
#include <QWebEngineView>
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;

private slots:
    void onPositionUpdated(const QString &position); // 声明一个槽来更新 QTextEdit

};
#endif // WIDGET_H
4.编写HTML文件以及其中的Javascript代码

        在这个部分需要用到qwbchannel.js文件,这个文件直接从自己安装目录下面的“QT.6\Examples\Qt-6.5.3\webchannel\shared”这个文件夹下获得即可,记得这个js文件要跟html放在同一个位置,不然找不到好像。不是很懂,希望有大哥解答一下!

获取经纬度坐标(实验).html

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <title>鼠标拾取地图坐标</title>
    <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
    <script type="text/javascript" src="https://cache.amap.com/lbs/static/addToolbar.js"></script>
    <script type="text/javascript" src="./src/qwebchannel.js"></script>
</head>
<style type="text/css">
    html,body{
        width: 100%;
        height: 100%;
        margin: 0px;
    }
    .map{
        height: 100%;
        width: 100%;
        float: left;
    }
</style>
<body>
<div id="container" class="map"></div>
</div>

<script src="https://webapi.amap.com/maps?v=1.4.15&key=“输入自己注册的key”&plugin=AMap.Autocomplete"></script>

<script src="qwebchannel.js"></script>  
<script type="text/javascript">  
    new QWebChannel(qt.webChannelTransport, function (channel) {  

  
        // 为地图注册click事件获取鼠标点击出的经纬度坐标  
        var map = new AMap.Map("container", {  
            mapStyle: "amap://styles/blue",resizeEnable: true  
        });  
        map.on('click', function(e) {  
            var lnglat = e.lnglat.getLng() + ',' + e.lnglat.getLat();  
            // 假设你在 Qt 端注册了一个名为 'mapListener' 的对象,并且它有一个 'updatePosition' 方法  
            channel.objects.maplistener.updatePosition(lnglat);  
        });  
    });  
</script>
</body>
</html>
转载请注明出处或者链接地址:https://www.qianduange.cn//article/9239.html
标签
pyqt
评论
发布的文章

JQuery中的load()、$

2024-05-10 08:05:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!