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

我写的这个插件的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. Tomcat基本入门知识及发布,虚拟访问及启动碰到的错误,虚拟目录,虚拟路径,各种Tomcat的配置

    Tomcat容器入门介绍 转自javaresearch.com由timgball 整理 Tomcat是一个免费的开源Web服务器,最新版本是5.5.1,支持Servlet2.4,JSP2.0,非常适合 ...

  2. JAVA中获取当前系统时间及格式转换

    JAVA中获取当前系统时间   一. 获取当前系统时间和日期并格式化输出: import java.util.Date;import java.text.SimpleDateFormat; publi ...

  3. 浅谈Android中layout_weight

    引言 在开发android过程中,我们经常需要对界面进行按比例进行布局,我们一般都会使用layout_属性来进行设置.今天这篇文章我们就来简单介绍下layout_weight的使用和布局原理.随着做项 ...

  4. 获取APP最新版本的接口案例

    思路: 开发初期.安卓的应用可能没有上传到应用市场,可以把应用apk放到服务器上,供用户下载.把对应用的版本信息整理成为一个XML文件,放到服务器上,通过接口读取xml文件,获取有版本信息,然后安卓端 ...

  5. DataTable数据检索的性能分析(转寒江独钓)

    我们知道在.NET平台上有很多种数据存储,检索解决方案-ADO.NET Entity Framework,ASP.NET Dynamic Data,XML, NHibernate,LINQ to SQ ...

  6. LNMP环境搭建笔记

    说明:前面尝试的在ubuntu12.04上搭建的LAMP环境由于开发的需要需要对php的版本进行升级,然而通过apt-get库安装的php的版本是5.3.10,不能满足开发需要.此笔记安装的php的 ...

  7. jquery 扩展插件方法

    分析插件jquery.countdown.js (function($) { $.fn.countdown = function(options) { // default options var d ...

  8. Java 中的内存泄露

    1.当你完成对流的读写时,应该通过调同close方法来关闭它,这个调用会释放掉十分有限的系统资源,否则,如果一个应用程序打开了过多的流而没有关闭,那么系统资源将被耗尽.

  9. 6个变态的C语言Hello World程序

    6个变态的C语言Hello World程序   下面的六个程序片段主要完成这些事情: 输出Hello, World 混乱C语言的源代码 下面的所有程序都可以在GCC下编译通过,只有最后一个需要动用C+ ...

  10. Eclipse自动编译问题

    今天遇到一个很郁闷的问题,在程序中修改了一个String字符串,结果打断点是发现,还是修改之前的值,一点都没有变,最终发现该类在tomcat中的class的大小一直都没有变,只有修改时间在变,这才意识 ...