当前位置:   article > 正文

Qt开发示例:COM应用程序示例(ActiveQt)_active qt

active qt

COM应用程序的例子展示了如何使用ActiveQt来开发一个可以通过COM自动化的Qt应用程序。不同的基于QObject的类被暴露为COM对象,与运行中的Qt应用程序的GUI进行通信。这些COM对象的API被设计成类似于标准COM应用程序的API,即那些来自Microsoft Office的API。

  1. class Application : public QObject
  2. {
  3. Q_OBJECT
  4. Q_CLASSINFO("ClassID", "{b50a71db-c4a7-4551-8d14-49983566afee}")
  5. Q_CLASSINFO("InterfaceID", "{4a427759-16ef-4ed8-be79-59ffe5789042}")
  6. Q_CLASSINFO("RegisterObject", "yes")
  7. Q_PROPERTY(DocumentList* documents READ documents)
  8. Q_PROPERTY(QString id READ id)
  9. Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
  10. public:
  11. explicit Application(QObject *parent = nullptr);
  12. DocumentList *documents() const;
  13. QString id() const { return objectName(); }
  14. void setVisible(bool on);
  15. bool isVisible() const;
  16. QTabWidget *window() const { return m_ui.data(); }
  17. public slots:
  18. void quit();
  19. private:
  20. QScopedPointer <DocumentList> m_docs;
  21. QScopedPointer <QTabWidget> m_ui;
  22. };
  23. 复制代码

第一个类Application代表应用对象。它公开了只读属性documents和id来获取对文档列表的访问,以及一个标识符。一个读/写属性visible控制应用程序基于QTabWidget的用户界面是否应该可见,一个槽quit()终止应用程序。

RegisterObject属性被设置为确保该类的实例在COM的运行对象表(ROT)中被注册--这允许COM客户端连接到一个已经实例化的COM对象。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

  1. class DocumentList : public QObject
  2. {
  3. Q_OBJECT
  4. Q_CLASSINFO("ClassID", "{496b761d-924b-4554-a18a-8f3704d2a9a6}")
  5. Q_CLASSINFO("InterfaceID", "{6c9e30e8-3ff6-4e6a-9edc-d219d074a148}")
  6. Q_PROPERTY(Application* application READ application)
  7. Q_PROPERTY(int count READ count)
  8. public:
  9. explicit DocumentList(Application *application);
  10. int count() const;
  11. Application *application() const;
  12. public slots:
  13. Document *addDocument();
  14. Document *item(int index) const;
  15. private:
  16. QVector<Document *> m_list;
  17. };
  18. 复制代码

DocumentList类存储了一个文档的列表,它提供了一个API来读取文档的数量,通过索引访问每个文档,并创建新的文档。它提供了一个API来读取文档的数量,通过索引访问每个文档并创建一个新的文档。应用属性返回根对象。

  1. class Document : public QObject
  2. {
  3. Q_OBJECT
  4. Q_CLASSINFO("ClassID", "{2b5775cd-72c2-43da-bc3b-b0e8d1e1c4f7}")
  5. Q_CLASSINFO("InterfaceID", "{2ce1761e-07a3-415c-bd11-0eab2c7283de}")
  6. Q_PROPERTY(Application *application READ application)
  7. Q_PROPERTY(QString title READ title WRITE setTitle)
  8. public:
  9. explicit Document(DocumentList *list);
  10. virtual ~Document();
  11. Application *application() const;
  12. QString title() const;
  13. void setTitle(const QString &title);
  14. private:
  15. QScopedPointer <QWidget> m_page;
  16. };
  17. 复制代码

Document类最后代表应用程序中的一个文档。每个文档由应用程序的标签部件中的一个页面来表示,并且有一个标题,这个标题是可以通过文档的API来读写的。应用程序属性再次返回根对象。

  1. Document::Document(DocumentList *list)
  2. : QObject(list)
  3. {
  4. QTabWidget *tabs = list->application()->window();
  5. m_page.reset(new QWidget(tabs));
  6. m_page->setWindowTitle(tr("Unnamed"));
  7. tabs->addTab(m_page.data(), m_page->windowTitle());
  8. m_page->show();
  9. }
  10. Document::~Document() = default;
  11. Application *Document::application() const
  12. {
  13. return qobject_cast<DocumentList *>(parent())->application();
  14. }
  15. QString Document::title() const
  16. {
  17. return m_page->windowTitle();
  18. }
  19. void Document::setTitle(const QString &t)
  20. {
  21. m_page->setWindowTitle(t);
  22. QTabWidget *tabs = application()->window();
  23. int index = tabs->indexOf(m_page.data());
  24. tabs->setTabText(index, m_page->windowTitle());
  25. }
  26. 复制代码

Document该类的实现为选项卡小部件创建一个新页面,并将该页面的标题用作title属性。删除文档后,页面即被删除。

  1. DocumentList::DocumentList(Application *application)
  2. : QObject(application)
  3. {
  4. }
  5. Application *DocumentList::application() const
  6. {
  7. return qobject_cast<Application *>(parent());
  8. }
  9. int DocumentList::count() const
  10. {
  11. return m_list.count();
  12. }
  13. Document *DocumentList::item(int index) const
  14. {
  15. return m_list.value(index, nullptr);
  16. }
  17. Document *DocumentList::addDocument()
  18. {
  19. Document *document = new Document(this);
  20. m_list.append(document);
  21. return document;
  22. }
  23. 复制代码

该DocumentList实现是直接的。

  1. Application::Application(QObject *parent)
  2. : QObject(parent),
  3. m_ui(new QTabWidget),
  4. m_docs(new DocumentList(this))
  5. {
  6. setObjectName(QStringLiteral("From QAxFactory"));
  7. }
  8. DocumentList *Application::documents() const
  9. {
  10. return m_docs.data();
  11. }
  12. void Application::setVisible(bool on)
  13. {
  14. m_ui->setVisible(on);
  15. }
  16. bool Application::isVisible() const
  17. {
  18. return m_ui->isVisible();
  19. }
  20. void Application::quit()
  21. {
  22. m_docs.reset();
  23. m_ui.reset();
  24. QTimer::singleShot(0 /*ms*/, qApp, &QCoreApplication::quit);
  25. }
  26. #include "main.moc"
  27. 复制代码

在Application类初始化构造函数中的用户界面,以及显示和隐藏它的实现setVisible()。对象名称(可通过id属性访问)设置为“ "From QAxFactory ”,以指示此COM对象已由COM创建。请注意,没有析构函数可删除QTabWidget-而是quit()在调用quit( )通过单次计时器进行,这是确保对插槽的COM调用完成所必需的。

  1. QAXFACTORY_BEGIN("{edd3e836-f537-4c6f-be7d-6014c155cc7a}", "{b7da3de8-83bb-4bbe-9ab7-99a05819e201}")
  2. QAXCLASS(Application)
  3. QAXTYPE(Document)
  4. QAXTYPE(DocumentList)
  5. QAXFACTORY_END()
  6. 复制代码

使用QAxFactory宏从服务器导出类。只能Application从外部实例化对象-其他API只能在访问整个ApplicationAPI中的相应对象后才能使用。

  1. int main(int argc, char *argv[])
  2. {
  3. QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
  4. QApplication app(argc, argv);
  5. app.setQuitOnLastWindowClosed(false);
  6. // started by COM - don't do anything
  7. if (QAxFactory::isServer())
  8. return app.exec();
  9. // started by user
  10. Application appobject;
  11. appobject.setObjectName(QStringLiteral("From Application"));
  12. QAxFactory::startServer();
  13. QAxFactory::registerActiveObject(&appobject);
  14. appobject.window()->setMinimumSize(300, 100);
  15. appobject.setVisible(true);
  16. QObject::connect(&app, &QGuiApplication::lastWindowClosed, &appobject, &Application::quit);
  17. return app.exec();
  18. }
  19. 复制代码

main()切入点函数创建一个QApplication,如果应用程序是由COM启动的,则进入事件循环即可。如果应用程序已被用户启动,则创建Application对象,并将对象名设置为 "From Application"。然后启动COM服务器,并将应用对象注册到COM中。现在,COM客户端可以通过客户端特定的API来访问它。

应用程序的退出是显式控制的--如果COM启动了应用程序,那么客户端代码必须调用quit();如果用户启动了应用程序,那么当最后一个窗口被关闭时,应用程序就会终止。

最后,使用户界面可见,并启动事件循环。

现在,一个简单的Visual Basic应用程序可以访问这个Qt应用程序。在VB中,启动一个新的 "Standard Exe "项目,并向comappLib类型库添加一个项目引用。创建一个具有列表框 "DocumentList"、静态标签 "DocumentsCount "和命令按钮 "NewDocument "的窗体。最后,像这样实现表单的代码。

  1. Private Application As comappLib.Application
  2. Private MyApp As Boolean
  3. Private Sub UpdateList()
  4. DocumentList.Clear
  5. DocumentsCount.Caption = Application.documents.Count
  6. For Index = 0 To Application.documents.Count - 1
  7. DocumentList.AddItem (Application.documents.Item(Index).Title)
  8. Next
  9. End Sub
  10. Private Sub Form_Load()
  11. On Error GoTo CreateNew
  12. Set Application = GetObject(, "comapp.Application")
  13. MyApp = False
  14. GoTo Initialized
  15. CreateNew:
  16. On Error GoTo InitializeFailed
  17. Set Application = New Application
  18. Application.Visible = True
  19. MyApp = True
  20. Initialized:
  21. Caption = Application.id
  22. UpdateList
  23. InitializeFailed:
  24. End Sub
  25. Private Sub Form_Unload(Cancel As Integer)
  26. If MyApp Then
  27. Application.quit
  28. End If
  29. End Sub
  30. Private Sub NewDocument_Click()
  31. Application.documents.addDocument
  32. UpdateList
  33. End Sub
  34. 复制代码

要构建示例,您必须首先构建QAxServer库。然后运行qmake,将您的制作工具放入examples\activeqt\comapp。

Qt相关组件:

  • QtitanRibbon| 下载试用:**** 遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件,致力于为Windows、Linux和Mac OS X提供功能完整的Ribbon组件。
  • **QtitanChart | 下载试用 :**是一个C ++库,代表一组控件,这些控件使您可以快速地为应用程序提供漂亮而丰富的图表。并且支持所有主要的桌面操作系统。
  • **QtitanDataGrid | 下载试用 :**这个Qt数据网格组件使用纯C++创建,运行速度极快,处理大数据和超大数据集的效果突出。QtitanDataGrid完全集成了QtDesigner,因而极易适应其他相似的开发环境,保证100%兼容Qt GUI。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/109949
推荐阅读
  

闽ICP备14008679号