QT中使用WebKit中的一些问题

1. 基本的使用方法

 1.1 加入项目依赖

(1)在pro文件中加入QT += webkit

或在cmakeList.txt中加入(本人未试过):

find_package(Qt4 COMPONENTS Widgets WebKit REQUIRED)

target_link_libraries(webEngineTest PRIVATE Qt4::Widgets Qt4::WebKit)

(2)生成实例

在mainWindow.h中加入

#include <QWebView>

QWebView* webView;

 

在mainWindow. cpp构造函数中加入:

    webView = new QWebView(this);
    QVBoxLayout *layout = new QVBoxLayout();
    layout->addWidget(webView);
    QWidget* widget = new QWidget();
    widget->setLayout(layout);
    setCentralWidget(widget);
    //webView->resize(this->size());
    //webView->move(0, 0);

    QString fpath = QCoreApplication::applicationDirPath();
    fpath.append("/test1.html");
    QUrl url = QUrl::fromUserInput(fpath);
    webView->load(url);
    webView->show();

2. QT交互类的槽定义

定义新类需要注意

(1)需要由js调用的函数必须定义为槽函数,不返回值(试验中,返回值失败)。

(2)槽函数的参数不要采用引用方式,采用值传递(试验中,引用方式调用失败)。


//env_scenario.h
#ifndef ENV_SCENARIO_H
#define ENV_SCENARIO_H
#include <QObject>
#include <QWebView>

class Env_scenario : public QObject
{
    Q_OBJECT
public:
    explicit Env_scenario(QWebView* webView, QObject *parent = NULL);
public slots:
    //***!!!与java绑定时,不能用引用传递参数,否则不能使用
    //***!!!槽函数不能返回值,否则出现异常
    void setMyItemText(QString id);
    void secondSlot(QString txt);
private:
    QWebView* m_pWebView;
};

#endif // ENV_SCENARIO_H
//env_scenario.cpp

#include "env_scenario.h"
#include <QDebug>
#include <QMessageBox>
Env_scenario::Env_scenario(QWebView* webView, QObject *parent)
    :QObject(parent), m_pWebView(webView)
{

}

void Env_scenario::setMyItemText(QString id)
{
    QMessageBox::information(NULL, "in Env_scenario::setMyItemText", id);
    qDebug() << id << endl;
}

void Env_scenario::secondSlot(QString txt)
{
    QMessageBox::information(NULL, "in Env_scenario::secondSlot", txt);
    qDebug() << txt << endl;
}

3. 注册交互类对象

在主程序中生成交互类实例后,通过webView进行注册

    envSce = new Env_scenario(webView, this);
    opoSce = new Opo_scenario(webView, this);
    webView->page()->mainFrame()->addToJavaScriptWindowObject("Evnitem", envSce);
    //***!!!看来不能同时注册两个对象
    //webView->page()->mainFrame()->addToJavaScriptWindowObject("Opoitem", opoSce);

需要注意的是:

(1)一个webView只能注册一个交互类对象(试验过两个,失败)

(2)如果出现错误提示:unable  using incomplete class,需要加入#include<QWebForm>

4.创建html文档

(1)当主程序注册了交互实体后,本实例就成为html文件中window的一个成员,可以用window."实例名"."函数名"调用其函数

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>scenario edit</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">    
        <meta http-equiv="Content-Language" content="Chinese">
        <link rel="stylesheet" type="text/css" href="./element-ui/lib/theme-chalk/index.css">
        <script language="javascript">
            function setEvnItem()
            {
                alert("call Evnitem");
                window.Evnitem.setMyItemText("call Evnitem");
            }
            function setOpoItem()
            {
                //alert("call Opoitem");
                window.Evnitem.secondSlot("call secondSlot");
            }
            function setName(name)
            {
                alert(name);
                document.getElementById(name).innerHTML = name;
            }
        </script>
    </head>
    <body>
        <div id="app">
            <h1>这是WebKit的一个应用</h1>
            <button onclick="SetEvnItem()">setEvnItem input</button> <br /><br />
            <button onclick="setOpoItem()">setOpoItem input</button> <br /><br />
        </div>
        <div>
            <p id="mytext"></p>
        </div>
    </body>    
</html>

5. QT调用JS

void MainWindow::on_actioncall_js_triggered()
{
    QString funName = QString("setName(\"%1\");").arg(QString("mytext"));
    webView->page()->mainFrame()->evaluateJavaScript(funName);
}

6. 加入Vue框架和element-ui

(1)element-ui依赖于Vue,所以不加入Vue就不能使用element-ui;

(2)要在<body>节点的外面加入Vue,否则由于Vue加载时间长,导致失效

(3)先加入Vue,再加入element-ui

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>scenario edit</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">    
        <meta http-equiv="Content-Language" content="Chinese">
        <link rel="stylesheet" type="text/css" href="./element-ui/lib/theme-chalk/index.css">
        <script language="javascript">
            function setEvnItem()
            {
                alert("call Evnitem");
                window.Evnitem.setMyItemText("call Evnitem");
            }
            function setOpoItem()
            {
                //alert("call Opoitem");
                window.Evnitem.secondSlot("call secondSlot");
            }
            function setName(name)
            {
                alert(name);
                document.getElementById(name).innerHTML = name;
            }
        </script>
    </head>
    <body>
        <div id="app">
            <h1>这是WebKit的一个应用</h1>
            <el-button v-on:click="SetEvn">setEvnItem input</el-button> <br /><br />
            <el-button onclick="setOpoItem()"> setOpoItem input</el-button> <br /><br />
        </div>
        <div>
            <p id="mytext"></p>
        </div>
    </body>
        <script type="text/javascript" src="./vue.js"></script>
        <script type="text/javascript" src="./element-ui/lib/index.js"></script>
        <script language="javascript">
            //window.Evnitem.ObjSignal.connect(setEvnItem);

            new Vue({
                el: '#app',
                data : {value: "setEvnItem"},
                methods:{
                    SetEvn: function()
                    {
                        //alert("setEvnItem");
              //这里直接调用QT注册的实例的函数
window.Evnitem.setMyItemText("call Evnitem"); //setEvnItem(); } } }) </script> </html>

代码中setEvnItem()和setOpoItem()两个函数可以删除,因为在Vue中可以直接调用注册的QT实体

 

posted @ 2020-12-28 10:42  小船1968  阅读(1321)  评论(0编辑  收藏  举报