Monthly Archives: March 2006

一个Qt Excel的文档翻译

使用Qt调用Excel

Eugene Eremin

翻译:tong # cngis.org

原文Urlhttp://www.qtlib.ru/index.php?option=com_content&task=view&id=42&Itemid=28

 

Qt 3.1及以上版本的一个新特性是为Windows操作系统提供了ActiveX支持。开发者如果关心如何使用Qt操作COM组件,比如在Excel里插入新数据,这个新增功能就很重要了。

然而不幸的是,在Internet上没有太多这方面的主题可以借鉴。我在这里演示一个例子,可能会对大家有所帮助。

首先我们来看一下Qt自带的例子。通常Qt自带的例子可以告诉大家一些常用的知识点。我不记得在哪里看过,说一个好的文档应当是用户看过后不再存在不解的地方。但Qt只提供了一个与MS Outlook Express交互的例子。不过这就是我开始Excel交互研究的起点了。

ActiveXCOM的区别不是很大,我不是这方面的专家,但我在这里推荐大家看一本Adam Denninga的书“ActiveX for professionals”。这本书会帮助大家很好地理解这些概念。第一步,我们来引入Excel,并创建一个对象。

#include <qaxobject.h>

QAxObject* excel = new QAxObject( "Excel.Application", this ); //获取一个Excel对象

excel->dynamicCall( "SetVisible(bool)", TRUE ); //设置为可见

这里我们通过代码构建了一个对象,并通过对象打开了Excel。第二步,我们计划插入新数据。为了做到这一步,必须了解一点Excel文档的结构。Excel应用程序包括一系列的workbooks,每个workbook又由多个sheets组成。Microsoft公司并没有给出太多这方面的结构信息,我在Google上寻找了不短的时间,也没有太多的结果。

QAxObject *workbooks = excel->querySubObject( "Workbooks" ); //得到Workbooks集合的指针

QAxObject *workbook = workbooks->querySubObject( "Open(const QString&)", "C:dataA.xls" ); //打开硬盘上的一个Excel文档

QAxObject *sheets = workbook->querySubObject( "Sheets" ); //得到Sheets对象的指针

QAxObject *StatSheet = sheets->querySubObject( "Item(const QVariant&)", QVariant("stat") );     //得到名为stat的一个sheet的指针

StatSheet->dynamicCall( "Select()" ); //选择名为statsheet使之可见 

QAxObject *range = StatSheet->querySubObject( "Range(const QVariant&)", QVariant( Qstring("A1:A1")));  //选择A1:A1这个range对象

range->dynamicCall( "Clear()" ); // 清除range对象

range->dynamicCall( "SetValue(const QVariant&)", QVariant(5) ); //将该range对象的值设为5

接下去用户可以保存和关闭这个Excel文档了。

最后说一句,这些对象的接口可以通过generateDocumentation () 产生。比如,我们可以这样做:

QFile outfile("excel.html");

QTextStream out( &outfile );

outfile.open( IO_WriteOnly | IO_Translate );

QString docu = excel->generateDocumentation();

out << docu;

outfile.close();

这些信息被保存在名为“excel.html”的文件里。如果插入的数据很大,会花费很多的时间。MFC使用了专门的class,但我没能在Qt里实现这个class。如果有意见,请反馈至http://prog.org.ru/forum/ptopic_141.html

译者注:本文由在线语言工具从俄语翻译至英语,然后人工翻译成中文,因此中文与俄文可能有一些出入,欢迎指正。

Qt 4里已经有很多的有关ActiveQt的文档,大家应当以那个为主要的学习的材料。

 

上周五早讨论时遇到的几个问题

1. olb?

*.olb可被认为是*.tlb的前身,它也是表述com对象的信息,现在已经被定义更完整的
*.tlb代替掉了,使用*.olb的ocs/activeX一般是较为早期的产品。

2. axWidgetTOC->dynamicCall("SetBuddyControl(IDispatch*)",
(axWidgetPageLayout->querySubObject("Object"))->asVariant());

Object是PageLayout的一个属性。querySubObject输入方法名或属性名。
HRESULT IPageLayoutControl2::get_Object(
IDispatch** ppDispatch
);

3. catalog open file dialog

GxDialog在ArcEngine里不能用。这里有个帖子讨论这个问题:
http://forums.esri.com/Thread.asp?c=159&f=1705&t=163159&mc=5
这里有个例子,也可以参考
http://edndoc.esri.com/arcobjects/9.0/default.asp?URL=/arcobjects/9.0/Sample
s/Geodatabase/Accessing_Data/Browse_for_data_using_name_objects/Browse_for_d
ata_using_name_objects.htm

4. Q_Declare_private / d_func()
目的是为了在类里隐藏界面冗长的代码,将界面代码放置到专设的 QxxxPrivate类里
去。相关的定义如下:
#define Q_DECLARE_PRIVATE(Class)
inline Class##Private* d_func() { return reinterpret_cast<Class##Private
*>(d_ptr); }
inline const Class##Private* d_func() const { return
reinterpret_cast<const Class##Private *>(d_ptr); }
friend class Class##Private;

#define Q_DECLARE_PUBLIC(Class)
inline Class* q_func() { return static_cast<Class *>(q_ptr); }
inline const Class* q_func() const { return static_cast<const Class
*>(q_ptr); }
friend class Class;

#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func()

在使用时,
//////////////////////
class QDialogPrivate;

class Q_GUI_EXPORT QDialog : public QWidget
{
Q_OBJECT
Q_DECLARE_PRIVATE(QDialog)
///////////////////////
class QDialogPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QDialog)
public:
///////////////////////
d_ptr是在QObject里定义的,protected,为指向 QObjectData的指针
p_ptr是在QObjectData里定义,public,指向QObject的指针
在使用时,定义Q_D(class)和Q_Q(Class),直接使用 d和q两个指针

集思gis精华帖子

集思从99年到现在,已经7年时间,积累了很多很好的帖子,都是网友智慧和知识的体
现。在小z的帮助下,建立了精华帖子的数据库,并打包成exe,可以安装到每人的机器
上。具备以下特点:
1. 使用mybase进行资料管理
2. 安装包和数据包分享,极小的安装包,数据包自动从网络上下载,或手动下载
3. 提供了安装wizard
4. 提供自动更新功能,新版本的精华帖子包,可以使用提供的“更新”功能进行下载
升级
v0.1测试版请从 http://503.mygis.org/cngis_collection/cngis_collection_setup.
exe
下载,安装之
界面见附件

友情提示,请从可靠来源下载可执行软件,用杀毒软件扫描,并安装

Founder Apabi Reader 图书馆版 1.82

图书馆买了一年的方正电子图书帐号,检查一下,发现还是有一些相关的书。
Reader其实是个做的不错的软件,无论从功能上还是外观上,都很出色,而且下载借阅
的速度也很快。
试着下载了一本图书,发现只有3天的借期,到期需要续借,而且无法打印(我其实很
想将其打印成pdf保存)
google了一下,一下子也找不着,个别论坛提示说有解除限制的方法或crk,但论坛限
制太多,或者根本就是骗点击
试着将Reader.exe反汇编了一下,发现很多信息都是明码保存在exe里,作者好象没在
反反汇编上下功夫。
找到几处切入点(比如打印选项无效,比如提示不能打印,比如对pdf虚拟打印机无效
等),简单处理了一下,发现就可以了,只是打印出来的pdf有些大。然后试着写了一
个图形patch界面,附下。(好象有很多别人已经写好的专用于patch的小软件,但懒得
找了,反正用qt写很方便,只是出来的结果文件大些)
仅是学习试验了一下,本人不提供任何具体的crk信息

如果档案图像无法显示

先检索档案的权限设置,将图像所在的栏目权限设成“公共”,如果还无法显示(我遇到的就是这种情况),将当前的档案文件删除(编辑档案文件页面的上部),然后重新创建,再上传照片。这个操作是安全的。

接到通知,旁听人大会议

93省委办公室通知,让去旁听省人大常委的第xxx次会议。建立旁听制度,据说是为了增加透明性。九三省委有1个名额,怎么就轮到我了。不过也许可以了解一下这种当官的会议跟咱们的学术会议有什么不一样,应该是官僚很重的那种。比如看到报到书上写着,旁听人员如果要发言,必须要经xxx人同意等。主要议题好象是传达刚结束的全国人大的这些精神。

arcims .net link的几种方式

至少有三种方式可以实现:
1. 通过servlet,asp.net其实是生成了servlet的url get串所需的参数。网上可以找
到一个例子,.net primer的实现就是基于这种方式。效率可能有点低。
2. arcims自身提供的.net link dll,链接进vs project refences。未在asp.net 2下
测试,未必与2.0兼容。
3. 一个意大利人开发的 .net connector 2.14,他自称是支持asp.net 2,刚才用对象
查看器检查了一下,发现对image service等几个有比较好的支持,已经实现了一些便
利的比如取得地图等方法。缺少文档,仅有的一点也是意大利文,metadata没有实现的
支持,但可通过sendrequesttoservice方法来进行get_metadata和 publish_metadata