Repository: myhhub/CTK-project Branch: main Commit: 6defa4ad78a7 Files: 171 Total size: 348.8 KB Directory structure: gitextract_mzwwt_jh/ ├── EventAdmin/ │ ├── SendEvent/ │ │ ├── App/ │ │ │ ├── App.pro │ │ │ └── main.cpp │ │ ├── CTK.pri │ │ ├── Plugins/ │ │ │ ├── BlogEventHandler/ │ │ │ │ ├── BlogEventHandler.pro │ │ │ │ ├── MANIFEST.MF │ │ │ │ ├── Resource.qrc │ │ │ │ ├── blog_event_handler.h │ │ │ │ ├── blog_event_handler_activator.cpp │ │ │ │ └── blog_event_handler_activator.h │ │ │ ├── BlogManager/ │ │ │ │ ├── BlogManager.pro │ │ │ │ ├── MANIFEST.MF │ │ │ │ ├── Resource.qrc │ │ │ │ ├── blog_manager.cpp │ │ │ │ ├── blog_manager.h │ │ │ │ ├── blog_manager_activator.cpp │ │ │ │ └── blog_manager_activator.h │ │ │ └── Plugins.pro │ │ ├── SendEvent.pro │ │ └── SendEvent.pro.user │ └── SignalSlot/ │ ├── App/ │ │ ├── App.pro │ │ └── main.cpp │ ├── CTK.pri │ ├── Plugins/ │ │ ├── BlogEventHandlerUsingSlots/ │ │ │ ├── BlogEventHandlerUsingSlots.pro │ │ │ ├── MANIFEST.MF │ │ │ ├── Resource.qrc │ │ │ ├── blog_event_handler_using_slots.h │ │ │ ├── blog_event_handler_using_slots_activator.cpp │ │ │ └── blog_event_handler_using_slots_activator.h │ │ ├── BlogManagerUsingSignals/ │ │ │ ├── BlogManagerUsingSignals.pro │ │ │ ├── MANIFEST.MF │ │ │ ├── Resource.qrc │ │ │ ├── blog_manager_using_signals.cpp │ │ │ ├── blog_manager_using_signals.h │ │ │ ├── blog_manager_using_signals_activator.cpp │ │ │ └── blog_manager_using_signals_activator.h │ │ └── Plugins.pro │ ├── SignalSlot.pro │ └── SignalSlot.pro.user ├── EventListener/ │ ├── EventListener.pro │ ├── EventListener.pro.user │ ├── event_listener.cpp │ ├── event_listener.h │ └── main.cpp ├── GetMetaData/ │ ├── GetMetaData.pro │ ├── GetMetaData.pro.user │ └── main.cpp ├── PluginAndService/ │ ├── MultipleInterfaces/ │ │ ├── App/ │ │ │ ├── App.pro │ │ │ └── main.cpp │ │ ├── CTK.pri │ │ ├── MultipleInterfaces.pro │ │ ├── MultipleInterfaces.pro.user │ │ └── Plugin/ │ │ ├── MANIFEST.MF │ │ ├── Plugin.pro │ │ ├── Resource.qrc │ │ ├── greet_activator.cpp │ │ ├── greet_activator.h │ │ ├── greet_impl.cpp │ │ ├── greet_impl.h │ │ └── greet_service.h │ └── OneInterface/ │ ├── App/ │ │ ├── App.pro │ │ └── main.cpp │ ├── CTK.pri │ ├── OneInterface.pro │ ├── OneInterface.pro.user │ ├── Plugins/ │ │ ├── Plugins.pro │ │ ├── WelcomeCTK/ │ │ │ ├── MANIFEST.MF │ │ │ ├── Resource.qrc │ │ │ ├── WelcomeCTK.pro │ │ │ ├── welcome_ctk_activator.cpp │ │ │ ├── welcome_ctk_activator.h │ │ │ ├── welcome_ctk_impl.cpp │ │ │ └── welcome_ctk_impl.h │ │ └── WelcomeQt/ │ │ ├── MANIFEST.MF │ │ ├── Resource.qrc │ │ ├── WelcomeQt.pro │ │ ├── welcome_qt_activator.cpp │ │ ├── welcome_qt_activator.h │ │ ├── welcome_qt_impl.cpp │ │ └── welcome_qt_impl.h │ └── Service/ │ └── welcome_service.h ├── README.md ├── RequirePlugin/ │ ├── App/ │ │ ├── App.pro │ │ └── main.cpp │ ├── CTK.pri │ ├── Plugins/ │ │ ├── PluginA/ │ │ │ ├── MANIFEST.MF │ │ │ ├── PluginA.pro │ │ │ ├── Resource.qrc │ │ │ ├── plugin_a_activator.cpp │ │ │ ├── plugin_a_activator.h │ │ │ ├── plugin_a_impl.cpp │ │ │ ├── plugin_a_impl.h │ │ │ └── plugin_a_service.h │ │ ├── PluginB/ │ │ │ ├── MANIFEST.MF │ │ │ ├── PluginB.pro │ │ │ ├── Resource.qrc │ │ │ ├── plugin_b_activator.cpp │ │ │ ├── plugin_b_activator.h │ │ │ ├── plugin_b_impl.cpp │ │ │ ├── plugin_b_impl.h │ │ │ └── plugin_b_service.h │ │ └── Plugins.pro │ ├── RequirePlugin.pro │ └── RequirePlugin.pro.user ├── SampleCTK/ │ ├── App/ │ │ ├── App.pro │ │ └── main.cpp │ ├── CTK.pri │ ├── HelloCTK/ │ │ ├── HelloCTK.pro │ │ ├── MANIFEST.MF │ │ ├── Resource.qrc │ │ ├── hello_activator.cpp │ │ ├── hello_activator.h │ │ ├── hello_impl.cpp │ │ ├── hello_impl.h │ │ └── hello_service.h │ ├── SampleCTK.pro │ └── SampleCTK.pro.user ├── ServiceFactory/ │ ├── App/ │ │ ├── App.pro │ │ └── main.cpp │ ├── CTK.pri │ ├── Plugins/ │ │ ├── Hello/ │ │ │ ├── Hello.pro │ │ │ ├── MANIFEST.MF │ │ │ ├── Resource.qrc │ │ │ ├── hello_activator.h │ │ │ ├── hello_impl.h │ │ │ ├── hello_service.h │ │ │ └── service_factory.h │ │ ├── PluginA/ │ │ │ ├── MANIFEST.MF │ │ │ ├── PluginA.pro │ │ │ ├── Resource.qrc │ │ │ ├── plugin_a_activator.cpp │ │ │ ├── plugin_a_activator.h │ │ │ ├── plugin_a_impl.cpp │ │ │ ├── plugin_a_impl.h │ │ │ └── plugin_a_service.h │ │ ├── PluginB/ │ │ │ ├── MANIFEST.MF │ │ │ ├── PluginB.pro │ │ │ ├── Resource.qrc │ │ │ ├── plugin_b_activator.cpp │ │ │ ├── plugin_b_activator.h │ │ │ ├── plugin_b_impl.cpp │ │ │ ├── plugin_b_impl.h │ │ │ └── plugin_b_service.h │ │ └── Plugins.pro │ ├── ServiceFactory.pro │ └── ServiceFactory.pro.user ├── ServiceTracker/ │ ├── App/ │ │ ├── App.pro │ │ └── main.cpp │ ├── CTK.pri │ ├── Plugins/ │ │ ├── Log/ │ │ │ ├── Log.pro │ │ │ ├── MANIFEST.MF │ │ │ ├── Resource.qrc │ │ │ ├── log_activator.cpp │ │ │ ├── log_activator.h │ │ │ ├── log_impl.cpp │ │ │ ├── log_impl.h │ │ │ └── log_service.h │ │ ├── Login/ │ │ │ ├── Login.pro │ │ │ ├── MANIFEST.MF │ │ │ ├── Resource.qrc │ │ │ ├── login_activator.cpp │ │ │ ├── login_activator.h │ │ │ ├── login_impl.cpp │ │ │ ├── login_impl.h │ │ │ ├── login_service.h │ │ │ └── service_tracker.h │ │ └── Plugins.pro │ ├── ServiceTracker.pro │ └── ServiceTracker.pro.user └── UseCTKWidgets/ ├── UseCTKWidgets.pro ├── UseCTKWidgets.pro.user └── main.cpp ================================================ FILE CONTENTS ================================================ ================================================ FILE: EventAdmin/SendEvent/App/App.pro ================================================ QT += core gui widgets TEMPLATE = app CONFIG += console TARGET = App DESTDIR = $$OUT_PWD/../bin include($$PWD/../CTK.pri) SOURCES += \ main.cpp ================================================ FILE: EventAdmin/SendEvent/App/main.cpp ================================================ #include #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); // 获取插件所在位置 // 在插件的搜索路径列表中添加一条路径 ctkPluginFrameworkLauncher::addSearchPath("../../../../CTKInstall/lib/ctk-0.1/plugins"); // 设置并启动 CTK 插件框架 ctkPluginFrameworkLauncher::start("org.commontk.eventadmin"); // 获取插件上下文 ctkPluginContext* context = ctkPluginFrameworkLauncher::getPluginContext(); QString path = QCoreApplication::applicationDirPath() + "/plugins"; // 启动插件 BlogEventHandler try { QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(path + "/BlogEventHandler.dll")); plugin->start(); qDebug() << "BlogEventHandler start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to start BlogEventHandler" << e.what(); } //启动插件 BlogManager try { QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(path + "/BlogManager.dll")); plugin->start(); qDebug() << "BlogManager start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to start BlogManager" << e.what(); } // 停止插件 ctkPluginFrameworkLauncher::stop(); return app.exec(); } ================================================ FILE: EventAdmin/SendEvent/CTK.pri ================================================ # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogEventHandler/BlogEventHandler.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = BlogEventHandler DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ blog_event_handler.h \ blog_event_handler_activator.h SOURCES += \ blog_event_handler_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogEventHandler/MANIFEST.MF ================================================ Plugin-SymbolicName: BlogEventHandler Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for handle event Plugin-Name: BlogEventHandler Plugin-Vendor: myh Plugin-Version: 1.0.0 ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogEventHandler/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogEventHandler/blog_event_handler.h ================================================ #ifndef BLOG_EVENT_HANDLER_H #define BLOG_EVENT_HANDLER_H #include #include // 事件处理程序(或订阅者) class BlogEventHandler : public QObject, public ctkEventHandler { Q_OBJECT Q_INTERFACES(ctkEventHandler) public: // 处理事件 void handleEvent(const ctkEvent& event) Q_DECL_OVERRIDE { QString title = event.getProperty("title").toString(); QString content = event.getProperty("content").toString(); QString author = event.getProperty("author").toString(); qDebug() << "EventHandler received the message, topic:" << event.getTopic() << "properties:" << "title:" << title << "content:" << content << "author:" << author; } }; #endif // BLOG_EVENT_HANDLER_H ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogEventHandler/blog_event_handler_activator.cpp ================================================ #include "blog_event_handler.h" #include "blog_event_handler_activator.h" #include #include void BlogEventHandlerActivator::start(ctkPluginContext* context) { m_pEventHandler = new BlogEventHandler(); ctkDictionary props; props[ctkEventConstants::EVENT_TOPIC] = "org/commontk/bloggenerator/published"; props[ctkEventConstants::EVENT_FILTER] = "(author=Waleon)"; context->registerService(m_pEventHandler, props); } void BlogEventHandlerActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pEventHandler; } ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogEventHandler/blog_event_handler_activator.h ================================================ #ifndef BLOG_EVENT_HANDLER_ACTIVATOR_H #define BLOG_EVENT_HANDLER_ACTIVATOR_H #include class BlogEventHandler; class BlogEventHandlerActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "BLOG_EVENT_HANDLER") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: BlogEventHandler *m_pEventHandler; }; #endif // BLOG_EVENT_HANDLER_ACTIVATOR_H ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogManager/BlogManager.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = BlogManager DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ blog_manager.h \ blog_manager_activator.h SOURCES += \ blog_manager.cpp \ blog_manager_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogManager/MANIFEST.MF ================================================ Plugin-SymbolicName: BlogManager Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for publish blog Plugin-Name: BlogManager Plugin-Vendor: myh Plugin-Version: 1.0.0 ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogManager/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogManager/blog_manager.cpp ================================================ #include "blog_manager.h" #include #include BlogManager::BlogManager(ctkPluginContext* context) : m_pContext(context) { } // 发布事件 void BlogManager::publishBlog(const Blog& blog) { ctkServiceReference ref = m_pContext->getServiceReference(); if (ref) { ctkEventAdmin* eventAdmin = m_pContext->getService(ref); ctkDictionary props; props["title"] = blog.title; props["content"] = blog.content; props["author"] = blog.author; ctkEvent event("org/commontk/bloggenerator/published", props); qDebug() << "Publisher sends a message, properties:" << props; eventAdmin->sendEvent(event); } } ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogManager/blog_manager.h ================================================ #ifndef BLOG_MANAGER_H #define BLOG_MANAGER_H #include typedef struct Blog_Info { QString title; QString author; QString content; } Blog; // 事件发布者 class BlogManager { public: BlogManager(ctkPluginContext* context); // 发布事件 void publishBlog(const Blog& blog); private: ctkPluginContext* m_pContext; }; #endif // BLOG_MANAGER_H ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogManager/blog_manager_activator.cpp ================================================ #include "blog_manager.h" #include "blog_manager_activator.h" #include void BlogManagerActivator::start(ctkPluginContext* context) { m_pBlogManager = new BlogManager(context); Blog blog; blog.title = "CTK Event Admin"; blog.content = "This is a simple blog"; blog.author = "Waleon"; m_pBlogManager->publishBlog(blog); } void BlogManagerActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pBlogManager; } ================================================ FILE: EventAdmin/SendEvent/Plugins/BlogManager/blog_manager_activator.h ================================================ #ifndef BLOG_MANAGER_ACTIVATOR_H #define BLOG_MANAGER_ACTIVATOR_H #include class BlogManager; class BlogManagerActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "BLOG_MANAGER") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: BlogManager *m_pBlogManager; }; #endif // BLOG_MANAGER_ACTIVATOR_H ================================================ FILE: EventAdmin/SendEvent/Plugins/Plugins.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ BlogManager \ BlogEventHandler CONFIG += ordered ================================================ FILE: EventAdmin/SendEvent/SendEvent.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ App \ Plugins CONFIG += ordered ================================================ FILE: EventAdmin/SendEvent/SendEvent.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\EventAdmin\build-SendEvent-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/build-SendEvent-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\EventAdmin\build-SendEvent-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/build-SendEvent-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\EventAdmin\build-SendEvent-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/build-SendEvent-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/SendEvent/App/App.pro C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/SendEvent/App/App.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/build-SendEvent-Desktop_Qt_5_15_1_MSVC2019_64bit-Release/App/../bin 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: EventAdmin/SignalSlot/App/App.pro ================================================ QT += core gui widgets TEMPLATE = app CONFIG += console TARGET = App DESTDIR = $$OUT_PWD/../bin include($$PWD/../CTK.pri) SOURCES += \ main.cpp ================================================ FILE: EventAdmin/SignalSlot/App/main.cpp ================================================ #include #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); // 获取插件所在位置 // 在插件的搜索路径列表中添加一条路径 ctkPluginFrameworkLauncher::addSearchPath("../../../../CTKInstall/lib/ctk-0.1/plugins"); // 设置并启动 CTK 插件框架 ctkPluginFrameworkLauncher::start("org.commontk.eventadmin"); // 获取插件上下文 ctkPluginContext* context = ctkPluginFrameworkLauncher::getPluginContext(); QString path = QCoreApplication::applicationDirPath() + "/plugins"; // 启动插件 BlogEventHandlerUsingSlots try { QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(path + "/BlogEventHandlerUsingSlots.dll")); plugin->start(); qDebug() << "BlogEventHandlerUsingSlots start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to start BlogEventHandlerUsingSlots" << e.what(); } // 启动插件 BlogManagerUsingSignals try { QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(path + "/BlogManagerUsingSignals.dll")); plugin->start(); qDebug() << "BlogManagerUsingSignals start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to start BlogManagerUsingSignals" << e.what(); } // 停止插件 ctkPluginFrameworkLauncher::stop(); return app.exec(); } ================================================ FILE: EventAdmin/SignalSlot/CTK.pri ================================================ # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogEventHandlerUsingSlots/BlogEventHandlerUsingSlots.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = BlogEventHandlerUsingSlots DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ blog_event_handler_using_slots.h \ blog_event_handler_using_slots_activator.h SOURCES += \ blog_event_handler_using_slots_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogEventHandlerUsingSlots/MANIFEST.MF ================================================ Plugin-SymbolicName: com.Waleon.BlogEventHandlerUsingSlots Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/Waleon Plugin-Description: A plugin for handle event Plugin-Name: BlogEventHandlerUsingSlots Plugin-Vendor: Waleon Plugin-Version: 1.0.0 ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogEventHandlerUsingSlots/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogEventHandlerUsingSlots/blog_event_handler_using_slots.h ================================================ #ifndef BLOG_EVENT_HANDLER_USING_SLOTS_H #define BLOG_EVENT_HANDLER_USING_SLOTS_H #include #include #include // 事件处理程序(订阅者) class BlogEventHandlerUsingSlots : public QObject { Q_OBJECT public slots: void onBlogPublished(const ctkEvent& event) { QString title = event.getProperty("title").toString(); QString content = event.getProperty("content").toString(); QString author = event.getProperty("author").toString(); qDebug() << "EventHandler received the message, topic:" << event.getTopic() << "properties:" << "title:" << title << "content:" << content << "author:" << author; } }; #endif // BLOG_EVENT_HANDLER_USING_SLOTS_H ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogEventHandlerUsingSlots/blog_event_handler_using_slots_activator.cpp ================================================ #include "blog_event_handler_using_slots.h" #include "blog_event_handler_using_slots_activator.h" #include #include void BlogEventHandlerUsingSlotsActivator::start(ctkPluginContext* context) { m_pEventHandler = new BlogEventHandlerUsingSlots(); ctkDictionary props; props[ctkEventConstants::EVENT_TOPIC] = "org/commontk/bloggenerator/published"; ctkServiceReference ref = context->getServiceReference(); if (ref) { ctkEventAdmin* eventAdmin = context->getService(ref); eventAdmin->subscribeSlot(m_pEventHandler, SLOT(onBlogPublished(ctkEvent)), props, Qt::DirectConnection); } } void BlogEventHandlerUsingSlotsActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pEventHandler; } ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogEventHandlerUsingSlots/blog_event_handler_using_slots_activator.h ================================================ #ifndef BLOG_EVENT_HANDLER_USING_SLOTS_ACTIVATOR_H #define BLOG_EVENT_HANDLER_USING_SLOTS_ACTIVATOR_H #include class BlogEventHandlerUsingSlots; class BlogEventHandlerUsingSlotsActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "BLOG_EVENT_HANDLER_USING_SLOTS") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: BlogEventHandlerUsingSlots *m_pEventHandler; }; #endif // BLOG_EVENT_HANDLER_USING_SLOTS_ACTIVATOR_H ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogManagerUsingSignals/BlogManagerUsingSignals.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = BlogManagerUsingSignals DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ blog_manager_using_signals.h \ blog_manager_using_signals_activator.h SOURCES += \ blog_manager_using_signals.cpp \ blog_manager_using_signals_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogManagerUsingSignals/MANIFEST.MF ================================================ Plugin-SymbolicName: com.Waleon.BlogManagerUsingSignals Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/Waleon Plugin-Description: A plugin for publish blog Plugin-Name: BlogManagerUsingSignals Plugin-Vendor: Waleon Plugin-Version: 1.0.0 ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogManagerUsingSignals/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogManagerUsingSignals/blog_manager_using_signals.cpp ================================================ #include "blog_manager_using_signals.h" BlogManagerUsingSignals::BlogManagerUsingSignals(ctkPluginContext *context) { ctkServiceReference ref = context->getServiceReference(); if (ref) { ctkEventAdmin* eventAdmin = context->getService(ref); // 使用 Qt::DirectConnection 等同于 ctkEventAdmin::sendEvent() eventAdmin->publishSignal(this, SIGNAL(blogPublished(ctkDictionary)), "org/commontk/bloggenerator/published", Qt::DirectConnection); } } // 发布事件 void BlogManagerUsingSignals::publishBlog(const Blog& blog) { ctkDictionary props; props["title"] = blog.title; props["content"] = blog.content; props["author"] = blog.author; qDebug() << "Publisher sends a message, properties:" << props; emit blogPublished(props); } ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogManagerUsingSignals/blog_manager_using_signals.h ================================================ #ifndef BLOG_MANAGER_USING_SIGNALS_SIGNALS_H #define BLOG_MANAGER_USING_SIGNALS_SIGNALS_H #include #include #include typedef struct Blog_Info { QString title; QString author; QString content; } Blog; // 事件发布者 class BlogManagerUsingSignals : public QObject { Q_OBJECT public: BlogManagerUsingSignals(ctkPluginContext* context); // 发布事件 void publishBlog(const Blog& blog); signals: void blogPublished(const ctkDictionary&); }; #endif // BLOG_MANAGER_USING_SIGNALS_SIGNALS_H ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogManagerUsingSignals/blog_manager_using_signals_activator.cpp ================================================ #include "blog_manager_using_signals.h" #include "blog_manager_using_signals_activator.h" void BlogManagerUsingSignalsActivator::start(ctkPluginContext* context) { m_pBlogManager = new BlogManagerUsingSignals(context); Blog blog; blog.title = "CTK Event Admin"; blog.content = "This is a simple blog"; blog.author = "Waleon"; m_pBlogManager->publishBlog(blog); } void BlogManagerUsingSignalsActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pBlogManager; } ================================================ FILE: EventAdmin/SignalSlot/Plugins/BlogManagerUsingSignals/blog_manager_using_signals_activator.h ================================================ #ifndef BLOG_MANAGER_USING_SIGNALS_ACTIVATOR_H #define BLOG_MANAGER_USING_SIGNALS_ACTIVATOR_H #include class BlogManagerUsingSignals; class BlogManagerUsingSignalsActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "BLOG_MANAGER_USING_SINGALS") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: BlogManagerUsingSignals *m_pBlogManager; }; #endif // BLOG_MANAGER_USING_SIGNALS_ACTIVATOR_H ================================================ FILE: EventAdmin/SignalSlot/Plugins/Plugins.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ BlogManagerUsingSignals \ BlogEventHandlerUsingSlots CONFIG += ordered ================================================ FILE: EventAdmin/SignalSlot/SignalSlot.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ App \ Plugins CONFIG += ordered ================================================ FILE: EventAdmin/SignalSlot/SignalSlot.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\EventAdmin\build-SignalSlot-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/build-SignalSlot-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\EventAdmin\build-SignalSlot-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/build-SignalSlot-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\EventAdmin\build-SignalSlot-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/build-SignalSlot-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/SignalSlot/App/App.pro C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/SignalSlot/App/App.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/EventAdmin/build-SignalSlot-Desktop_Qt_5_15_1_MSVC2019_64bit-Release/App/../bin 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: EventListener/EventListener.pro ================================================ QT += core QT -= gui TARGET = EventListener CONFIG += console TEMPLATE = app # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH SOURCES += main.cpp \ event_listener.cpp HEADERS += \ event_listener.h ================================================ FILE: EventListener/EventListener.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-EventListener-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/build-EventListener-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\build-EventListener-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/build-EventListener-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-EventListener-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/build-EventListener-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/EventListener/EventListener.pro C:/d/mmm/qt/ctk/CTK-examples/EventListener/EventListener.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/build-EventListener-Desktop_Qt_5_15_1_MSVC2019_64bit-Release 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: EventListener/event_listener.cpp ================================================ #include "event_listener.h" EventListener::EventListener(QObject *parent) : QObject(parent) { } EventListener::~EventListener() { } // 监听框架事件 void EventListener::onFrameworkEvent(const ctkPluginFrameworkEvent& event) { if (!event.isNull()) { QSharedPointer plugin = event.getPlugin(); qDebug() << "FrameworkEvent: [" << plugin->getSymbolicName() << "]" << event.getType() << event.getErrorString(); } else { qDebug() << "The framework event is null"; } } // 监听插件事件 void EventListener::onPluginEvent(const ctkPluginEvent& event) { if (!event.isNull()) { QSharedPointer plugin = event.getPlugin(); qDebug() << "PluginEvent: [" << plugin->getSymbolicName() << "]" << event.getType(); } else { qDebug() << "The plugin event is null"; } } // 监听服务事件 void EventListener::onServiceEvent(const ctkServiceEvent &event) { if (!event.isNull()) { ctkServiceReference ref = event.getServiceReference(); QSharedPointer plugin = ref.getPlugin(); qDebug() << "ServiceEvent: [" << event.getType() << "]" << plugin->getSymbolicName() << ref.getUsingPlugins(); } else { qDebug() << "The service event is null"; } } ================================================ FILE: EventListener/event_listener.h ================================================ #ifndef EVENT_LISTENER_H #define EVENT_LISTENER_H #include #include #include #include class EventListener : public QObject { Q_OBJECT public: explicit EventListener(QObject *parent = Q_NULLPTR); ~EventListener(); public slots: // 监听框架事件 void onFrameworkEvent(const ctkPluginFrameworkEvent& event); // 监听插件事件 void onPluginEvent(const ctkPluginEvent& event); // 监听服务事件 void onServiceEvent(const ctkServiceEvent& event); }; #endif // EVENT_LISTENER_H ================================================ FILE: EventListener/main.cpp ================================================ #include #include #include #include #include #include #include #include "event_listener.h" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); ctkPluginFrameworkFactory frameWorkFactory; QSharedPointer framework = frameWorkFactory.getFramework(); try { // 初始化并启动插件框架 framework->init(); framework->start(); qDebug() << "CTK Plugin Framework start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to initialize the plugin framework: " << e.what(); return -1; } // 获取插件上下文 ctkPluginContext* context = framework->getPluginContext(); // 事件监听 EventListener listener; context->connectFrameworkListener(&listener, SLOT(onFrameworkEvent(ctkPluginFrameworkEvent))); context->connectPluginListener(&listener, SLOT(onPluginEvent(ctkPluginEvent))); // 过滤 ctkEventAdmin 服务 // QString filter = QString("(%1=%2)").arg(ctkPluginConstants::OBJECTCLASS).arg("org.commontk.eventadmin"); context->connectServiceListener(&listener, "onServiceEvent"); //, filter); // 获取插件所在位置 QString path = QCoreApplication::applicationDirPath() + "/plugins"; // 遍历路径下的所有插件 QDirIterator itPlugin(path, QStringList() << "*.dll" << "*.so", QDir::Files); while (itPlugin.hasNext()) { QString strPlugin = itPlugin.next(); try { // 安装插件 QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(strPlugin)); // 启动插件 plugin->start(ctkPlugin::START_TRANSIENT); } catch (const ctkPluginException &e) { return -1; } } framework->stop(); return app.exec(); } ================================================ FILE: GetMetaData/GetMetaData.pro ================================================ QT += core QT -= gui DESTDIR = $$PWD/bin TARGET = GetMetaData CONFIG += c++11 console CONFIG -= app_bundle TEMPLATE = app # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH SOURCES += main.cpp ================================================ FILE: GetMetaData/GetMetaData.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-GetMetaData-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/build-GetMetaData-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\build-GetMetaData-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/build-GetMetaData-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-GetMetaData-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/build-GetMetaData-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/GetMetaData/GetMetaData.pro C:/d/mmm/qt/ctk/CTK-examples/GetMetaData/GetMetaData.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/GetMetaData/bin 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: GetMetaData/main.cpp ================================================ #include #include #include #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); ctkPluginFrameworkFactory frameWorkFactory; QSharedPointer framework = frameWorkFactory.getFramework(); try { // 初始化并启动插件框架 framework->init(); framework->start(); qDebug() << "CTK Plugin Framework start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to initialize the plugin framework: " << e.what(); return -1; } // 获取插件上下文 ctkPluginContext* context = framework->getPluginContext(); // 获取插件所在位置 QString path = QCoreApplication::applicationDirPath() + "/plugins"; // 遍历路径下的所有插件 QDirIterator itPlugin(path, QStringList() << "*.dll" << "*.so", QDir::Files); while (itPlugin.hasNext()) { QString strPlugin = itPlugin.next(); try { // 安装插件 QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(strPlugin)); qDebug() << "Plugin install ..."; // 获取清单头和值 QHash headers = plugin->getHeaders(); qDebug() << "Headers:" << headers << "\r\n"; // 获取符号名 QString symb = plugin->getSymbolicName(); qDebug() << "Symbolic Name:" << symb << "\r\n"; // 获取版本号 ctkVersion version = plugin->getVersion(); qDebug() << "Version:" << version.toString() << "Major:" << version.getMajor() << "Minor:" << version.getMinor() << "Micro:" << version.getMicro() << "Qualifier:" << version.getQualifier(); // 启动插件 //plugin->start(ctkPlugin::START_TRANSIENT); } catch (const ctkPluginException &e) { qDebug() << "Failed to install plugin" << e.what(); return -1; } } return app.exec(); } ================================================ FILE: PluginAndService/MultipleInterfaces/App/App.pro ================================================ QT += core gui widgets TEMPLATE = app CONFIG += console TARGET = App DESTDIR = $$OUT_PWD/../bin include($$PWD/../CTK.pri) SOURCES += \ main.cpp ================================================ FILE: PluginAndService/MultipleInterfaces/App/main.cpp ================================================ #include #include #include #include #include #include #include #include "../Plugin/greet_service.h"" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); ctkPluginFrameworkFactory frameWorkFactory; QSharedPointer framework = frameWorkFactory.getFramework(); try { // 初始化并启动插件框架 framework->init(); framework->start(); qDebug() << "CTK Plugin Framework start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to initialize the plugin framework: " << e.what(); return -1; } // 获取插件上下文 ctkPluginContext* context = framework->getPluginContext(); // 获取插件所在位置 QString path = QCoreApplication::applicationDirPath() + "/plugins"; // 遍历路径下的所有插件 QDirIterator itPlugin(path, QStringList() << "*.dll" << "*.so", QDir::Files); while (itPlugin.hasNext()) { QString strPlugin = itPlugin.next(); try { // 安装插件 QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(strPlugin)); // 启动插件 plugin->start(ctkPlugin::START_TRANSIENT); qDebug() << "Plugin start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to install plugin" << e.what(); return -1; } } // 获取服务引用 ctkServiceReference ref = context->getServiceReference(); if (ref) { HelloService* service = qobject_cast(context->getService(ref)); if (service != Q_NULLPTR) service->sayHello(); } ref = context->getServiceReference(); if (ref) { ByeService* service = qobject_cast(context->getService(ref)); if (service != Q_NULLPTR) service->sayBye(); } return app.exec(); } ================================================ FILE: PluginAndService/MultipleInterfaces/CTK.pri ================================================ # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH ================================================ FILE: PluginAndService/MultipleInterfaces/MultipleInterfaces.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ App \ Plugin CONFIG += ordered ================================================ FILE: PluginAndService/MultipleInterfaces/MultipleInterfaces.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\PluginAndService\build-MultipleInterfaces-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/build-MultipleInterfaces-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\PluginAndService\build-MultipleInterfaces-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/build-MultipleInterfaces-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\PluginAndService\build-MultipleInterfaces-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/build-MultipleInterfaces-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/MultipleInterfaces/App/App.pro C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/MultipleInterfaces/App/App.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/build-MultipleInterfaces-Desktop_Qt_5_15_1_MSVC2019_64bit-Release/App/../bin 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: PluginAndService/MultipleInterfaces/Plugin/MANIFEST.MF ================================================ Plugin-SymbolicName: Greet Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for greet Plugin-Name: Greet Plugin-Vendor: myh Plugin-Version: 1.0.0 ================================================ FILE: PluginAndService/MultipleInterfaces/Plugin/Plugin.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = Greet DESTDIR = $$OUT_PWD/../bin/plugins include($$PWD/../CTK.pri) HEADERS += \ greet_service.h \ greet_impl.h \ greet_activator.h SOURCES += \ greet_impl.cpp \ greet_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: PluginAndService/MultipleInterfaces/Plugin/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: PluginAndService/MultipleInterfaces/Plugin/greet_activator.cpp ================================================ #include "greet_impl.h" #include "greet_activator.h" void GreetActivator::start(ctkPluginContext* context) { m_pImpl = new GreetImpl(); // 注册服务 context->registerService(m_pImpl); context->registerService(m_pImpl); } void GreetActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pImpl; } ================================================ FILE: PluginAndService/MultipleInterfaces/Plugin/greet_activator.h ================================================ #ifndef GREET_ACTIVATOR_H #define GREET_ACTIVATOR_H #include class GreetImpl; class GreetActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "GREET") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: GreetImpl *m_pImpl; }; #endif // GREET_ACTIVATOR_H ================================================ FILE: PluginAndService/MultipleInterfaces/Plugin/greet_impl.cpp ================================================ #include "greet_impl.h" #include GreetImpl::GreetImpl() { } void GreetImpl::sayHello() { qDebug() << "Hello,CTK!"; } void GreetImpl::sayBye() { qDebug() << "Bye,CTK!"; } ================================================ FILE: PluginAndService/MultipleInterfaces/Plugin/greet_impl.h ================================================ #ifndef GREET_IMPL_H #define GREET_IMPL_H #include "greet_service.h" #include class GreetImpl : public QObject, public HelloService, public ByeService { Q_OBJECT Q_INTERFACES(HelloService) Q_INTERFACES(ByeService) public: GreetImpl(); void sayHello() Q_DECL_OVERRIDE; void sayBye() Q_DECL_OVERRIDE; }; #endif // GREET_IMPL_H ================================================ FILE: PluginAndService/MultipleInterfaces/Plugin/greet_service.h ================================================ #ifndef GREET_SERVICE_H #define GREET_SERVICE_H #include class HelloService { public: virtual ~HelloService() {} virtual void sayHello() = 0; }; #define HelloService_iid "org.commontk.service.demos.HelloService" Q_DECLARE_INTERFACE(HelloService, HelloService_iid) class ByeService { public: virtual ~ByeService() {} virtual void sayBye() = 0; }; #define ByeService_iid "org.commontk.service.demos.ByeService" Q_DECLARE_INTERFACE(ByeService, ByeService_iid) #endif // GREET_SERVICE_H ================================================ FILE: PluginAndService/OneInterface/App/App.pro ================================================ QT += core gui widgets TEMPLATE = app CONFIG += console TARGET = App DESTDIR = $$OUT_PWD/../bin include($$PWD/../CTK.pri) SOURCES += \ main.cpp ================================================ FILE: PluginAndService/OneInterface/App/main.cpp ================================================ #include #include #include #include #include #include #include #include "../Service/welcome_service.h" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); ctkPluginFrameworkFactory frameWorkFactory; QSharedPointer framework = frameWorkFactory.getFramework(); try { // 初始化并启动插件框架 framework->init(); framework->start(); qDebug() << "CTK Plugin Framework start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to initialize the plugin framework: " << e.what(); return -1; } qDebug() << "********************"; // 获取插件上下文 ctkPluginContext* context = framework->getPluginContext(); // 获取插件所在位置 QString path = QCoreApplication::applicationDirPath() + "/plugins"; // 遍历路径下的所有插件 QDirIterator itPlugin(path, QStringList() << "*.dll" << "*.so", QDir::Files); while (itPlugin.hasNext()) { QString strPlugin = itPlugin.next(); try { // 安装插件 QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(strPlugin)); // 启动插件 plugin->start(ctkPlugin::START_TRANSIENT); qDebug() << "Plugin start:" << QFileInfo(strPlugin).fileName(); } catch (const ctkPluginException &e) { qDebug() << "Failed to start plugin" << e.what(); return -1; } } qDebug() << "********************"; // 1. 获取所有服务 QList refs = context->getServiceReferences(); foreach (ctkServiceReference ref, refs) { if (ref) { qDebug() << "Name:" << ref.getProperty("name").toString() << "Service ranking:" << ref.getProperty(ctkPluginConstants::SERVICE_RANKING).toLongLong() << "Service id:" << ref.getProperty(ctkPluginConstants::SERVICE_ID).toLongLong(); WelcomeService* service = qobject_cast(context->getService(ref)); if (service != Q_NULLPTR) service->welcome(); } } qDebug() << "********************"; // 2. 使用过滤表达式,获取感兴趣的服务 refs = context->getServiceReferences("(&(name=CTK))"); foreach (ctkServiceReference ref, refs) { if (ref) { WelcomeService* service = qobject_cast(context->getService(ref)); if (service != Q_NULLPTR) service->welcome(); } } qDebug() << "********************"; // 3. 获取某一个服务(由 Service Ranking 和 Service ID 决定) ctkServiceReference ref = context->getServiceReference(); if (ref) { WelcomeService* service = qobject_cast(context->getService(ref)); if (service != Q_NULLPTR) service->welcome(); } return app.exec(); } ================================================ FILE: PluginAndService/OneInterface/CTK.pri ================================================ # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH ================================================ FILE: PluginAndService/OneInterface/OneInterface.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ App \ Plugins CONFIG += ordered ================================================ FILE: PluginAndService/OneInterface/OneInterface.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\PluginAndService\build-OneInterface-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/build-OneInterface-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\PluginAndService\build-OneInterface-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/build-OneInterface-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\PluginAndService\build-OneInterface-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/build-OneInterface-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/OneInterface/App/App.pro C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/OneInterface/App/App.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/PluginAndService/build-OneInterface-Desktop_Qt_5_15_1_MSVC2019_64bit-Release/App/../bin 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: PluginAndService/OneInterface/Plugins/Plugins.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ WelcomeCTK \ WelcomeQt CONFIG += ordered ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeCTK/MANIFEST.MF ================================================ Plugin-SymbolicName: Welcome.CTK Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for welcome CTK Plugin-Name: WelcomeCTK Plugin-Vendor: myh Plugin-Version: 1.0.0 ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeCTK/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeCTK/WelcomeCTK.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = WelcomeCTK DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ welcome_ctk_impl.h \ welcome_ctk_activator.h SOURCES += \ welcome_ctk_impl.cpp \ welcome_ctk_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeCTK/welcome_ctk_activator.cpp ================================================ #include "welcome_ctk_impl.h" #include "welcome_ctk_activator.h" #include void WelcomeCTKActivator::start(ctkPluginContext* context) { ctkDictionary properties; properties.insert(ctkPluginConstants::SERVICE_RANKING, 2); properties.insert("name", "CTK"); m_pImpl = new WelcomeCTKImpl(); context->registerService(m_pImpl, properties); } void WelcomeCTKActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pImpl; } ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeCTK/welcome_ctk_activator.h ================================================ #ifndef WELCOME_CTK_ACTIVATOR_H #define WELCOME_CTK_ACTIVATOR_H #include class WelcomeCTKImpl; class WelcomeCTKActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "WELCOME_CTK") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: WelcomeCTKImpl *m_pImpl; }; #endif // WELCOME_CTK_ACTIVATOR_H ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeCTK/welcome_ctk_impl.cpp ================================================ #include "welcome_ctk_impl.h" #include WelcomeCTKImpl::WelcomeCTKImpl() { } void WelcomeCTKImpl::welcome() { qDebug() << "Welcome CTK!"; } ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeCTK/welcome_ctk_impl.h ================================================ #ifndef WELCOME_CTK_IMPL_H #define WELCOME_CTK_IMPL_H #include "../../Service/welcome_service.h" #include class ctkPluginContext; class WelcomeCTKImpl : public QObject, public WelcomeService { Q_OBJECT Q_INTERFACES(WelcomeService) public: WelcomeCTKImpl(); void welcome() Q_DECL_OVERRIDE; }; #endif // WELCOME_CTK_IMPL_H ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeQt/MANIFEST.MF ================================================ Plugin-SymbolicName: Welcome.Qt Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for welcome Qt Plugin-Name: WelcomeQt Plugin-Vendor: myh Plugin-Version: 1.0.0 ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeQt/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeQt/WelcomeQt.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = WelcomeQt DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ welcome_qt_impl.h \ welcome_qt_activator.h SOURCES += \ welcome_qt_impl.cpp \ welcome_qt_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeQt/welcome_qt_activator.cpp ================================================ #include "welcome_qt_impl.h" #include "welcome_qt_activator.h" #include void WelcomeQtActivator::start(ctkPluginContext* context) { ctkDictionary properties; properties.insert(ctkPluginConstants::SERVICE_RANKING, 1); properties.insert("name", "Qt"); m_pImpl = new WelcomeQtImpl(); context->registerService(m_pImpl, properties); } void WelcomeQtActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pImpl; } ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeQt/welcome_qt_activator.h ================================================ #ifndef WELCOME_CTK_ACTIVATOR_H #define WELCOME_CTK_ACTIVATOR_H #include class WelcomeQtImpl; class WelcomeQtActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "WELCOME_QT") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: WelcomeQtImpl *m_pImpl; }; #endif // WELCOME_CTK_ACTIVATOR_H ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeQt/welcome_qt_impl.cpp ================================================ #include "welcome_qt_impl.h" #include WelcomeQtImpl::WelcomeQtImpl() { } void WelcomeQtImpl::welcome() { qDebug() << "Welcome Qt!"; } ================================================ FILE: PluginAndService/OneInterface/Plugins/WelcomeQt/welcome_qt_impl.h ================================================ #ifndef WELCOME_QT_IMPL_H #define WELCOME_QT_IMPL_H #include "../../Service/welcome_service.h" #include class ctkPluginContext; class WelcomeQtImpl : public QObject, public WelcomeService { Q_OBJECT Q_INTERFACES(WelcomeService) public: WelcomeQtImpl(); void welcome() Q_DECL_OVERRIDE; }; #endif // WELCOME_QT_IMPL_H ================================================ FILE: PluginAndService/OneInterface/Service/welcome_service.h ================================================ #ifndef WELCOME_SERVICE_H #define WELCOME_SERVICE_H #include class WelcomeService { public: virtual ~WelcomeService() {} virtual void welcome() = 0; }; #define WelcomeService_iid "org.commontk.service.demos.WelcomeService" Q_DECLARE_INTERFACE(WelcomeService, WelcomeService_iid) #endif // WELCOME_SERVICE_H ================================================ FILE: README.md ================================================ [CTK完整教程(OSGI for C++ 实现 C++ Qt 模块化)](https://www.ljjyy.com/archives/2021/03/100645.html) CTK框架实际应用比较可靠,但网上资料很少。本教程围绕 CTK Plugin Framework,探索 C++ 中的模块化技术,并能够基于 CTK 快速搭建 C++ 组件化框架,避免后来的人走弯路。本教程的源码下载地址:[项目源代码](https://github.com/myhhub/CTK-project)。 # CTK介绍 [CTK](http://www.commontk.org/) 为支持生物医学图像计算的公共开发包,其全称为 Common Toolkit。CTK插件框架的设计有很大的灵感来自OSGi并且使得应用程序由许多不同的组件组合成一个可扩展模型。这个模型允许通过那些组件间共享对象的服务通信。 当前,CTK 工作的主要范围包括: - [DICOM](http://www.commontk.org/index.php/Documentation/Dicom_Overview):提供了从 PACS 和本地数据库中查询和检索的高级类。包含 Qt 部件,可以轻松地设置服务器连接,并发送查询和查看结果。 - [DICOM Application Hosting](http://www.commontk.org/index.php/Documentation/DicomApplicationHosting):目标是创建 DICOM Part 19 Application Hosting specifications 的 C++ 参考实现。它提供了用于创建主机和托管应用程序的基础设。 - [Widgets](http://www.commontk.org/index.php/Documentation/Widgets):用于生物医学成像应用的 Qt Widgets 集合。 - [Plugin Framework](http://www.commontk.org/index.php/Documentation/Plugin_Framework):用于 C++ 的动态组件系统,以 OSGi 规范为模型。它支持一个开发模型,在这个模型中,应用程序(动态地)由许多不同(可重用的)组件组成,遵循面向服务的方法。 - [Command Line Interfaces](http://www.commontk.org/index.php/Documentation/Command_Line_Interface):一种允许将算法编写为自包含可执行程序的技术,可以在多个终端用户应用程序环境中使用,而无需修改。 ## 使用 CTK Plugin Framework 的好处 由于 CTK Plugin Framework 基于 OSGi,因此它继承了一种非常成熟且完全设计的组件系统,这在 Java 中用于构建高度复杂的应用程序,它将这些好处带给了本地(基于 Qt 的)C++ 应用程序。以下内容摘自 [Benefits of Using OSGi](https://www.osgi.org/developer/benefits-of-using-osgi/),并适应于 CTK Plugin Framework: - 降低复杂性 使用 CTK Plugin Framework 开发意味着开发插件,它们隐藏了内部实现,并通过定义良好的服务来和其它插件通信。隐藏内部机制意味着以后可以自由地更改实现,这不仅有助于 Bug 数量的减少,还使得插件的开发变得更加简单,因为只需要实现已经定义好的一定数量的功能接口即可。 - 复用 标准化的组件模型,使得在应用程序中使用第三方组件变得非常容易。 - 现实情况 CTK Plugin Framework 是一个动态框架,它可以动态地更新插件和服务。在现实世界中,有很多场景都和动态服务模型相匹配。因此,应用程序可以在其所属的领域中重用 Service Registry 的强大基元(注册、获取、用富有表现力的过滤语言列表、等待服务的出现和消失)。这不仅节省了编写代码,还提供了全局可见性、调试工具以及比为专用解决方案实现的更多的功能。在这样的动态环境下编写代码听起来似乎是个噩梦,但幸运的是,有支持类和框架可以消除大部分(如果不是全部的话)痛苦。 - 开发简单 CTK Plugin Framework 不仅仅是组件的标准,它还指定了如何安装和管理组件。这个 API 可以被插件用来提供一个管理代理,这个管理代理可以非常简单,如命令 shell、图形桌面应用程序、Amazon EC2 的云计算接口、或 IBM Tivoli 管理系统。标准化的管理 API 使得在现有和未来的系统中集成 CTK Plugin Framework 变得非常容易。 - 动态更新 OSGi 组件模型是一个动态模型,插件可以在不关闭整个系统的情况下被安装、启动、停止、更新和卸载。 - 自适应 OSGi 组件模型是从头设计的,以允许组件的混合和匹配。这就要求必须指定组件的依赖关系,并且需要组件在其可选依赖性并不总是可用的环境中生存。Service Registry 是一个动态注册表,其中插件可以注册、获取和监听服务。这种动态服务模型允许插件找出系统中可用的功能,并调整它们所能提供的功能。这使得代码更加灵活,并且能够更好地适应变化。 - 透明性 插件和服务是 CTK 插件环境中的一等公民。管理 API 提供了对插件的内部状态的访问,以及插件之间的连接方式。可以停止部分应用程序来调试某个问题,或者可以引入诊断插件。 - 版本控制 在 CTK Plugin Framework 中,所有的插件都经过严格的版本控制,只有能够协作的插件才会被连接在一起。 - 简单 CTK 插件相关的 API 非常简单,核心 API 不到 25 个类。这个核心 API 足以编写插件、安装、启动、停止、更新和卸载它们,并且还包含了所有的监听类。 - 懒加载 懒加载是软件中一个很好的点,OSGi 技术有很多的机制来保证只有当类真正需要的时候才开始加载它们。例如,插件可以用饿汉式启动,但是也可以被配置为仅当其它插件使用它们时才启动。服务可以被注册,但只有在使用时才创建。这些懒加载场景,可以节省大量的运行时成本。 - 非独占性 CTK Plugin Framework 不会接管整个应用程序,你可以选择性地将所提供的功能暴露给应用程序的某些部分,或者甚至可以在同一个进程中运行该框架的多个实例。 - 非侵入 在一个 CTK 插件环境中,不同插件均有自己的环境。它们可以使用任何设施,框架对此并无限制。CTK 服务没有特殊的接口需求,每个 QObject 都可以作为一个服务,每个类(也包括非 QObject)都可以作为一个接口。 # CTK编译 使用cmake编译出与系统版本相应的动态库。参见[CTK编译教程(64位环境 Windows + Qt + MinGW或MSVC + CMake)](https://www.ljjyy.com/archives/2021/02/100643.html)。 # [使用 CTK](https://www.ljjyy.com/archives/2021/03/100645.html) - [使用 CTKWidgets](https://www.ljjyy.com/archives/2021/03/100645.html#%E4%BD%BF%E7%94%A8-CTKWidgets) - [使用 CTK Plugin Framework](https://www.ljjyy.com/archives/2021/03/100645.html#%E5%88%9D%E6%AD%A5%E4%BD%BF%E7%94%A8-CTK-Plugin-Framework) - [CTK 插件间通信.注册接口调用](https://www.ljjyy.com/archives/2021/03/100645.html#%E9%80%9A%E4%BF%A1%E6%96%B9%E6%B3%95%E4%B8%80-%E6%B3%A8%E5%86%8C%E6%8E%A5%E5%8F%A3%E8%B0%83%E7%94%A8) - [CTK 插件和服务](https://www.ljjyy.com/archives/2021/03/100645.html#%E6%8E%A5%E5%8F%A3%E3%80%81%E6%8F%92%E4%BB%B6%E3%80%81%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%85%B3%E7%B3%BB) - [CTK 插件间通信.事件监听](https://www.ljjyy.com/archives/2021/03/100645.html#%E9%80%9A%E4%BF%A1%E6%96%B9%E6%B3%95%E4%BA%8C-%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC) - [CTK 事件管理机制](https://www.ljjyy.com/archives/2021/03/100645.html#%E4%BA%8B%E4%BB%B6%E5%8F%91%E9%80%81%E6%96%B9%E5%BC%8F-%E7%B1%BB%E9%80%9A%E4%BF%A1%E3%80%81%E4%BF%A1%E5%8F%B7%E6%A7%BD%E9%80%9A%E4%BF%A1) - [CTK 插件元数据](https://www.ljjyy.com/archives/2021/03/100645.html#%E6%8F%92%E4%BB%B6%E5%85%83%E6%95%B0%E6%8D%AE) - [CTK 插件之间的依赖](https://www.ljjyy.com/archives/2021/03/100645.html#%E6%8F%92%E4%BB%B6%E4%BE%9D%E8%B5%96) - [CTK 服务工厂](https://www.ljjyy.com/archives/2021/03/100645.html#CTK-%E6%9C%8D%E5%8A%A1%E5%B7%A5%E5%8E%82) - [CTK 事件与监听](https://www.ljjyy.com/archives/2021/03/100645.html#CTK-%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC) - [CTK 服务追踪](https://www.ljjyy.com/archives/2021/03/100645.html#CTK-%E6%9C%8D%E5%8A%A1%E8%BF%BD%E8%B8%AA) ================================================ FILE: RequirePlugin/App/App.pro ================================================ QT += core QT -= gui TARGET = RequirePlugin CONFIG += console TEMPLATE = app DESTDIR = $$OUT_PWD/../bin include($$PWD/../CTK.pri) SOURCES += main.cpp ================================================ FILE: RequirePlugin/App/main.cpp ================================================ #include #include #include #include #include #include #include #include "../Plugins/PluginA/plugin_a_service.h" #include "../Plugins/PluginB/plugin_b_service.h" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); ctkPluginFrameworkFactory frameWorkFactory; QSharedPointer framework = frameWorkFactory.getFramework(); try { // 初始化并启动插件框架 framework->init(); framework->start(); qDebug() << "CTK Plugin Framework start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to initialize the plugin framework: " << e.what(); return -1; } // 获取插件上下文 ctkPluginContext* context = framework->getPluginContext(); // 获取插件所在位置 QString path = QCoreApplication::applicationDirPath() + "/plugins"; // 启动插件 A try { QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(path + "/PluginA.dll")); plugin->start(); qDebug() << "PluginA start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to start PluginA" << e.what(); } // 启动插件 B try { QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(path + "/PluginB.dll")); plugin->start(); qDebug() << "PluginB start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to start PluginB" << e.what(); } // 获取服务引用 ctkServiceReference reference = context->getServiceReference(); if (reference) { // 获取指定 ctkServiceReference 引用的服务对象 PluginAService* service = qobject_cast(context->getService(reference)); if (service != Q_NULLPTR) { // 调用服务 service->doSomething(); } } reference = context->getServiceReference(); if (reference) { // 获取指定 ctkServiceReference 引用的服务对象 PluginBService* service = qobject_cast(context->getService(reference)); if (service != Q_NULLPTR) { // 调用服务 service->doSomething(); } } return app.exec(); } ================================================ FILE: RequirePlugin/CTK.pri ================================================ # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH ================================================ FILE: RequirePlugin/Plugins/PluginA/MANIFEST.MF ================================================ Plugin-SymbolicName: Plugin.A Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for test Plugin-Name: PluginA Plugin-Vendor: myh Plugin-Version: 1.0.0 ================================================ FILE: RequirePlugin/Plugins/PluginA/PluginA.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = PluginA DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ plugin_a_service.h \ plugin_a_impl.h \ plugin_a_activator.h SOURCES += \ plugin_a_impl.cpp \ plugin_a_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: RequirePlugin/Plugins/PluginA/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: RequirePlugin/Plugins/PluginA/plugin_a_activator.cpp ================================================ #include "plugin_a_impl.h" #include "plugin_a_activator.h" #include void PluginAActivator::start(ctkPluginContext* context) { m_pPlugin = new PluginAImpl(); context->registerService(m_pPlugin); } void PluginAActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pPlugin; m_pPlugin = Q_NULLPTR; } ================================================ FILE: RequirePlugin/Plugins/PluginA/plugin_a_activator.h ================================================ #ifndef PLUGIN_A_ACTIVATOR_H #define PLUGIN_A_ACTIVATOR_H #include class PluginAImpl; class PluginAActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "PLUGIN_A") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: PluginAImpl *m_pPlugin; }; #endif // PLUGIN_A_ACTIVATOR_H ================================================ FILE: RequirePlugin/Plugins/PluginA/plugin_a_impl.cpp ================================================ #include "plugin_a_impl.h" #include PluginAImpl::PluginAImpl() { } void PluginAImpl::doSomething() { qDebug() << "Do something...A"; } ================================================ FILE: RequirePlugin/Plugins/PluginA/plugin_a_impl.h ================================================ #ifndef PLUGIN_A_IMPL_H #define PLUGIN_A_IMPL_H #include "plugin_a_service.h" #include class PluginAImpl : public QObject, public PluginAService { Q_OBJECT Q_INTERFACES(PluginAService) public: PluginAImpl(); void doSomething() Q_DECL_OVERRIDE; }; #endif // PLUGIN_A_IMPL_H ================================================ FILE: RequirePlugin/Plugins/PluginA/plugin_a_service.h ================================================ #ifndef PLUGIN_A_SERVICE_H #define PLUGIN_A_SERVICE_H #include class PluginAService { public: virtual ~PluginAService() {} virtual void doSomething() = 0; }; #define PluginAService_iid "org.commontk.service.demos.PluginAService" Q_DECLARE_INTERFACE(PluginAService, PluginAService_iid) #endif // PLUGIN_A_SERVICE_H ================================================ FILE: RequirePlugin/Plugins/PluginB/MANIFEST.MF ================================================ Plugin-SymbolicName: Plugin.B Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for test Plugin-Name: PluginB Plugin-Vendor: myh Plugin-Version: 1.0.0 Require-Plugin: Plugin.A; resolution:="mandatory"; plugin-version="[1.0,2.0)" ================================================ FILE: RequirePlugin/Plugins/PluginB/PluginB.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = PluginB DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ plugin_b_service.h \ plugin_b_impl.h \ plugin_b_activator.h SOURCES += \ plugin_b_impl.cpp \ plugin_b_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: RequirePlugin/Plugins/PluginB/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: RequirePlugin/Plugins/PluginB/plugin_b_activator.cpp ================================================ #include "plugin_b_impl.h" #include "plugin_b_activator.h" #include void PluginBActivator::start(ctkPluginContext* context) { m_pPlugin = new PluginBImpl(); context->registerService(m_pPlugin); } void PluginBActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pPlugin; m_pPlugin = Q_NULLPTR; } ================================================ FILE: RequirePlugin/Plugins/PluginB/plugin_b_activator.h ================================================ #ifndef PLUGIN_B_ACTIVATOR_H #define PLUGIN_B_ACTIVATOR_H #include class PluginBImpl; class PluginBActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "PLUGIN_B") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: PluginBImpl *m_pPlugin; }; #endif // PLUGIN_B_ACTIVATOR_H ================================================ FILE: RequirePlugin/Plugins/PluginB/plugin_b_impl.cpp ================================================ #include "plugin_b_impl.h" #include PluginBImpl::PluginBImpl() { } void PluginBImpl::doSomething() { qDebug() << "Do something...B"; } ================================================ FILE: RequirePlugin/Plugins/PluginB/plugin_b_impl.h ================================================ #ifndef PLUGIN_B_IMPL_H #define PLUGIN_B_IMPL_H #include "plugin_b_service.h" #include class PluginBImpl : public QObject, public PluginBService { Q_OBJECT Q_INTERFACES(PluginBService) public: PluginBImpl(); void doSomething() Q_DECL_OVERRIDE; }; #endif // PLUGIN_B_IMPL_H ================================================ FILE: RequirePlugin/Plugins/PluginB/plugin_b_service.h ================================================ #ifndef PLUGIN_B_SERVICE_H #define PLUGIN_B_SERVICE_H #include class PluginBService { public: virtual ~PluginBService() {} virtual void doSomething() = 0; }; #define PluginBService_iid "org.commontk.service.demos.PluginBService" Q_DECLARE_INTERFACE(PluginBService, PluginBService_iid) #endif // PLUGIN_B_SERVICE_H ================================================ FILE: RequirePlugin/Plugins/Plugins.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ PluginA \ PluginB CONFIG += ordered ================================================ FILE: RequirePlugin/RequirePlugin.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ App \ Plugins CONFIG += ordered ================================================ FILE: RequirePlugin/RequirePlugin.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-RequirePlugin-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/build-RequirePlugin-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\build-RequirePlugin-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/build-RequirePlugin-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-RequirePlugin-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/build-RequirePlugin-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/RequirePlugin/App/App.pro C:/d/mmm/qt/ctk/CTK-examples/RequirePlugin/App/App.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/build-RequirePlugin-Desktop_Qt_5_15_1_MSVC2019_64bit-Release/App/../bin 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: SampleCTK/App/App.pro ================================================ QT += core QT -= gui TARGET = App CONFIG += console TEMPLATE = app DESTDIR = $$OUT_PWD/../bin include($$PWD/../CTK.pri) SOURCES += main.cpp ================================================ FILE: SampleCTK/App/main.cpp ================================================ #include #include #include #include #include #include #include #include "../HelloCTK/hello_service.h" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); app.setApplicationName("SampleCTK");//给框架创建名称,Linux下没有会报错 ctkPluginFrameworkFactory frameWorkFactory; QSharedPointer framework = frameWorkFactory.getFramework(); try { // 初始化并启动插件框架 framework->init(); framework->start(); qDebug() << "CTK Plugin Framework start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to initialize the plugin framework: " << e.what(); qDebug() << e.message() << e.getType(); return -1; } // 获取插件上下文 ctkPluginContext* context = framework->getPluginContext(); // 获取插件所在位置 QString path = QCoreApplication::applicationDirPath() + "/plugins"; qDebug() << path; // 遍历路径下的所有插件 QDirIterator itPlugin(path, QStringList() << "*.dll" << "*.so", QDir::Files); while (itPlugin.hasNext()) { QString strPlugin = itPlugin.next(); try { // 安装插件 QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(strPlugin)); // 启动插件 plugin->start(ctkPlugin::START_TRANSIENT); qDebug() << "Plugin start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to install plugin" << e.what(); return -1; } } // 获取服务引用 ctkServiceReference reference = context->getServiceReference(); if (reference) { // 获取指定 ctkServiceReference 引用的服务对象 HelloService* service = qobject_cast(context->getService(reference)); if (service != Q_NULLPTR) { // 调用服务 service->sayHello(); } } return app.exec(); } ================================================ FILE: SampleCTK/CTK.pri ================================================ # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH ================================================ FILE: SampleCTK/HelloCTK/HelloCTK.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = HelloCTK DESTDIR = $$OUT_PWD/../bin/plugins include($$PWD/../CTK.pri) file.path = $$DESTDIR file.files = MANIFEST.MF INSTALLS += file RESOURCES += \ Resource.qrc HEADERS += \ hello_activator.h \ hello_impl.h \ hello_service.h SOURCES += \ hello_activator.cpp \ hello_impl.cpp ================================================ FILE: SampleCTK/HelloCTK/MANIFEST.MF ================================================ Plugin-SymbolicName: HelloCTK Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for say hello Plugin-Name: HelloCTK Plugin-Vendor: myh Plugin-Version: 1.2.4 ================================================ FILE: SampleCTK/HelloCTK/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: SampleCTK/HelloCTK/hello_activator.cpp ================================================ #include "hello_activator.h" #include "hello_impl.h" void HelloActivator::start(ctkPluginContext* context) { s.reset(new HelloImpl(context)); // HelloImpl* helloImpl = new HelloImpl(); // context->registerService(helloImpl); // s.reset(helloImpl); } void HelloActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } ================================================ FILE: SampleCTK/HelloCTK/hello_activator.h ================================================ #ifndef HELLO_ACTIVATOR_H #define HELLO_ACTIVATOR_H #include #include "hello_service.h" class HelloActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "HELLO_CTK") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: QScopedPointer s; }; #endif // HELLO_ACTIVATOR_H ================================================ FILE: SampleCTK/HelloCTK/hello_impl.cpp ================================================ #include "hello_impl.h" #include #include HelloImpl::HelloImpl(ctkPluginContext* context) { context->registerService(this); } void HelloImpl::sayHello() { qDebug() << "Hello,CTK!"; } ================================================ FILE: SampleCTK/HelloCTK/hello_impl.h ================================================ #ifndef HELLO_IMPL_H #define HELLO_IMPL_H #include "hello_service.h" #include class ctkPluginContext; class HelloImpl : public QObject, public HelloService { Q_OBJECT Q_INTERFACES(HelloService) public: HelloImpl(ctkPluginContext* context); void sayHello() Q_DECL_OVERRIDE; }; #endif // HELLO_IMPL_H ================================================ FILE: SampleCTK/HelloCTK/hello_service.h ================================================ #ifndef HELLO_SERVICE_H #define HELLO_SERVICE_H #include class HelloService { public: virtual ~HelloService() {} virtual void sayHello() = 0; }; #define HelloService_iid "org.commontk.service.demos.HelloService" Q_DECLARE_INTERFACE(HelloService, HelloService_iid) #endif // HELLO_SERVICE_H ================================================ FILE: SampleCTK/SampleCTK.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ App \ HelloCTK ================================================ FILE: SampleCTK/SampleCTK.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-SampleCTK-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/build-SampleCTK-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\build-SampleCTK-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/build-SampleCTK-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-SampleCTK-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/build-SampleCTK-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/SampleCTK/App/App.pro C:/d/mmm/qt/ctk/CTK-examples/SampleCTK/App/App.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/build-SampleCTK-Desktop_Qt_5_15_1_MSVC2019_64bit-Release/App/../bin 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: ServiceFactory/App/App.pro ================================================ QT += core QT -= gui TARGET = ServiceFactory CONFIG += console TEMPLATE = app DESTDIR = $$OUT_PWD/../bin include($$PWD/../CTK.pri) SOURCES += main.cpp ================================================ FILE: ServiceFactory/App/main.cpp ================================================ #include #include #include #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); ctkPluginFrameworkFactory frameWorkFactory; QSharedPointer framework = frameWorkFactory.getFramework(); try { // 初始化并启动插件框架 framework->init(); framework->start(); qDebug() << "CTK Plugin Framework start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to initialize the plugin framework: " << e.what(); return -1; } // 获取插件上下文 ctkPluginContext* context = framework->getPluginContext(); // 获取插件所在位置 QString path = QCoreApplication::applicationDirPath() + "/plugins"; // 启动插件 Hello try { QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(path + "/Hello.dll")); plugin->start(); qDebug() << "Hello plugin start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to start Hello" << e.what(); } // 启动插件 A try { QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(path + "/PluginA.dll")); plugin->start(); qDebug() << "PluginA start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to start PluginA" << e.what(); } // 启动插件 B try { QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(path + "/PluginB.dll")); plugin->start(); qDebug() << "PluginB start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to start PluginB" << e.what(); } return app.exec(); } ================================================ FILE: ServiceFactory/CTK.pri ================================================ # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH ================================================ FILE: ServiceFactory/Plugins/Hello/Hello.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = Hello DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ hello_service.h \ hello_impl.h \ hello_activator.h \ service_factory.h RESOURCES += Resource.qrc ================================================ FILE: ServiceFactory/Plugins/Hello/MANIFEST.MF ================================================ Plugin-SymbolicName: Hello Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for say hello Plugin-Name: Hello Plugin-Vendor: myh Plugin-Version: 1.0.0 ================================================ FILE: ServiceFactory/Plugins/Hello/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: ServiceFactory/Plugins/Hello/hello_activator.h ================================================ #ifndef HELLO_ACTIVATOR_H #define HELLO_ACTIVATOR_H #include #include #include "hello_service.h" #include "service_factory.h" class HelloActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "HELLO") public: // 注册服务工厂 void start(ctkPluginContext* context) { ServiceFactory *factory = new ServiceFactory(); context->registerService(factory); } void stop(ctkPluginContext* context) { Q_UNUSED(context) } }; #endif // HELLO_ACTIVATOR_H ================================================ FILE: ServiceFactory/Plugins/Hello/hello_impl.h ================================================ #ifndef HELLO_IMPL_H #define HELLO_IMPL_H #include "hello_service.h" #include #include // HelloWorld class HelloWorldImpl : public QObject, public HelloService { Q_OBJECT Q_INTERFACES(HelloService) public: void sayHello() Q_DECL_OVERRIDE { qDebug() << "Hello,World!"; } }; // HelloCTK class HelloCTKImpl : public QObject, public HelloService { Q_OBJECT Q_INTERFACES(HelloService) public: void sayHello() Q_DECL_OVERRIDE { qDebug() << "Hello,CTK!"; } }; #endif // HELLO_IMPL_H ================================================ FILE: ServiceFactory/Plugins/Hello/hello_service.h ================================================ #ifndef HELLO_SERVICE_H #define HELLO_SERVICE_H #include class HelloService { public: virtual ~HelloService() {} virtual void sayHello() = 0; }; #define HelloService_iid "org.commontk.service.demos.HelloService" Q_DECLARE_INTERFACE(HelloService, HelloService_iid) #endif // HELLO_SERVICE_H ================================================ FILE: ServiceFactory/Plugins/Hello/service_factory.h ================================================ #ifndef SERVICE_FACTORY_H #define SERVICE_FACTORY_H #include #include #include #include "hello_impl.h" class ServiceFactory : public QObject, public ctkServiceFactory { Q_OBJECT Q_INTERFACES(ctkServiceFactory) public: ServiceFactory() : m_counter(0) {} // 创建服务对象 QObject* getService(QSharedPointer plugin, ctkServiceRegistration registration) Q_DECL_OVERRIDE { Q_UNUSED(registration) qDebug() << "Create object of HelloService for: " << plugin->getSymbolicName(); m_counter++; qDebug() << "Number of plugins using service: " << m_counter; QHash headers = plugin->getHeaders(); ctkVersion version = ctkVersion::parseVersion(headers.value(ctkPluginConstants::PLUGIN_VERSION)); QString name = headers.value(ctkPluginConstants::PLUGIN_NAME); QObject* hello = getHello(version); return hello; } // 释放服务对象 void ungetService(QSharedPointer plugin, ctkServiceRegistration registration, QObject* service) Q_DECL_OVERRIDE { Q_UNUSED(plugin) Q_UNUSED(registration) Q_UNUSED(service) qDebug() << "Release object of HelloService for: " << plugin->getSymbolicName(); m_counter--; qDebug() << "Number of plugins using service: " << m_counter; } private: // 根据不同的版本,获取不同的服务 QObject* getHello(ctkVersion version) { if (version.toString().contains("alpha")) { return new HelloWorldImpl(); } else { return new HelloCTKImpl(); } } private: int m_counter; // 计数器 }; #endif // SERVICE_FACTORY_H ================================================ FILE: ServiceFactory/Plugins/PluginA/MANIFEST.MF ================================================ Plugin-SymbolicName: Plugin.A Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for test Plugin-Name: PluginA Plugin-Vendor: myh Plugin-Version: 1.0.0.alpha ================================================ FILE: ServiceFactory/Plugins/PluginA/PluginA.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = PluginA DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ plugin_a_service.h \ plugin_a_impl.h \ plugin_a_activator.h SOURCES += \ plugin_a_activator.cpp \ plugin_a_impl.cpp RESOURCES += Resource.qrc ================================================ FILE: ServiceFactory/Plugins/PluginA/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: ServiceFactory/Plugins/PluginA/plugin_a_activator.cpp ================================================ #include "plugin_a_impl.h" #include "plugin_a_activator.h" #include "../Hello/hello_service.h" #include #include void PluginAActivator::start(ctkPluginContext* context) { m_pPlugin = new PluginAImpl(); context->registerService(m_pPlugin); // 第一次访问服务 ctkServiceReference reference = context->getServiceReference(); if (reference) { HelloService* service = qobject_cast(context->getService(reference)); if (service != Q_NULLPTR) { service->sayHello(); } qDebug() << "The first call: " << service; } // 第二次访问服务 reference = context->getServiceReference(); if (reference) { HelloService* service = qobject_cast(context->getService(reference)); if (service != Q_NULLPTR) { service->sayHello(); } qDebug() << "The second call: " << service; } } void PluginAActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pPlugin; m_pPlugin = Q_NULLPTR; } ================================================ FILE: ServiceFactory/Plugins/PluginA/plugin_a_activator.h ================================================ #ifndef PLUGIN_A_ACTIVATOR_H #define PLUGIN_A_ACTIVATOR_H #include class PluginAImpl; class PluginAActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "PLUGIN_A") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: PluginAImpl *m_pPlugin; }; #endif // PLUGIN_A_ACTIVATOR_H ================================================ FILE: ServiceFactory/Plugins/PluginA/plugin_a_impl.cpp ================================================ #include "plugin_a_impl.h" #include PluginAImpl::PluginAImpl() { } void PluginAImpl::doSomething() { qDebug() << "Do something...A"; } ================================================ FILE: ServiceFactory/Plugins/PluginA/plugin_a_impl.h ================================================ #ifndef PLUGIN_A_IMPL_H #define PLUGIN_A_IMPL_H #include "plugin_a_service.h" #include class PluginAImpl : public QObject, public PluginAService { Q_OBJECT Q_INTERFACES(PluginAService) public: PluginAImpl(); void doSomething() Q_DECL_OVERRIDE; }; #endif // PLUGIN_A_IMPL_H ================================================ FILE: ServiceFactory/Plugins/PluginA/plugin_a_service.h ================================================ #ifndef PLUGIN_A_SERVICE_H #define PLUGIN_A_SERVICE_H #include class PluginAService { public: virtual ~PluginAService() {} virtual void doSomething() = 0; }; #define PluginAService_iid "org.commontk.service.demos.PluginAService" Q_DECLARE_INTERFACE(PluginAService, PluginAService_iid) #endif // PLUGIN_A_SERVICE_H ================================================ FILE: ServiceFactory/Plugins/PluginB/MANIFEST.MF ================================================ Plugin-SymbolicName: Plugin.B Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for test Plugin-Name: PluginB Plugin-Vendor: myh Plugin-Version: 1.0.0.beta ================================================ FILE: ServiceFactory/Plugins/PluginB/PluginB.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = PluginB DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ plugin_b_service.h \ plugin_b_impl.h \ plugin_b_activator.h SOURCES += \ plugin_b_impl.cpp \ plugin_b_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: ServiceFactory/Plugins/PluginB/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: ServiceFactory/Plugins/PluginB/plugin_b_activator.cpp ================================================ #include "plugin_b_impl.h" #include "plugin_b_activator.h" #include "../Hello/hello_service.h" #include void PluginBActivator::start(ctkPluginContext* context) { m_pPlugin = new PluginBImpl(); context->registerService(m_pPlugin); // 访问服务 ctkServiceReference reference = context->getServiceReference(); if (reference) { HelloService* service = qobject_cast(context->getService(reference)); if (service != Q_NULLPTR) { service->sayHello(); } } } void PluginBActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pPlugin; m_pPlugin = Q_NULLPTR; } ================================================ FILE: ServiceFactory/Plugins/PluginB/plugin_b_activator.h ================================================ #ifndef PLUGIN_B_ACTIVATOR_H #define PLUGIN_B_ACTIVATOR_H #include class PluginBImpl; class PluginBActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "PLUGIN_B") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: PluginBImpl *m_pPlugin; }; #endif // PLUGIN_B_ACTIVATOR_H ================================================ FILE: ServiceFactory/Plugins/PluginB/plugin_b_impl.cpp ================================================ #include "plugin_b_impl.h" #include PluginBImpl::PluginBImpl() { } void PluginBImpl::doSomething() { qDebug() << "Do something...B"; } ================================================ FILE: ServiceFactory/Plugins/PluginB/plugin_b_impl.h ================================================ #ifndef PLUGIN_B_IMPL_H #define PLUGIN_B_IMPL_H #include "plugin_b_service.h" #include class PluginBImpl : public QObject, public PluginBService { Q_OBJECT Q_INTERFACES(PluginBService) public: PluginBImpl(); void doSomething() Q_DECL_OVERRIDE; }; #endif // PLUGIN_B_IMPL_H ================================================ FILE: ServiceFactory/Plugins/PluginB/plugin_b_service.h ================================================ #ifndef PLUGIN_B_SERVICE_H #define PLUGIN_B_SERVICE_H #include class PluginBService { public: virtual ~PluginBService() {} virtual void doSomething() = 0; }; #define PluginBService_iid "org.commontk.service.demos.PluginBService" Q_DECLARE_INTERFACE(PluginBService, PluginBService_iid) #endif // PLUGIN_B_SERVICE_H ================================================ FILE: ServiceFactory/Plugins/Plugins.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ Hello \ PluginA \ PluginB CONFIG += ordered ================================================ FILE: ServiceFactory/ServiceFactory.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ App \ Plugins CONFIG += ordered ================================================ FILE: ServiceFactory/ServiceFactory.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-ServiceFactory-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/build-ServiceFactory-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\build-ServiceFactory-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/build-ServiceFactory-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-ServiceFactory-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/build-ServiceFactory-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/ServiceFactory/App/App.pro C:/d/mmm/qt/ctk/CTK-examples/ServiceFactory/App/App.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/build-ServiceFactory-Desktop_Qt_5_15_1_MSVC2019_64bit-Release/App/../bin 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: ServiceTracker/App/App.pro ================================================ QT += core QT -= gui TARGET = ServiceTracker CONFIG += console TEMPLATE = app DESTDIR = $$OUT_PWD/../bin include($$PWD/../CTK.pri) SOURCES += main.cpp ================================================ FILE: ServiceTracker/App/main.cpp ================================================ // main.cpp #include #include #include #include #include #include #include #include "../Plugins/Login/login_service.h" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); ctkPluginFrameworkFactory frameWorkFactory; QSharedPointer framework = frameWorkFactory.getFramework(); try { // 初始化并启动插件框架 framework->init(); framework->start(); qDebug() << "CTK Plugin Framework start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to initialize the plugin framework: " << e.what(); return -1; } // 获取插件上下文 ctkPluginContext* context = framework->getPluginContext(); // 获取插件所在位置 QString path = QCoreApplication::applicationDirPath() + "/plugins"; // 遍历路径下的所有插件 QDirIterator itPlugin(path, QStringList() << "*.dll" << "*.so", QDir::Files); while (itPlugin.hasNext()) { QString strPlugin = itPlugin.next(); try { // 安装插件 QSharedPointer plugin = context->installPlugin(QUrl::fromLocalFile(strPlugin)); // 启动插件 plugin->start(ctkPlugin::START_TRANSIENT); qDebug() << "Plugin start ..."; } catch (const ctkPluginException &e) { qDebug() << "Failed to install plugin" << e.what(); return -1; } } // 获取服务引用 ctkServiceReference reference = context->getServiceReference(); if (reference) { // 获取指定 ctkServiceReference 引用的服务对象 LoginService* service = qobject_cast(context->getService(reference)); if (service != Q_NULLPTR) { // 调用服务 service->login("root", "123456"); } } return app.exec(); } ================================================ FILE: ServiceTracker/CTK.pri ================================================ # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../CTKInstall # CTK 插件相关库所在路径(例如:CTKCore.lib、CTKPluginFramework.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 插件相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # CTK 插件相关头文件所在路径(主要因为用到了 service 相关东西) CTK_INCLUDE_FRAMEWORK_PATH = $$PWD/../../CTK-master/Libs/PluginFramework LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKPluginFramework INCLUDEPATH += $$CTK_INCLUDE_PATH \ $$CTK_INCLUDE_FRAMEWORK_PATH ================================================ FILE: ServiceTracker/Plugins/Log/Log.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = Log DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ log_service.h \ log_impl.h \ log_activator.h SOURCES += \ log_activator.cpp \ log_impl.cpp RESOURCES += Resource.qrc ================================================ FILE: ServiceTracker/Plugins/Log/MANIFEST.MF ================================================ Plugin-SymbolicName: Log Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for log Plugin-Name: Log Plugin-Vendor: myh Plugin-Version: 1.0.0 ================================================ FILE: ServiceTracker/Plugins/Log/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: ServiceTracker/Plugins/Log/log_activator.cpp ================================================ #include "log_impl.h" #include "log_activator.h" #include #include void LogActivator::start(ctkPluginContext* context) { m_pPlugin = new LogImpl(); context->registerService(m_pPlugin); } void LogActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) delete m_pPlugin; m_pPlugin = Q_NULLPTR; } ================================================ FILE: ServiceTracker/Plugins/Log/log_activator.h ================================================ #ifndef LOG_ACTIVATOR_H #define LOG_ACTIVATOR_H #include class LogImpl; class LogActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "LOG") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: LogImpl *m_pPlugin; }; #endif // LOG_ACTIVATOR_H ================================================ FILE: ServiceTracker/Plugins/Log/log_impl.cpp ================================================ #include "log_impl.h" #include LogImpl::LogImpl() { } void LogImpl::debug(QString msg) { qDebug() << "This is a debug message: " << msg; } ================================================ FILE: ServiceTracker/Plugins/Log/log_impl.h ================================================ #ifndef LOG_IMPL_H #define LOG_IMPL_H #include "log_service.h" #include class LogImpl : public QObject, public LogService { Q_OBJECT Q_INTERFACES(LogService) public: LogImpl(); void debug(QString msg) Q_DECL_OVERRIDE; }; #endif // LOG_IMPL_H ================================================ FILE: ServiceTracker/Plugins/Log/log_service.h ================================================ #ifndef LOG_SERVICE_H #define LOG_SERVICE_H #include class LogService { public: virtual ~LogService() {} virtual void debug(QString msg) = 0; }; #define LogService_iid "org.commontk.service.demos.LogService" Q_DECLARE_INTERFACE(LogService, LogService_iid) #endif // LOG_SERVICE_H ================================================ FILE: ServiceTracker/Plugins/Login/Login.pro ================================================ QT += core QT -= gui TEMPLATE = lib CONFIG += plugin TARGET = Login DESTDIR = $$OUT_PWD/../../bin/plugins include($$PWD/../../CTK.pri) HEADERS += \ login_service.h \ login_impl.h \ login_activator.h \ service_tracker.h SOURCES += \ login_impl.cpp \ login_activator.cpp RESOURCES += Resource.qrc ================================================ FILE: ServiceTracker/Plugins/Login/MANIFEST.MF ================================================ Plugin-SymbolicName: Login Plugin-ActivationPolicy: eager Plugin-Category: Demos Plugin-ContactAddress: https://github.com/myhhub Plugin-Description: A plugin for login Plugin-Name: Login Plugin-Vendor: myh Plugin-Version: 1.0.0 ================================================ FILE: ServiceTracker/Plugins/Login/Resource.qrc ================================================ MANIFEST.MF ================================================ FILE: ServiceTracker/Plugins/Login/login_activator.cpp ================================================ #include "login_impl.h" #include "login_activator.h" #include "service_tracker.h" #include void LoginActivator::start(ctkPluginContext* context) { // 开启服务跟踪器 m_pTracker = new ServiceTracker(context); m_pTracker->open(); m_pPlugin = new LoginImpl(m_pTracker); m_registration = context->registerService(m_pPlugin); } void LoginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) // 注销服务 m_registration.unregister(); // 关闭服务跟踪器 m_pTracker->close(); delete m_pPlugin; m_pPlugin = Q_NULLPTR; } ================================================ FILE: ServiceTracker/Plugins/Login/login_activator.h ================================================ #ifndef LOGIN_ACTIVATOR_H #define LOGIN_ACTIVATOR_H #include class LoginImpl; class ServiceTracker; class LoginActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) Q_PLUGIN_METADATA(IID "LOGIN") public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: LoginImpl *m_pPlugin; ServiceTracker* m_pTracker; ctkServiceRegistration m_registration; }; #endif // LOGIN_ACTIVATOR_H ================================================ FILE: ServiceTracker/Plugins/Login/login_impl.cpp ================================================ #include "login_impl.h" #include "service_tracker.h" LoginImpl::LoginImpl(ServiceTracker *tracker) : m_pTracker(tracker) { } bool LoginImpl::login(const QString& username, const QString& password) { LogService* service = (LogService*)(m_pTracker->getService()); if (QString::compare(username, "root") == 0 && QString::compare(password, "123456") == 0) { if (service != Q_NULLPTR) service->debug("Login successfully"); return true; } else { if (service != Q_NULLPTR) service->debug("Login failed"); return false; } } ================================================ FILE: ServiceTracker/Plugins/Login/login_impl.h ================================================ #ifndef LOGIN_IMPL_H #define LOGIN_IMPL_H #include "login_service.h" #include class ServiceTracker; class LoginImpl : public QObject, public LoginService { Q_OBJECT Q_INTERFACES(LoginService) public: LoginImpl(ServiceTracker *tracker); bool login(const QString& username, const QString& password) Q_DECL_OVERRIDE; private: ServiceTracker *m_pTracker; }; #endif // LOGIN_IMPL_H ================================================ FILE: ServiceTracker/Plugins/Login/login_service.h ================================================ #ifndef LOGIN_SERVICE_H #define LOGIN_SERVICE_H #include class LoginService { public: virtual ~LoginService() {} virtual bool login(const QString& username, const QString& password) = 0; }; #define LoginService_iid "org.commontk.service.demos.LoginService" Q_DECLARE_INTERFACE(LoginService, LoginService_iid) #endif // LOGIN_SERVICE_H ================================================ FILE: ServiceTracker/Plugins/Login/service_tracker.h ================================================ #ifndef SERVICE_TRACKER_H #define SERVICE_TRACKER_H #include #include #include "../Log/log_service.h" class ServiceTracker : public ctkServiceTracker { public: ServiceTracker(ctkPluginContext* context) : ctkServiceTracker(context) {} ~ServiceTracker() {} protected: // 在 Service 注册时访问 LogService* addingService(const ctkServiceReference& reference) Q_DECL_OVERRIDE { qDebug() << "Adding service:" << reference.getPlugin()->getSymbolicName(); // return ctkServiceTracker::addingService(reference); LogService* service = (LogService*)(ctkServiceTracker::addingService(reference)); if (service != Q_NULLPTR) { service->debug("Ok"); } return service; } void modifiedService(const ctkServiceReference& reference, LogService* service) Q_DECL_OVERRIDE { qDebug() << "Modified service:" << reference.getPlugin()->getSymbolicName(); ctkServiceTracker::modifiedService(reference, service); } void removedService(const ctkServiceReference& reference, LogService* service) Q_DECL_OVERRIDE { qDebug() << "Removed service:" << reference.getPlugin()->getSymbolicName(); ctkServiceTracker::removedService(reference, service); } }; #endif // SERVICE_TRACKER_H ================================================ FILE: ServiceTracker/Plugins/Plugins.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ Login \ Log CONFIG += ordered ================================================ FILE: ServiceTracker/ServiceTracker.pro ================================================ TEMPLATE = subdirs SUBDIRS += \ App \ Plugins CONFIG += ordered ================================================ FILE: ServiceTracker/ServiceTracker.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-ServiceTracker-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/build-ServiceTracker-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\build-ServiceTracker-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/build-ServiceTracker-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-ServiceTracker-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/build-ServiceTracker-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/ServiceTracker/App/App.pro C:/d/mmm/qt/ctk/CTK-examples/ServiceTracker/App/App.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/build-ServiceTracker-Desktop_Qt_5_15_1_MSVC2019_64bit-Release/App/../bin 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: UseCTKWidgets/UseCTKWidgets.pro ================================================ QT += core gui widgets TARGET = UseCTKWidgets TEMPLATE = app # CTK 安装路径 CTK_INSTALL_PATH = $$PWD/../../CTKInstall # CTK 相关库所在路径(例如:CTKCore.lib、CTKWidgets.lib) CTK_LIB_PATH = $$CTK_INSTALL_PATH/lib/ctk-0.1 # CTK 相关头文件所在路径(例如:ctkPluginFramework.h) CTK_INCLUDE_PATH = $$CTK_INSTALL_PATH/include/ctk-0.1 # 相关库文件(CTKCore.lib、CTKWidgets.lib) LIBS += -L$$CTK_LIB_PATH -lCTKCore -lCTKWidgets INCLUDEPATH += $$CTK_INCLUDE_PATH SOURCES += main.cpp ================================================ FILE: UseCTKWidgets/UseCTKWidgets.pro.user ================================================ EnvironmentId {c4da1889-17ad-47a8-bddc-cd90da2180db} ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false true Cpp CppGlobal QmlJS QmlJSGlobal Nim NimGlobal 3 UTF-8 false 4 false 80 true true 1 true false 0 true true 0 8 true 2 true true true *.md, *.MD, Makefile false true ProjectExplorer.Project.PluginSettings true true true true true 0 true -fno-delayed-template-parsing true Builtin.Questionable true Builtin.DefaultTidyAndClazy 4 true ProjectExplorer.Project.Target.0 Desktop Desktop Qt 5.15.1 MSVC2019 64bit Desktop Qt 5.15.1 MSVC2019 64bit qt.qt5.5151.win64_msvc2019_64_kit 1 0 0 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-UseCTKWidgets-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug C:/d/mmm/qt/ctk/CTK-examples/build-UseCTKWidgets-Desktop_Qt_5_15_1_MSVC2019_64bit-Debug true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Debug Qt4ProjectManager.Qt4BuildConfiguration 2 2 2 true 2 C:\d\mmm\qt\ctk\CTK-examples\build-UseCTKWidgets-Desktop_Qt_5_15_1_MSVC2019_64bit-Release C:/d/mmm/qt/ctk/CTK-examples/build-UseCTKWidgets-Desktop_Qt_5_15_1_MSVC2019_64bit-Release true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Release Qt4ProjectManager.Qt4BuildConfiguration 0 0 2 true 0 C:\d\mmm\qt\ctk\CTK-examples\build-UseCTKWidgets-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile C:/d/mmm/qt/ctk/CTK-examples/build-UseCTKWidgets-Desktop_Qt_5_15_1_MSVC2019_64bit-Profile true QtProjectManager.QMakeBuildStep false true Qt4ProjectManager.MakeStep false false 2 Build Build ProjectExplorer.BuildSteps.Build true Qt4ProjectManager.MakeStep true clean false 1 Clean Clean ProjectExplorer.BuildSteps.Clean 2 false Profile Qt4ProjectManager.Qt4BuildConfiguration 0 0 0 3 0 Deploy Deploy ProjectExplorer.BuildSteps.Deploy 1 false ProjectExplorer.DefaultDeployConfiguration 1 dwarf cpu-cycles 250 -e cpu-cycles --call-graph dwarf,4096 -F 250 -F true 4096 false false 1000 true false false false false true 0.01 10 true kcachegrind 1 25 1 true false true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 2 Qt4ProjectManager.Qt4RunConfiguration:C:/d/mmm/qt/ctk/CTK-examples/UseCTKWidgets/UseCTKWidgets.pro C:/d/mmm/qt/ctk/CTK-examples/UseCTKWidgets/UseCTKWidgets.pro false false true true false false true C:/d/mmm/qt/ctk/CTK-examples/build-UseCTKWidgets-Desktop_Qt_5_15_1_MSVC2019_64bit-Release 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 22 Version 22 ================================================ FILE: UseCTKWidgets/main.cpp ================================================ #include #include #include #include #include #include #include int main(int argc, char* argv[]) { QApplication app(argc, argv); // 可折叠按钮 ctkCollapsibleButton* buttons = new ctkCollapsibleButton("Buttons"); // 可勾选按钮 ctkCheckablePushButton* checkablePushButton = new ctkCheckablePushButton(); checkablePushButton->setText("Checkable"); // 颜色拾取器 ctkColorPickerButton* colorPickerButton = new ctkColorPickerButton(); colorPickerButton->setColor(QColor("#9e1414")); ctkCollapsibleButton* sliders = new ctkCollapsibleButton("Sliders"); QFormLayout* buttonsLayout = new QFormLayout; buttonsLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); buttonsLayout->addRow("ctkCheckablePushButton", checkablePushButton); buttonsLayout->addRow("ctkColorPickerButton", colorPickerButton); buttons->setLayout(buttonsLayout); QVBoxLayout* topLevelLayout = new QVBoxLayout(); topLevelLayout->addWidget(buttons); topLevelLayout->addWidget(sliders); QFormLayout* slidersLayout = new QFormLayout; ctkRangeWidget* rangeWidget = new ctkRangeWidget(); slidersLayout->addRow("ctkRangeWidget", rangeWidget); sliders->setLayout(slidersLayout); QWidget topLevel; topLevel.setLayout(topLevelLayout); topLevel.show(); return app.exec(); }