Qt 之 c++ Qml与html交互_qt 使用 html 方法

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

<!DOCTYPE html>
<head>
 <meta charset="utf-8" />
</head>
<script type="text/javascript" src="qrc:/qwebchannel.js"></script>
<script type="text/javascript">
function test(){
    new QWebChannel(qt.webChannelTransport, function(channel) {
        // 所有通过 WebChannel 发布的对象都可以在 channel.objects 中访问的到
        window.foo = channel.objects.foo;

        // 访问一个属性
        alert(foo.hello);

        // Writing a property will instantly update the client side cache.
        // The remote end will be notified about the change asynchronously
        foo.hello = "Hello World!";

 // 连接信号
 foo.someSignal.connect(function(message) {
            alert("Got signal: " + message);
        });

 // 调用方法,并\*异步\*接收返回值
 foo.someMethod("bar", function(ret) {
            alert("Got return value: " + ret);
        });

        // One can also access enums that are marked with Q\_ENUM:
        //console.log(foo.MyEnum.MyEnumerator);
    });
}
    </script>

<body>
    <div><button type="button" onClick="test()>Click Me!</button></div>   
</body>
</html>

HTML / JavaScript 客户端
在客户端,首先,通过 Qt 资源 URL 包含客户端 qwebchannel.js 库(该文件可以在 %QtDir%\Src\qtwebchannel\examples\webchannel\shared\qwebchannel.js 中找到,经过测试在 Qt 5.12 以后不将该文件加入资源也可),并在 HTML 文件中插入一段 JavaScript:

<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>

然后,在 JavaScript 代码中实例化 QWebChannel 对象并设置回调函数。当 web 通道的初始化成功时,将调用回调函数。此外,您可以传递 qt.webChannelTransport 对象到 channel 中,详见下文:

new QWebChannel(qt.webChannelTransport, function(channel) {
// 所有通过 WebChannel 发布的对象都可以在 channel.objects 中访问的到
window.foo = channel.objects.foo;

// 访问一个属性
alert(foo.hello);

// Writing a property will instantly update the client side cache.
// The remote end will be notified about the change asynchronously
foo.hello = "Hello World!";

// 连接信号
foo.someSignal.connect(function(message) {
    alert("Got signal: " + message);
});

// 调用方法,并*异步*接收返回值
foo.someMethod("bar", function(ret) {
    alert("Got return value: " + ret);
});

// One can also access enums that are marked with Q_ENUM:
//console.log(foo.MyEnum.MyEnumerator);

});

C++/QML/HTML 混合应用程序
利用在 QML 应用程序中可以引用 C++ 类的这个特点,我们也可以实现在 HTML 页面中调用 C++ 类的需求。

首先定义 C++ 对象并将它注册到 QML 中,我们在 main.cpp 中添加下面的一行,注意, TestObejct 类必须直接继承自 Object:

qmlRegisterType<TestObejct>("TestObejct", 1, 0, "TestObejct");

然后在 QML 文件中将这个类对象注册到 WebChannel,你可以使用上节中提到的方法直接调用 C++ 类中已存在的信号、方法、属性和枚举类型,也可以在 QML 中继续扩展其他方法:

import TestObejct 1.0

TestObejct {
id: myObject
WebChannel.id: “foo”

// 在 QML中可以继续扩展信号、方法和属性
signal someSignal2(string message);

function someMethod2(message) {
    console.log(message);
    someSignal2(message);
    return "foobar";
}

property string hello2: "world"

}
Qt WebChannel 不只可以在 QML 应用程序中使用,在纯 Qt/C++ 应用程序中也可以创建一个 QWebChannel 并发布 QObject 实例

项目需求(html页面定位)

项目用到了html页面定位功能,即点击一个导航按钮,使页面直接跳转到该位置(滚动条直接滚到到位置)
有两种方式实现:
1 借用a标签的href定位,瞄点

<div id="content">
  <div class="btn-container">
    <a class="btn" href="#anchor1">锚点1</a>
    <a class="btn" href="#anchor2">锚点2</a>
    <a class="btn" href="#anchor3">锚点3</a>
  </div>
  <div id="anchor1" class="anchor-con">anchor1</div>
  <div id="anchor2" class="anchor-con">anchor2</div>
  <div id="anchor3" class="anchor-con">anchor3</div>
</div>

2 简单的window.scrollTo方法使用

该方法需要在html文件中加载jquery.min.js:

<script type=\"text/javascript\" src=\"qrc:/jquery.min.js\"></script>

html 中js方法

function textClicked(){
       $(window).scrollTop($(\"#pos0\").offset().top);
       }

html 标签

<div id=\"pos1\"><span class=\"Title\">考点解析</span></div>

单击导肮按钮 “文字解析”即可实现定位

<button id=\"textPos\" class=\"topnavi\" onClick=\"textClicked()\">文字解析</button>

遇到的问题:

1 qwebchannel.js 版本不一样 ,项目中刚开始始终在html文件中调用QtObject方法不可行,后来发现qwebchannel.js文件不对
2 html中显示中文问题,webengine找不到中文字库,因为在嵌入式下,需要自己手动编译
3 Uncaught ReferenceError: $ is not defined报错;$未定义是为什么呢?
原因一:你未引用jquery库jquery.min.js文件,或者说路径错误;

扩展 :Chrome打开PDF报错:Not allowed to navigate top frame to data URL

Chrome打开PDF报错:Not allowed to navigate top frame to data URL

var pdf = "data:application/pdf;base64," + data;
window.open(pdf);

在Chrome使用window.open()打开pdf报错:

Not allowed to navigate top frame to data URL: data:application/pdf;base64,JVBERi0xLjMKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1…
原因分析
Chrome 60 开始禁止页面使用data:url的方式跳转导航,禁止data:url导航的使用包括:

<a href="data:xxxxx"> 点击跳转
window.open(“data:xxx”)
window.location="data:xxx"

对于使用data:url直接来加载数据的场景不会禁止,如

直接加载图片

解决方案
Chrome并没有禁止直接使用data:url的方式加载数据,如iframe,所以可以把数据放到iframe的属性src里。

var win = window.open();
var pdf = "data:application/pdf;base64," + data;
win.document.write('&lt;iframe src="' + pdf + '" frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" allowfullscreen&gt;&lt;/iframe&gt;')

扩展:JS控制div跳转到指定的位置的解决方案总结

1.给链接a加个#的方式来实现跳转

html页面:

<div id="container">
       <a href="#div1">div1</a>
       <a href="#div2">div2</a>
       <a href="#div3">div3</a>
</div>
   <div id="div1">div1</div>
   <div id="div2">div2</div>
   <div id="div3">div3</div>

css样式:

div {
           height: 800px;
           width: 400px;
           border: 2px solid black;
       }
  #container{
           position: fixed;
           margin:50px  500px;
 }

该锚点法,不需要任何的js代码,即可实现跳转的方法。缺点:点击链接url发生变化,刷新的话会有问题。此方法貌似只能在.html后缀的页面才能起作用,对于.cshtml页面不起作用。
  
2.用animate属性,当点击锚点后,页面滚动到相应的DIV
接着上面的代码,具体添加如下代码:

html页面:

<div id="container">
          <p id="p1">div1</p>
          <p id="p2">div2</p>
          <p id="p3">div3</p>
</div>
   <div id="div1">div1</div>
   <div id="div2">div2</div>
   <div id="div3">div3</div>

css样式页面同上,看下js代码如下:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
$(document).ready(function() {
    $("#p1").click(function() {
        $("html, body").animate({
            scrollTop: $("#div1").offset().top }, {duration: 500,easing: "swing"});
        return false;
    });
 $("#p2").click(function() {
        $("html, body").animate({
            scrollTop: $("#div2").offset().top }, {duration: 500,easing: "swing"});
        return false;
    });
 $("#p3").click(function() {
        $("html, body").animate({
            scrollTop: $("#div3").offset().top }, {duration: 500,easing: "swing"});
        return false;
    });
});

3.简单的window.scrollTo方法使用
即滚动到坐标为(100,500)的地方。比较单一,且没有缓慢的效果

function scrollWindow(){
    window.scrollTo(100,500);
}

4.用js的srollIntoView方法进行使用。这里贴下代码:

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

码:**

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
[外链图片转存中…(img-xDq4TH0X-1715896704390)]
[外链图片转存中…(img-LiI0kgOf-1715896704391)]

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值