• 【引用】Qt——web网页和本地对象的交互


    有时候可能需要在html网页中调用本地的对象方法。

    比如说我点击了一个视频文件的链接,希望调用本地的多媒体模块来播放这个视频文件, 如何实现?

    一、html中的JavaScript调用Qt本地对象方法

    过程如下:

    1. 将本地的QObject对象暴露给webkit和JavaScript
    2. 通过JavaScript调用本地QObject的槽

    下面对每个步骤进行详细的分析:


    1、将本地的QObject对象暴露给webkit和JavaScript

    QWebFrame里提供了实现这个功能的接口:

    1 void addToJavaScriptWindowObject(const QString &name, QObject *object, QScriptEngine::ValueOwnership ownership);

    Qt的帮助文档中对这个方法的说明如下:

    Make object available under name from within the frame's JavaScript context. The object will be inserted as a child of the frame's window object.

    Qt properties will be exposed as JavaScript properties and slots as JavaScript methods.

    If you want to ensure that your QObjects remain accessible after loading a new URL, you should add them in a slot connected to the javaScriptWindowObjectCleared() signal.

    If Javascript is not enabled for this page, then this method does nothing.

    The object will never be explicitly deleted by QtWebKit.

    从这里可以看出,要想addToJavaScriptWindowObject方法有效,必须是能javascript;为了保证每次打开个新网页或刷新网页时都调用这个方法,那就应该将这个方法和javaScriptWindowObjectCleared信号相连。

    相关代码如下:

    webkit_vlc.h

    #ifndef WEBKIT_VLC_H 
    #define WEBKIT_VLC_H 
    #include <QWidget> 
    #include <QWebView> 
    #include "obj_openvlc.h" 
    namespace Ui { 
        class Webkit_VLC; 
    } 
    class Webkit_VLC : public QWebView 
    { 
        Q_OBJECT 
    public: 
        explicit Webkit_VLC(QWidget *parent = 0); 
        ~Webkit_VLC(); 
    private slots: 
        void addJavaScriptObject(); 
    private: 
        Ui::Webkit_VLC *ui; 
        Obj_OpenVlc *obj_openVlc; //将暴露给javascript的对象 
    }; 
    #endif // WEBKIT_VLC_H 

    webkit_vlc.cpp

    #include "webkit_vlc.h" 
    #include "ui_webkit_vlc.h" 
    #include <QWebPage> 
    #include <QWebFrame> 
    #include <QtDebug> 
    Webkit_VLC::Webkit_VLC(QWidget *parent) : 
        QWebView(parent), 
        ui(new Ui::Webkit_VLC) 
    { 
        setWindowFlags( Qt::FramelessWindowHint); 
        ui->setupUi(this); 
        resize(1280,720); 
        obj_openVlc = new Obj_OpenVlc(this); 
        settings()->setAttribute(QWebSettings::JavascriptEnabled,true); 
        settings()->setAttribute(QWebSettings::PluginsEnabled,true); 
        connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared ()), 
                this, SLOT(addJavaScriptObject())); 
        load(QUrl("file:///home/nxx/Webkit_VLC/view.html")); 
    } 
    Webkit_VLC::~Webkit_VLC() 
    { 
        delete ui; 
    } 
    void Webkit_VLC::addJavaScriptObject(){ 
        qDebug()<<"addJavaScriptObject"; 
        //javascript可以通过对象名obj_open_vlc访问obj_openVlc对象。 
        page()->mainFrame()->addToJavaScriptWindowObject("obj_open_vlc",this->obj_openVlc); 
    } 

    现在已经将名为“obj_open_vlc”的对象暴露给了webkit的javascript, 这个对象名对应的是本地的一个类的对象

    Obj_OpenVlc *obj_openVlc.

    下面的代码为这个类的实现,并且类中定义了一个槽供webkit的javascript调用。

    obj_openvlc.h

    #ifndef OBJ_OPENVLC_H 
    #define OBJ_OPENVLC_H 
    #include <QObject> 
    class Obj_OpenVlc : public QObject 
    { 
        Q_OBJECT 
    public: 
        explicit Obj_OpenVlc(QObject *parent = 0); 
    signals: 
    public slots: 
        //供javascript调用的槽 
        QString openVLC(QString url); 
    }; 
    #endif // OBJ_OPENVLC_H 
    obj_openvlc.cpp
    #include "obj_openvlc.h" 
    #include <QtDebug> 
    Obj_OpenVlc::Obj_OpenVlc(QObject *parent) : 
        QObject(parent) 
    { 
    } 
    QString Obj_OpenVlc::openVLC(QString url) 
    { 
        qDebug()<<"open "<< url; 
        return url; 
    } 

    2、在html中通过JavaScript调用本地QObject的槽

    html的代码如下:

    view.html

    <html>
    <script LANGUAGE="JScript">  
       function open()
       {
           try{
                 var url = obj_open_vlc.openVLC("192.168.0.1/webroot/test.f4v");
                 alert(url);
           }
           catch(e) {
                alert(e);
           }
      }

    </script>

      <body>
        <h1>Open VLC</h1>
        <input type=button value="open" onclick="open()">
      </body>
    </html>
    这个html中通过javascript代码

    obj_open_vlc.openVLC("192.168.0.1/webroot/test.f4v");

    调用了本地类Obj_OpenVlc的对象obj_openVlc的槽(方法)openVLC()。

    这样子就实现了在webkit的html网页中的,通过javascript调用本地对象的方法。

    二、Qt本地对象调用html中的javascript方法

    目前我知道的有两种方法:

    1. 通过QWebFrame类的槽:

    QVariant QWebFrame::evaluateJavaScript ( const QString & scriptSource )

    来直接调用javascript中的方法, 比如我html网页中有个javascript  的 loadFinished()方法 , 那么就可按下面的方式直接调用:

    webView->page()->mainFrame()->evaluateJavaScript("loadFinished();");

    这里假设 webView 是 QWebView类的对象。

    2.将本地OBject的信号和javascript的方法相连。

    当本地发射出这个信号时,也会调用javascript的方法。不过这里需要在javascript中加入类似下面的代码。

    //将Qt本地对象 obj_open_vlc的信号与 javascript的函数slotButtonClicked相连 
    obj_open_vlc.ObjSignal.connect(slotLinkClicked);

    此处的 ObjSignal 是Qt本地对象obj_open_vlc的一个信号,slotButtonClicked 是javascipt 中的一个方法。之后,如果本地obj_open_vlc 对象执行 emit ObjSignal() 之后就会调用javascipt的方法slotLinkClicked()。

    这里贴上相关的html的代码:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <title>Media Server</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script language="javascript">
    //将Qt本地对象 obj_open_vlc的信号与 javascript的函数slotButtonClicked相连 
    obj_open_vlc.ObjSignal.connect(slotLinkClicked);
    function slotLinkClicked()
    {
        alert("link is clicked!");
    }  
    function loadFinished()
    {
        alert("page load finished!");
    } 
    function getRTMPHost()
    {
        if (location.protocol == "http:" || location.protocol == "https:")
            return "/" + location.hostname + "/";
        else
            return "";
    } 
    function open(file)
    {
        url = 'rtmp:/' + getRTMPHost() + 'vod/' + file
        try {
              var play = obj_open_vlc.openVLC(url);
              //alert(play);
          }
          catch(e) {
              alert(e);
          }
    } 
    </script>
      <body>
        <h1>Media Server</h1>
        <p><a href="javascript:open('test1.f4v');">test1.f4v</a></p>
        <p><a href="javascript:open('test2.f4v');">test2.f4v</a></p>
      </body>
    </html>
  • 相关阅读:
    未来房价经济管窥(崩溃不行,疯涨也不行,所以只能冰冻。房产税的开征是个关键转折点,也是判断未来房价的重要指标。大城市的房租还会继续涨,以后不愁没房子住,虽然仍然买不起)
    QT使用UAC(经过验证)
    ALT+数字,可输入汉字或拉丁字母 good
    RUST叫系统编程语言,而GO是网络编程语言
    最近学习了下BI(商业智能)做报表
    选择优势股票,动态配置
    对加密方式(公钥私钥)的形象理解(以http和https为例)
    SQLServer重建索引
    怎么样成为一个全栈程序员(请把一个能力发展到90,如果你还有余力把另一个能力发展到90,否则就是平庸的废材)
    如何才能学到Qt的精髓——信号槽之间的无关性,提供了绝佳的对象间通讯方式,QT的GUI全是自己的一套,并且完全开源,提供了一个绝好机会窥视gui具体实现
  • 原文地址:https://www.cnblogs.com/qq78292959/p/2634860.html
Copyright © 2020-2023  润新知