最近写的插件功能基本完成,也遇到了一些坑,在这里记录一下。

我写的这个插件的js接口是仿造google earth的js接口,尽可能的达到与它的api一致。先从最简单的说起:

1. 导出接口中的float参数

GE中的一些接口有些参数是float,比如下面这个:
    float KmlMouseEvent::getLatitude()

你要是真按着这个函数来返回float,我估计你在页面里调用这个方法的时候肯定会提示你“方法不存在,或不支持该方法”之类的。
明明写了,为啥提示没有这个方法呢?原因很简单,因为这个接口没有导出成功!没有导出成功的方法,你咋调呢?
那么为什么没有导出成功?这个就得问assisant了。

请翻到 Building ActiveX servers in Qt 这一页,往下翻,会看到一个Qt data types与COM property的对应表。
仔细看就会发现,根本没有float这一项!

我对COM不熟,不知道COM是不是本身就没有float;还是Qt认为有double就够用了,float不需要;还是因为javascript只有number类型,不区分float和double,如果能导出float,会影响精度。。。

所以解决办法就出来了,接口参数都用double,不要用float!

2. 导出类的创建和回收

这个其实是我对ActiveQt框架如何管理对象的一个疑惑。因为在这个框架中,所以导出的类都只能以new这种方式创建出来,在js代码中也是new xxxx;而且所有的导出函数也不能用对象作为参数,而必须用对象的指针才行。那我什么时候删除呢?

其实这里我也没有看到一些说明文档,不过倒是在网上搜的时候看到这篇博客,写的还是挺不错的,解释的很清楚。

3. 枚举类型的导出

在GE的api中是存在这样的调用的:
    ge.getLayerRoot().enableLayerById(ge.LAYER_TERRAIN, true);
    (其中ge是google.earth.createInstance得到的对象)

这里就涉及到枚举值。那怎么在Qt里导出枚举呢。
这个其实翻翻例子,应该就能找到这个宏:
    Q_ENUMS

用法:
class MyClass : public QObject
{
     Q_OBJECT
     Q_ENUMS(Priority)
 
public:
     MyClass(QObject *parent = 0);
     ~MyClass();
 
     enum Priority { High, Low, VeryHigh, VeryLow };
     void setPriority(Priority priority);
     Priority priority() const;
}

看上去,似乎这样就OK了。实际上,枚举也确实是这样导出的。
但你对照着GE的API看看,就会发现,这个定义的枚举值我怎么在其他的函数里调用!而且 ge.LAYER_TERRAIN 这样调用,仔细看似乎并不是枚举,因为ge是对象,用对象再点出来一个枚举。。我反正是没见过。

所以我的最后的解决方案是用:property。代码如下:
class MyClass : public QWidget, public QAxBindable
{
    Q_OBJECT
    Q_PROPERTY(int LAYER_TERRAIN READ enum_TERRAIN)
    Q_PROPERTY(int LAYER_BORDERS READ enum_BORDERS)

public:
    int enum_TERRAIN() {return 0;}
    int enum_BORDERS() {return 1;}
}

看着很啰嗦是吧,暂时我也没好的解决方案,如果哪位看官解决过,麻烦告诉一下:)

4. 动态生成函数,事件监听

这里费了我很大的力气,但最终的解决方案还是没有与GE完全一致(哎,还得努力啊。。)。这里把我的解决方案记录下来,供大家参考。

在GE的api里有个 addEventListener 函数,可以用于事件的绑定。函数的原型:
    addEventListener(obj, 'signal', callbackfunc)
也就是当obj发出'signal'事件时,会回调callbackfunc这个函数。

可以直接用C++写导出函数,但问题是怎么调用js的函数,我搜了很久也没有找到。。。所以就把这个方法写成js的函数了。

因为ActiveQt中的事件写成监听函数要写成:
    function obj::signal(e) { }
这样的方式才行,所以问题就变成了怎么用那三个参数生成一个监听函数了。

同样,搜了很久,再参考了这个这个后,才得到一个解决方案:
//////////////////////////////////////////////////
// 动态生成函数
var X2={} //my namespace:)
X2.Eval=function(code){
    if(!!(window.attachEvent && !window.opera)){
        //ie
        alert(code);
        window.execScript(code);
    }else{
        //not ie
        window.eval_r(code);
    }
}
 
MYOBJECT.property.addEventListener = function(obj, signal, func) {
    var src = "function "+obj+"::"+signal+"(event) {" +
        func+"(event);" +
    "}";
    X2.Eval(src);
}

这里的 addEventListener 函数,两个参数都必须是字符串才行。所以最终的调用效果是:

function mouseuphandler(e) { alert('ok'); }
obj.addEventListener("mouseup", "mouseuphandler");

附上GE的调用方式:
google.earth.addEventListener(ge.getWindow(), 'click', function (event) { })

呵呵,差别还是挺大的吧,哎,还得改啊,有进展了再来分享。


PS:当用ActiveQt开发插件时,推荐用 out-of-process 方式,这样写出的插件是exe,可以直接运行,调试的时候方便不少,而且还能当桌面程序用,哈哈。

Qt写Activex插件 总结的更多相关文章

  1. Qt编写自定义控件插件路过的坑及注意事项

    在一日一控件的口号下,终于写好了五十几个自定义控件,包括各种仪表盘,各种温度计,各种进度条,各种按钮等,具体可参见(http://www.cnblogs.com/feiyangqingyun/p/61 ...

  2. C#开发ActiveX插件-aspx中嵌入

    刚到新的公司,第一周让我熟悉一下他们用的silverlight和arcgis.这周,也就是昨天分配了我一个小小的任务! 哪个项目的不知道,是让我实现一个在aspx中嵌入activeX插件! 在网上找了 ...

  3. 非IE内核浏览器支持activex插件

    之前在一个B/S项目中遇到一个需求,就是客户需要在页面上对报表的布局以及显示内容,进行自定义.最后决定使用activex技术来实现.众所周知,activex是微软搞得,因此只有ie内核的浏览器才能支持 ...

  4. 使用Qt编写模块化插件式应用程序

    动态链接库技术使软件工程师们兽血沸腾,它使得应用系统(程序)可以以二进制模块的形式灵活地组建起来.比起源码级别的模块化,二进制级别的模块划分使得各模块更加独立,各模块可以分别编译和链接,模块的升级不会 ...

  5. C#制作ActiveX插件

    首先新建项目--->类库,取名:ActiveXDemo 右键项目属性:应用属性==>程序集信息=>使程序集Com可见, 生成==>输出==>为com互操作注册 新建接口类 ...

  6. Qt编写activex控件在网页中运行

    qt能够实现的东西非常多,还可以写activex控件直接在网页中运行.参照qtdemo下的例子即可. 方案一:可执行文件下载:https://pan.baidu.com/s/14ge9ix2Ny0x7 ...

  7. 非IE内核浏览器如何支持activex插件

    原文地址:https://blog.csdn.net/johnson2008t/article/details/46126605 之前在一个B/S项目中遇到一个需求,就是客户需要在页面上对报表的布局以 ...

  8. ActiveX插件

    C#制作ActiveX插件 首先新建项目--->类库,取名:ActiveXDemo 右键项目属性:应用属性==>程序集信息=>使程序集Com可见, 生成==>输出==>为 ...

  9. 自己写jquery插件之模版插件高级篇(一)

    需求场景 最近项目改版中,发现很多地方有这样一个操作(见下图gif动画演示),很多地方都有用到.这里不讨论它的用户体验怎么样. 仅仅是从复用的角度,如果每个页面都去写text和select元素,两个b ...

随机推荐

  1. morse code

    morse code,摩斯电码,是一种时通时断的信号代码,通过不同的排列顺序来表达不同的英文字母.数字和标点符号. 摩斯电码,是一种早期的数字化通信形式,但是它不同于现代只使用0和1两种状态的二进制代 ...

  2. block要掌握的东西

    /* block要掌握的东西 1> 如何定义block变量 int (^sumBlock)(int, int); void (^myBlock)(); 2> 如何利用block封装代码 ^ ...

  3. Cufflinks

    Transcriptome assembly and differential expression analysis for RNA-Seq. Cufflinks assembles transcr ...

  4. CMake命令/函数汇总(翻译自官方手册)

    查看官方文档 cmake命令 选项 CMake变量 CMake命令汇总 / add_custom_command add_custom_target/add_definitions/add_depen ...

  5. MySQL分库分表总结

    单库单表 单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到. 单库多表 随着用户数量的增加,user表的数据量会越来越大,当数 ...

  6. java1

    1:计算机概述(了解) (1)计算机 (2)计算机硬件 (3)计算机软件 系统软件:window,linux,mac 应用软件:qq,yy,飞秋 (4)软件开发(理解) 软件:是由数据和指令组成的.( ...

  7. log4cxx

    1.简介 (1)Apache log4cxx当前是由Apache软件基金会进行维护.它是java中著名开源项目Apache log4j在c++中对应的日志框架.它是借助于APR(Apache Port ...

  8. testng 教程之使用参数的一些tricks配合使用reportng

    前两次的总结:testng annotation生命周期 http://www.cnblogs.com/tobecrazy/p/4579414.html testng.xml的使用和基本配置http: ...

  9. Linux搭建JDK、Tomcat安装及配置

    一.JDK安装及配置 1.JKD下载地址:http://pan.baidu.com/s/1i5NpImx 2.查看安装: rpm -qa | grep jdk 3.卸载:rpm -e --nodeps ...

  10. hdu 3746 Cyclic Nacklace

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746 思路:KMP中Next数组的应用,求出最小的循环节,题目的意思是只能在字符串的后面上添加新的字符 ...