Plugin Life Cycle
To be able to write Qt Creator plugins, you must understand the steps that the plugin manager takes when you start or shut down Qt Creator. This section describes the process and the state that plugins go through in detail.
You can get more information about what happens when you start Qt Creator by running it with the environment variable QT_LOGGING_RULES
set to qtc.extensionsystem*=true
which enables logging of plugin-related debug output.
When you start Qt Creator, the plugin manager does the following:
- Looks in its search paths for all dynamic libraries, and reads their meta data. All libraries without meta data and all libraries without the
org.qt-project.Qt.QtCreatorPlugin
IID are ignored. This is the first point where loading a plugin can fail in the worst case of malformed meta data. - Creates an instance of the ExtensionSystem::PluginSpec class for each plugin. This class is a container for all the information from the plugin specification, and additionally tracks the state of the plugin. You can get the ExtensionSystem::PluginSpec instances via the plugin manager's plugins() function.
- Sets the plugins to
Read
state. - Verifies that the dependencies of each plugin exist and are compatible. For more information about plugin dependencies, see Plugin Meta Data.
- Sets the plugins to
Resolved
state. - Sorts all plugins into a list that we call the load queue, where the dependencies of a plugin are positioned after the plugin (but not necessarily directly after the plugin). It will make sure that we load and initialize the plugins in proper order.
- Loads the plugins' libraries, and creates their IPlugin instances in the order of the load queue. At this point the plugin constructors are called. Plugins that other plugins depend on are created first.
- Sets the plugins to
Loaded
state. - Calls the initialize() functions of all plugins in the order of the load queue. In the
initialize
function, a plugin should make sure that all exported interfaces are set up and available to other plugins. A plugin can assume that plugins they depend on have set up their exported interfaces. For example, theCore
plugin sets up the Core::ActionManager, Core::EditorManager and all other publicly available interfaces, so other plugins can request and use them.The initialize() function of a plugin is a good place for
- registering objects in the plugin manager's object pool (see The Plugin Manager, the Object Pool, and Registered Objects)
- loading settings
- adding new menus, and new actions to menus
- connecting to other plugin's signals.
- Sets the plugins to
Initialized
state. - Calls the extensionsInitialized() functions of all plugins in reverse order of the load queue. After the
extensionsInitialized
function, a plugin should be fully initialized, set up and running. A plugin can assume that plugins that depend on it are fully set up, and can finish the initialization of parts that can be extended by other plugins. For example, theCore
plugin assumes that all plugins have registered their actions, and finishes initialization of the action manager. - Sets the plugins to
Running
state.
At the end of startup, the Core
plugin's Core::ICore sends two signals. Before the Qt Creator UI is shown it sends coreAboutToOpen(), and afterwards coreOpened().
After startup, when the event loop of Qt Creator is running, the plugin manager calls the delayedInitialize() functions of all plugins in reverse order of the load queue. The calls are done on the main thread, but separated by a delay of a few milliseconds to ensure responsiveness of Qt Creator. In the delayedInitialize
function, a plugin can perform non-critical initialization that could unnecessarily delay showing the Qt Creator UI if done during startup.
After all delayed initializations are done the PluginManager sends the initializationDone()
signal.
Before shutdown, the Core
plugin Core::ICore sends the coreAboutToClose() signal. After that, the plugin manager starts its shutdown sequence:
- Calls the aboutToShutdown() functions of all plugins in the order of the load queue. Plugins should perform measures for speeding up the actual shutdown here, like disconnecting signals that would otherwise needlessly be called. If a plugin needs to delay the real shutdown for a while, for example if it needs to wait for external processes to finish for a clean shutdown, the plugin can return ExtensionSystem::IPlugin::AsynchronousShutdown from this function. This will make the plugin manager wait with the next step, and keep the main event loop running, until all plugins requesting AsynchronousShutdown have sent the asynchronousShutdownFinished() signal.
- Destroys all plugins by deleting their ExtensionSystem::IPlugin instances in reverse order of the load queue. At this point the plugin destructors are called. Plugins should clean up after themselves by freeing memory and other resources.
© 2024 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.