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

我写的这个插件的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. IntersectionObserver API

    温馨提示:本文目前仅适用于在 Chrome 51 及以上中浏览. 2016.11.1 追加,Firefox 52 也已经实现. 2016.11.29 追加,Firefox 的人担心目前规范不够稳定,未 ...

  2. 大熊君学习html5系列之------History API(SPA单页应用的必备------重构完结版)

    一,开篇分析 Hi,大家好!大熊君又和大家见面了,(*^__^*) 嘻嘻……,这系列文章主要是学习Html5相关的知识点,以学习API知识点为入口,由浅入深的引入实例, 让大家一步一步的体会" ...

  3. 【转载】使用Pandas对数据进行筛选和排序

    使用Pandas对数据进行筛选和排序 本文转载自:蓝鲸的网站分析笔记 原文链接:使用Pandas对数据进行筛选和排序 目录: sort() 对单列数据进行排序 对多列数据进行排序 获取金额最小前10项 ...

  4. NOSDK--一键打包的实现(二)

    Android.mk文件,位置在android工程/jni目录下,是android工程中的makefile文件,这里我们简称它为mk文件. 1.2 自动刷新mk文件的脚本介绍 这一节介绍mk文件的自动 ...

  5. soundtouch变速wsola算法之改进

    soundtouch变速算法很类似sola算法,细看才知道是wsola算法. 上个星期有个需求,将该变速应用到直播的包处理,有点类似于webrtc的netEQ处理机制. 直接使用soundtouch, ...

  6. Python3实现简单的爬虫功能

    python3简单实现一个爬去网站图片的小功能: 有时候想要下载自己喜欢的多个图片时,不需要一个个点击来下载,使用python脚本批量拉取,并保存到本地. 1. 首先找到自己要下载图片的url 2. ...

  7. vim 使用

    vim有三种模式:输入模式,命令模式,底行模式,使用esc进入命令模式,在命令模式下按英文的冒号,进入底行模式:命令行模式下按i进入输入模式.vim编辑文件是将文件内容复制到缓冲区显示在屏幕上. vi ...

  8. sql语句中----删除表数据drop、truncate和delete的用法

    sql语句中----删除表数据drop.truncate和delete的用法 --drop drop table  tb   --tb表示数据表的名字,下同 删除内容和定义,释放空间.简单来说就是把整 ...

  9. CKEditor 配置

    在asp.net 中注意需要特殊处理控件的ID 先引入js <script type="text/javascript" src="ckeditor/ckedito ...

  10. [转] CC 命令

    1.最基本的操作cleartool co -nc xxx.cppcleartool ci -nc xxx.cpp 2.查看自己总共co了多少文件cleartool lscheckout -cview ...