Qt之Web内容的展示

为了创建基于Qt的web应用程序,Qt提供了支持各种标准web技术(如HTML、CSS和JavaScript)的接口。这些接口使应用程序能够嵌入来自万维网的内容。

也可以将Qt c++和QML代码与HTML和JavaScript结合起来创建web应用程序。通过Qt WebChannel,远程客户端可以访问Qt的api。

ps:什么是web应用程序?Web应用程序是由多个Servlet、JSP页面、HTML文件以及图像文件等组成。所有这些组件相互协调为用户提供一组完整的服务。常见的计数器、留言版、聊天室和论坛BBS等,都是Web应用程序。

一、WebEngine in Qt

1、Qt为面向桌面和嵌入式平台的应用程序提供基于chrome的Qt WebEngine模块。

Qt WebEngine模块提供了一个web浏览器引擎,可以在没有本地web引擎的平台上轻松地将来自万维网的内容嵌入到Qt应用程序中。就相当于程序是一个浏览器,只不过和专业的浏览器比功能很少而已。

可以在传统的widget中实现Qt WebEngine,也可以在Qt quick中实现。看需求选择。

1)在传统的widget中实现Qt WebEngine。为了实现这个,我花费了1天左右的时间来踩坑,在这里记录下:

在安装Qt时,一定要选msvc编译才行,否则模块会报不存在

然后,得装两个东西,一个是vs2017/vs2015,另一个是WinSDk10,具体参考:https://blog.csdn.net/nupt_zhangtao/article/details/77444132

这里还有个坑就是 必须在vs中去安装助手,必须在vs中去安装助手,必须在vs中去安装助手。

2)QWebEngineView类:我们能用这个view可以干嘛。如下图,首先通过view获得page对象,page对象下可以获得history历史数据,相关的action动作,等。

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QAction *action = menuBar()->addAction("Icon");
    QAction *back = menuBar()->addAction("返回");
    QAction *forward = menuBar()->addAction("前进");
    QAction *reload = menuBar()->addAction("刷新");
    QAction *stop = menuBar()->addAction("停止");
    QWebEngineView *view = new QWebEngineView;
    setCentralWidget(view);

    connect(back,&QAction::triggered,[=]{
       view->back();
    });

    connect(forward,&QAction::triggered,[=]{
       view->forward();
    });

    connect(reload,&QAction::triggered,[=]{
       view->reload();
    });

    connect(stop,&QAction::triggered,[=]{
        view->stop();
    });

    //相关信号
    //与视图关联的图标(“favicon”)发生更改
    connect(view,&QWebEngineView::iconChanged,[=](const QIcon& icon){
        action->setIcon(icon);
    });
    //与视图关联的图标(“favicon”)的URL发生更改
    connect(view,&QWebEngineView::iconUrlChanged,[=](const QUrl &url){
        action->setText(url.url());
    });
    //是否加载完毕
    connect(view,&QWebEngineView::loadFinished,[=](bool){
        qDebug() << "加载完毕";
        menuBar()->addAction(view->pageAction(QWebEnginePage::Back));
        menuBar()->addAction(view->pageAction(QWebEnginePage::Cut));

    });
    //加载进度
    connect(view,&QWebEngineView::loadProgress,[=](int progress){
        qDebug() << "加载进度:" << progress << "%";
    });

    //开始加载
    connect(view,&QWebEngineView::loadStarted,[=]{
        qDebug() << "正在加载";
    });
    //当呈现进程以非零退出状态终止时,将发出此信号
    connect(view,&QWebEngineView::renderProcessTerminated,
            [=](QWebEnginePage::RenderProcessTerminationStatus terminationStatus,int exitCode){

    });
    //选择文本时发出信号
    connect(view,&QWebEngineView::selectionChanged,[=]{
        if(view->hasSelection()){
            qDebug() << "选择了文本:" << view->selectedText();
        }
    });
    //视图的标题发生变化
    connect(view,&QWebEngineView::titleChanged,[=](const QString& title){
        qDebug() << "标题:" << title;
    });
    //视图的url发生更改
    connect(view,&QWebEngineView::urlChanged,[=](const QUrl &url){
        qDebug() << "视图的url:" << url.url();
    });

    view->load(QUrl("http://www.baidu.com"));
    view->show();
}

 

3)在qml中实现的必要的步骤是:

  int main(int argc, char *argv[])
  {
      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      QGuiApplication app(argc, argv);

      QtWebEngine::initialize();

      QQmlApplicationEngine engine;
      engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

      return app.exec();
  }
import QtQuick 2.9
import QtQuick.Window 2.2
import QtWebEngine 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    WebEngineView{
        anchors.fill: parent
        url: "http://www.jd.com";
    }
}

2、它还提供了Qt WebView模块,该模块使用平台的本机web引擎。Qt WebView提供了一种在QML应用程序中显示web内容的方法,它在有意义的地方使用本机api,而不必包含完整的web浏览器堆栈。这在Android、iOS和WinRT等移动平台上非常有用;特别是在iOS上,策略要求所有web内容都使用操作系统的web view显示。

qml中的简单例子:

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QtWebView::initialize();//因为用的是库,所以必须先初始化

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    WebView{
        id:webView
        anchors.fill: parent
        url: "http://www.baidu.com";
        //新的页面时响应
        onLoadingChanged: {
            console.debug(loadRequest.errorString);
            console.debug(loadRequest.status);
            console.debug(loadRequest.url);
        }
    }
}

3、

二、Qt和HTML-JavaScript混合应用程序

Qt WebChannel模块允许HTML或JavaScript客户端访问Qt api,如QObject。它提供c++或QML API,允许Qt应用程序与JavaScript和HTML前端通信。

API分3种,这3中API可以相互通信:

1、JavaScript API。

主要是qrc:///qtwebchannel/qwebchannel.js.

2、C++ API。

QWebChannel:向远程HTML客户端公开qobject。

QWebChannelAbstractTransport:服务器(c++ 的QWebChannel)与客户端(HTML/JS)之间的通信通道。

3、QML API。

WebChannel:WebChannel提供了一种机制,可以透明地从HTML客户机访问QObject或QML对象。所有属性、信号和公共插槽都可以从HTML客户机中使用。

Qt中的实例:

//该类的一个实例通过WebChannel发布,然后HTML客户机可以访问它

class Core : public QObject
{
    Q_OBJECT

public:
    Core(Dialog *dialog, QObject *parent = 0):QObject(parent)
    {
        connect(dialog,&Dialog::sendText,this,&Core::sendText);
    }

signals:
    //这个信号是从c++端发出的,文本显示在HTML客户端。
    void sendText(const QString &text);
public slots:
    //这个插槽是从HTML客户端和服务器端显示的文本调用的。
    void receiveText(const QString &text)
    {
        m_dialog->displayMessage(Dialog::tr("Received message: %1").arg(text));
    }


private:
    Dialog *m_dialog;
};
class QPlainTextEdit;
class QLineEdit;
class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

    void displayMessage(const QString &message);

signals:
    void sendText(const QString &text);

private slots:
    void clicked();

private:
    QPlainTextEdit *plain;
    QLineEdit *edit;
    QPushButton *sendBtn;
};
Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    QVBoxLayout *mainLayout = new QVBoxLayout;
    setLayout(mainLayout);

    plain = new QPlainTextEdit;
    plain->setReadOnly(true);
    mainLayout->addWidget(plain);

    QHBoxLayout *layout = new QHBoxLayout;
    edit = new QLineEdit;
    layout->addWidget(edit);
    sendBtn = new QPushButton("Send");
    layout->addWidget(sendBtn);

    mainLayout->addLayout(layout);

    connect(sendBtn,&QPushButton::clicked,this,&Dialog::clicked);
}

Dialog::~Dialog()
{

}

void Dialog::displayMessage(const QString &message)
{
    plain->appendPlainText(message);
}

void Dialog::clicked()
{
    const QString text = edit->text().trimmed();
    if(text.isEmpty())
        return;
    emit sendText(text);

    displayMessage(tr("Send message: %1").arg(text));

    edit->clear();
}
class WebSocketTransport;
class QWebSocketServer;
class WebSocketClientWrapper : public QObject
{
    Q_OBJECT

public:
    WebSocketClientWrapper(QWebSocketServer *server, QObject *parent = 0);
signals:
    void clientConnected(WebSocketTransport *client);

private slots:
    void handleNewConnection();

private:
    QWebSocketServer *m_server;
};
WebSocketClientWrapper::WebSocketClientWrapper(QWebSocketServer *server, QObject *parent)
    :QObject(parent),m_server(server)
{
    connect(m_server,&QWebSocketServer::newConnection,
            this,&WebSocketClientWrapper::handleNewConnection);
}

void WebSocketClientWrapper::handleNewConnection()
{
    //把客户端socket放进传输通道对象中 专门处理与远程客户端的通信
    emit clientConnected(new WebSocketTransport(m_server->nextPendingConnection()));
}
class QWebSocket;
class WebSocketTransport : public QWebChannelAbstractTransport
{
    Q_OBJECT
public:
    explicit WebSocketTransport(QWebSocket *socket);
    virtual ~WebSocketTransport();

    void sendMessage(const QJsonObject &message) override;

private slots:
    //接收数据
    void textMessageReceived(const QString &message);

private:
    QWebSocket *m_socket;
};
WebSocketTransport::WebSocketTransport(QWebSocket *socket)
    :m_socket(socket),QWebChannelAbstractTransport(socket)//绑定一个socket 用于读取远程客户端发送来的数据
{
    connect(socket,&QWebSocket::textMessageReceived,
            this,&WebSocketTransport::textMessageReceived);
    connect(socket,&QWebSocket::disconnected,this,&WebSocketTransport::deleteLater);
}

WebSocketTransport::~WebSocketTransport()
{
    m_socket->deleteLater();
}

void WebSocketTransport::sendMessage(const QJsonObject &message)
{
    QJsonDocument doc;
    doc.setObject(message);
    m_socket->sendTextMessage(QString::fromUtf8(doc.toJson(QJsonDocument::Compact)));
}

void WebSocketTransport::textMessageReceived(const QString &message)
{
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(),&error);
    if(error.error != QJsonParseError::NoError){
        qDebug() << error.errorString();
        return;
    }else if(!doc.isObject()){
        qDebug() << " is not Object";
        return;
    }
    emit messageReceived(doc.object(),this);
}
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QFileInfo jsFileInfo(QDir::currentPath()+"/qwebchannel.js");

    if(!jsFileInfo.exists())
        QFile::copy(":/qtwebchannel/qwebchannel.js",
                    jsFileInfo.absoluteFilePath());

    //创建服务端对象
    QWebSocketServer server(QStringLiteral("QWebChannel Standalone Example Server"),
                            QWebSocketServer::NonSecureMode);
    //监听
    if(!server.listen(QHostAddress::LocalHost, 12345)){
        qDebug() << "监听失败";
        return 1;
    }

    //创建传输通道
    WebSocketClientWrapper clientWrapper(&server);

    //建立web通道 暴露api给远程客户端调用
    QWebChannel channel;
    QObject::connect(&clientWrapper,&WebSocketClientWrapper::clientConnected,
                     &channel,&QWebChannel::connectTo);

    Dialog w;

    Core core(&w);
    //向QWebChannel注册单个对象
    //对象的属性、信号和公共方法被发布到远程客户端。然后构造一个具有标识符id的对象
    channel.registerObject(QStringLiteral("core"),&core);

    //开启html 客户端
    QUrl url = QUrl::fromLocalFile(SOURCEDIR "/index.html");
    QDesktopServices::openUrl(url);

    w.displayMessage(QDialog::tr("Initialization complete, opening browser at %1.").arg(url.toDisplayString()));

    w.show();

    return a.exec();
}

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Qt Web Assembly是一种将Qt应用程序编译成Web Assembly格式的工具。Web Assembly是一种可移植、高性能的代码格式,使得开发者能够使用高级语言编写网页应用程序,同时提供类似于原生应用程序的性能。 Qt Web Assembly Demo是一个展示Qt应用程序在Web Assembly上的运行能力的示例程序。通过这个示例,我们可以了解Qt如何在Web浏览器中展示并执行应用程序。 这个示例可能包含一个简单的Qt应用程序,如绘制一个基本的GUI界面、处理用户交互等。该应用程序在本地开发环境中编写和测试后,通过Qt Web Assembly编译器将其转换为Web Assembly格式。转换后的文件可以在支持Web Assembly标准的Web浏览器中加载和运行。 通过加载Web Assembly文件,浏览器就能够展示和执行Qt应用程序,让用户可以在浏览器中直接使用该应用程序而不需要进行额外的安装或下载。用户可以与应用程序进行交互,使用其中的功能,并在浏览器中进行各种操作。 Qt Web Assembly Demo展示QtWeb Assembly平台上的跨平台能力,使得开发者能够使用Qt框架和工具链来开发高性能、可移植的Web应用程序。这对于那些希望在Web上部署其Qt应用程序的开发者来说,具有很大的实用价值。 ### 回答2: Qt Web Assembly Demo是一个使用Qt开发的演示程序,旨在展示Qt如何支持Web Assembly技术。 Web Assembly是一项开放的Web标准,它使得可以在浏览器中运行高性能的、跨平台的应用程序。传统上,Web应用程序使用JavaScript来开发,但由于JavaScript的性能有限,不能处理一些复杂的任务,如图形渲染和图像处理。而web assembly可以通过将C++代码编译为二进制格式,以更高的效率运行在浏览器中,从而提供了更好的性能。 Qt作为跨平台应用程序开发框架,可以利用它的优势来支持Web Assembly。Qt Web Assembly Demo利用Qt提供的工具和API,可以将Qt应用程序编译为Web Assembly格式,使其可以在Web浏览器中运行。 Qt Web Assembly Demo可以展示很多功能,如界面布局、图形绘制、图像处理等。用户可以通过浏览器打开这个Demo,并且在浏览器中操作应用程序的界面和功能。这个Demo向用户展示Qt框架的强大能力,以及其与Web Assembly的集成。 通过Qt Web Assembly Demo,开发人员可以了解如何使用Qt开发Web Assembly应用程序,并学习如何利用Qt提供的丰富的功能和界面组件来创建更复杂的Web应用程序。这个Demo也可以作为一个教学资源,帮助开发人员更好地理解和应用Web Assembly技术。 总之,Qt Web Assembly Demo是一个展示QtWeb Assembly集成的演示程序,通过它可以了解如何使用Qt开发跨平台的高性能Web应用程序。它为开发人员提供了一个学习和实践的平台,帮助他们更好地使用Web Assembly技术来开发前端应用程序。 ### 回答3: QT WebAssembly Demo是一个基于Qt框架开发的示例应用程序,旨在通过WebAssembly技术将Qt应用程序转换为web可运行的格式。 Qt是一个跨平台的C++应用程序开发框架,可以用于开发各种类型的桌面应用程序和移动应用程序。而WebAssembly是一种新的web技术,允许开发者在网页上直接运行速度更快的原生代码。 QT WebAssembly Demo的开发可以分为以下几个步骤: 1. 在Qt Creator中创建一个新的Qt Quick Application项目。 2. 修改项目的.pro文件,添加WebAssembly构建配置,以便将应用程序编译为WebAssembly格式。 3. 在源代码中编写你想要展示的功能和界面。 4. 使用Qt提供的工具将应用程序编译为WebAssembly格式。 5. 将生成的WebAssembly文件部署到一个web服务器上,并通过浏览器访问该网页。 QT WebAssembly Demo可以展示Qt应用程序在web浏览器中的运行情况。用户可以通过浏览器访问该网页,并与应用程序进行交互,体验应用程序提供的功能和界面。 在QT WebAssembly Demo中,开发者可以演示如何在web浏览器上使用Qt开发框架创建一个具有交互功能的应用程序。通过这个示例,开发者可以了解和学习如何将现有的Qt应用程序转换为web可运行的格式,并在web平台上进行应用程序的开发和发布。 总之,QT WebAssembly Demo是一个展示Qt应用程序在web浏览器上运行的示例应用程序,通过WebAssembly技术,使得Qt应用程序能够在web平台上进行开发和发布。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值