翻譯|使用教程|編輯:鮑佳佳|2021-02-23 10:15:45.383|閱讀 372 次
概述:COM應用程序的例子展示了如何使用ActiveQt來開發一個可以通過COM自動化的Qt應用程序。不同的基于QObject的類被暴露為COM對象,與運行中的Qt應用程序的GUI進行通信。這些COM對象的API被設計成類似于標準COM應用程序的API,即那些來自Microsoft Office的API。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
Qt相關組件:
COM應用程序的例子展示了如何使用ActiveQt來開發一個可以通過COM自動化的Qt應用程序。不同的基于QObject的類被暴露為COM對象,與運行中的Qt應用程序的GUI進行通信。這些COM對象的API被設計成類似于標準COM應用程序的API,即那些來自Microsoft Office的API。
class Application : public QObject { Q_OBJECT Q_CLASSINFO("ClassID", "{b50a71db-c4a7-4551-8d14-49983566afee}") Q_CLASSINFO("InterfaceID", "{4a427759-16ef-4ed8-be79-59ffe5789042}") Q_CLASSINFO("RegisterObject", "yes") Q_PROPERTY(DocumentList* documents READ documents) Q_PROPERTY(QString id READ id) Q_PROPERTY(bool visible READ isVisible WRITE setVisible) public: explicit Application(QObject *parent = nullptr); DocumentList *documents() const; QString id() const { return objectName(); } void setVisible(bool on); bool isVisible() const; QTabWidget *window() const { return m_ui.data(); } public slots: void quit(); private: QScopedPointer <DocumentList> m_docs; QScopedPointer <QTabWidget> m_ui; };
第一個類Application代表應用對象。它公開了只讀屬性documents和id來獲取對文檔列表的訪問,以及一個標識符。一個讀/寫屬性visible控制應用程序基于QTabWidget的用戶界面是否應該可見,一個槽quit()終止應用程序。
RegisterObject屬性被設置為確保該類的實例在COM的運行對象表(ROT)中被注冊--這允許COM客戶端連接到一個已經實例化的COM對象。
class DocumentList : public QObject { Q_OBJECT Q_CLASSINFO("ClassID", "{496b761d-924b-4554-a18a-8f3704d2a9a6}") Q_CLASSINFO("InterfaceID", "{6c9e30e8-3ff6-4e6a-9edc-d219d074a148}") Q_PROPERTY(Application* application READ application) Q_PROPERTY(int count READ count) public: explicit DocumentList(Application *application); int count() const; Application *application() const; public slots: Document *addDocument(); Document *item(int index) const; private: QVector<Document *> m_list; };
DocumentList類存儲了一個文檔的列表,它提供了一個API來讀取文檔的數量,通過索引訪問每個文檔,并創建新的文檔。它提供了一個API來讀取文檔的數量,通過索引訪問每個文檔并創建一個新的文檔。應用屬性返回根對象。
class Document : public QObject { Q_OBJECT Q_CLASSINFO("ClassID", "{2b5775cd-72c2-43da-bc3b-b0e8d1e1c4f7}") Q_CLASSINFO("InterfaceID", "{2ce1761e-07a3-415c-bd11-0eab2c7283de}") Q_PROPERTY(Application *application READ application) Q_PROPERTY(QString title READ title WRITE setTitle) public: explicit Document(DocumentList *list); virtual ~Document(); Application *application() const; QString title() const; void setTitle(const QString &title); private: QScopedPointer <QWidget> m_page; };
Document類最后代表應用程序中的一個文檔。每個文檔由應用程序的標簽部件中的一個頁面來表示,并且有一個標題,這個標題是可以通過文檔的API來讀寫的。應用程序屬性再次返回根對象。
Document::Document(DocumentList *list) : QObject(list) { QTabWidget *tabs = list->application()->window(); m_page.reset(new QWidget(tabs)); m_page->setWindowTitle(tr("Unnamed")); tabs->addTab(m_page.data(), m_page->windowTitle()); m_page->show(); } Document::~Document() = default; Application *Document::application() const { return qobject_cast<DocumentList *>(parent())->application(); } QString Document::title() const { return m_page->windowTitle(); } void Document::setTitle(const QString &t) { m_page->setWindowTitle(t); QTabWidget *tabs = application()->window(); int index = tabs->indexOf(m_page.data()); tabs->setTabText(index, m_page->windowTitle()); }
Document該類的實現為選項卡小部件創建一個新頁面,并將該頁面的標題用作title屬性。刪除文檔后,頁面即被刪除。
DocumentList::DocumentList(Application *application) : QObject(application) { } Application *DocumentList::application() const { return qobject_cast<Application *>(parent()); } int DocumentList::count() const { return m_list.count(); } Document *DocumentList::item(int index) const { return m_list.value(index, nullptr); } Document *DocumentList::addDocument() { Document *document = new Document(this); m_list.append(document); return document; }
該DocumentList實現是直接的。
Application::Application(QObject *parent) : QObject(parent), m_ui(new QTabWidget), m_docs(new DocumentList(this)) { setObjectName(QStringLiteral("From QAxFactory")); } DocumentList *Application::documents() const { return m_docs.data(); } void Application::setVisible(bool on) { m_ui->setVisible(on); } bool Application::isVisible() const { return m_ui->isVisible(); } void Application::quit() { m_docs.reset(); m_ui.reset(); QTimer::singleShot(0 /*ms*/, qApp, &QCoreApplication::quit); } #include "main.moc"
在Application類初始化構造函數中的用戶界面,以及顯示和隱藏它的實現setVisible()。對象名稱(可通過id屬性訪問)設置為“ "From QAxFactory ”,以指示此COM對象已由COM創建。請注意,沒有析構函數可刪除QTabWidget-而是quit()在調用quit( )通過單次計時器進行,這是確保對插槽的COM調用完成所必需的。
QAXFACTORY_BEGIN("{edd3e836-f537-4c6f-be7d-6014c155cc7a}", "{b7da3de8-83bb-4bbe-9ab7-99a05819e201}") QAXCLASS(Application) QAXTYPE(Document) QAXTYPE(DocumentList) QAXFACTORY_END()
使用QAxFactory宏從服務器導出類。只能Application從外部實例化對象-其他API只能在訪問整個ApplicationAPI中的相應對象后才能使用。
int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); app.setQuitOnLastWindowClosed(false); // started by COM - don't do anything if (QAxFactory::isServer()) return app.exec(); // started by user Application appobject; appobject.setObjectName(QStringLiteral("From Application")); QAxFactory::startServer(); QAxFactory::registerActiveObject(&appobject); appobject.window()->setMinimumSize(300, 100); appobject.setVisible(true); QObject::connect(&app, &QGuiApplication::lastWindowClosed, &appobject, &Application::quit); return app.exec(); }
main()切入點函數創建一個QApplication,如果應用程序是由COM啟動的,則進入事件循環即可。如果應用程序已被用戶啟動,則創建Application對象,并將對象名設置為 "From Application"。然后啟動COM服務器,并將應用對象注冊到COM中。現在,COM客戶端可以通過客戶端特定的API來訪問它。
應用程序的退出是顯式控制的--如果COM啟動了應用程序,那么客戶端代碼必須調用quit();如果用戶啟動了應用程序,那么當最后一個窗口被關閉時,應用程序就會終止。
最后,使用戶界面可見,并啟動事件循環。
現在,一個簡單的Visual Basic應用程序可以訪問這個Qt應用程序。在VB中,啟動一個新的 "Standard Exe "項目,并向comappLib類型庫添加一個項目引用。創建一個具有列表框 "DocumentList"、靜態標簽 "DocumentsCount "和命令按鈕 "NewDocument "的窗體。最后,像這樣實現表單的代碼。
Private Application As comappLib.Application Private MyApp As Boolean Private Sub UpdateList() DocumentList.Clear DocumentsCount.Caption = Application.documents.Count For Index = 0 To Application.documents.Count - 1 DocumentList.AddItem (Application.documents.Item(Index).Title) Next End Sub Private Sub Form_Load() On Error GoTo CreateNew Set Application = GetObject(, "comapp.Application") MyApp = False GoTo Initialized CreateNew: On Error GoTo InitializeFailed Set Application = New Application Application.Visible = True MyApp = True Initialized: Caption = Application.id UpdateList InitializeFailed: End Sub Private Sub Form_Unload(Cancel As Integer) If MyApp Then Application.quit End If End Sub Private Sub NewDocument_Click() Application.documents.addDocument UpdateList End Sub
要構建示例,您必須首先構建QAxServer庫。然后運行qmake,將您的制作工具放入examples\activeqt\comapp。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自: