欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

QT篇之QT与MxDraw COM控件

程序员文章站 2024-03-15 23:09:18
...

接上一篇QT篇之QT与数据库交互,现在开始在QT中调用MxDraw52控件

必要准备:请先在官网MxDraw下载MxDraw5.2控件,然后参照官方帮助文档qt中使用mxdraw控件自行安装好开发环境。

当我们注册好MxDraw控件,也添加了QAxWidget(选择 Active X为MxDraw52 control)之后。
然后开始编程吧~
先看一下运行效果:

QT篇之QT与MxDraw COM控件

可以放大缩小,也可以移动,同时点击下方数据事件就可以将定位坐标在CAD图上动态标注出来

QT篇之QT与MxDraw COM控件
QT篇之QT与MxDraw COM控件

OK,下面是具体实现

问题:

1.怎么查找控件接口的命令?
2.找到命令后如何调用?

先解决第一个问题:

两个办法:
1.通过官方给的最新的API接口来查看

QT篇之QT与MxDraw COM控件

比如这一个clear方法,删除一个对象并清除其内容。但是用这种方式找一个命令是比较麻烦的,因为我们不熟悉这个接口,一个一个找比较麻烦。所以就有了方法2.
2. 通过启动安装好的MxDraw软件,进入到编辑界面,我们点击右侧打开dwg文件按钮,可以在下方看到该按钮所对应的命令

QT篇之QT与MxDraw COM控件

我们看到这个命令以后,就可以通过索引的方式直接在官方API文档中查找,但是要注意了,命令要选择关键字,直接搜EditTestOpenDwgFile是找不到的,我们可以选取OpenDwg来索引一下

QT篇之QT与MxDraw COM控件

这样就可以看到了,这种方式还是比较直观且方便的。

再来解决第二个问题:

如何在QT中调用我们找到的命令呢?
我们可以看一下官方给的例子,代码如下:
void MainWindow::on_pushButton_clicked()
{
    // 执行控件自定义命令函数,命令的id为2,这个id用户可以自己取任意数,可以理解为是给执行的命令一个编号.
    ui->axWidget->dynamicCall("DoCommand(const qint32&)",2);
}
这是通过调用QAxWidget的dynamicCall方法,然后参数为对应控件的自定义命令执行函数。
我们先看一下dynamicCall函数的用法,QT官方文档说明如下:
QVariant QAxBase::dynamicCall(const char *function, const QVariant &var1 = QVariant(), const QVariant &var2 = QVariant(), const QVariant &var3 = QVariant(), const QVariant &var4 = QVariant(), const QVariant &var5 = QVariant(), const QVariant &var6 = QVariant(), const QVariant &var7 = QVariant(), const QVariant &var8 = QVariant())
Calls the COM object's method function, passing the parameters var1, var1, var2, var3, var4, var5, var6, var7 and var8, and returns the value returned by the method, or an invalid QVariant if the method does not return a value or when the function call failed.
If function is a method of the object the string must be provided as the full prototype, for example as it would be written in a QObject::connect() call.

  activeX->dynamicCall("Navigate(const QString&)", "www.qt-project.org");
第一个参数是命令名,后面的QVariant表示可以对该命令传递参数(注意参数一定是QVariant类型才可以)。
再来看Docommand命令,通过MxDraw官方API查看,如下:

QT篇之QT与MxDraw COM控件

参数就是自己定义的命令的编号。
那么问题来了,我们看到的参数都是COM所对应的类型,那么对应QT中的是哪个呢,比如SHORT类型对应的QT中的哪个类型呢?
这里提供一种简单高效的方式,就是利用QT的generateDocument命令,该命令说明如下:
QString QAxBase::generateDocumentation()
Returns a rich text string with documentation for the wrapped COM object. Dump the string to an HTML-file, or use it in e.g. a QTextBrowser widget.
他可以把插入的COM控件的命令参数转换为QT所对应的命令参数。使用方法如下面的代码:
      //下面是生成QT版的com接口说明文档,很有必要阅读
    QString doc=ui->axWidget->generateDocumentation();
    QFile outFile("c:/Users/13696/Desktop/项目参考资料/debuglog.html");
    outFile.open(QIODevice::WriteOnly|QIODevice::Append);
    QTextStream ts(&outFile);
    ts<<doc<<endl;
    outFile.close();
我们打开生成的.html文件,找到OpenDwgFile命令,可以看到

QT篇之QT与MxDraw COM控件

是不是都转换为QT的格式了,而且还有调用例子,是不是很方便呢!
那么问题都解决了,接下来只需要实现我们所需要的功能就好了。
可以看一下我的功能代码:
//控件命令按钮
void Widget::on_axWidget_ImplementCommandEvent(int iCommandId)
{
    if(iCommandId == 1){
        // 调用控件打开dwg文件命令。
        ui->axWidget->dynamicCall("OpenDwgFile(const QString&)","C:\\Users\\13696\\Desktop\\项目参考资料\\test.dwg");
    }
    if(iCommandId == 5){
        // 调用控件缩放命令。
        ui->axWidget->dynamicCall("ZoomScale(double dScale)",0.8);
    }
    if(iCommandId == 6){
        ui->axWidget->dynamicCall("ZoomScale(double dScale)",1.1);
    }
    if(iCommandId == 7){
        // 调用控件视区还原命令
        ui->axWidget->dynamicCall("ZoomAll()");
    }
    if(iCommandId == 8){
        // 调用控件移动视区命令
        ui->axWidget->dynamicCall("SendStringToExecute(P)");
    }
    if(iCommandId == 9){
       // 取消动态标记
        ui->axWidget->dynamicCall("StopAllTwinkeEnt()");
        for(int row=0;row<entityId.size();row++)
            if(entityId.contains(row)){
                QList<qlonglong> myValues = entityId.values(row);
                 for (int i=0;i<myValues.size();i++) {
                     ui->axWidget->dynamicCall("Clear(qlonglong)",myValues.at(i));
                     qDebug()<<"values="<<myValues.at(i);
                 }
            }
    }
}
有疑惑的应该是动态标记这块,我用的是以获取到数据事件定位点(坐标)然后将该坐标在CAD图上以画一个圆形对象的方式动态标记出来。当然也可以根据自己需要用别的方法来实现。关键代码如下:
 //画一个圆形,然后获取其ID,再动态闪烁,效果可以
    QVariant result = ui->axWidget->dynamicCall("DrawCircle(double, double, double)",coordinates[0],coordinates[1],300);
    qDebug()<<"id="<<result.toLongLong();
    qlonglong id= result.toLongLong();
    ui->axWidget->dynamicCall("TwinkeEnt(qlonglong)",id);

    entityId.insertMulti(row,id);                        //将该圆形实体ID存入容器,方便后期操作
OK,大体就是这么些东西了,淦!
相关标签: QT qt activex