Plugins - labsquare/cutevariant GitHub Wiki

Plugins

Plugins make possible to enhance cutevariant application with different kind of widget like QDockWidget.

Plugin directory structure

To create a plugin, you must write a python package with at least two files. __init__.py and widget.py into the plugins directory. The following tree illustrates the plugins folder with 1 plugin:

Example:

└── plugins
    └── plugin_name
        ├── __init__.py
        ├── widgets.py

A plugin directory must be named in snake_case. It contains modules whose will be described later and a init.py file which describes the plugin with the following mandatory variables:

    __title__ = "PluginName"
    __description__ = "A plugin to cook variants"
    __author__ = "E. Micron"
    __version__ = "1.0.0"

Note:

  • __title__ will be used on the GUI for the name of the plugin.
  • __long_description__ can be used to provide high quality helper text via tooltip or What's This functionality (question mark button on top of all windows). It can be written in html. If it is not specified, the variable __description__ will be used instead.

Plugin types

Three kinds of plugins are supported, each one corresponds to a module in a plugin directory.

  • Module named widgets.py: widget type: Parent class PluginWidget; Widget will be displayed on the main window according to the widget_location .
  • Module named dialogs.py: dialog type: Parent class PluginDialog; Dialog widget will be accessible from the tool menu.
  • Module named settings.py: setting type: Parent class PluginSettingsWidget; Widget will be accessible from the settings of the app.

That is, a plugin can support these 3 types simultaneously, but types must be unique (i.e. no multiple widgets, or dialogs, or settings).

Module content

Instantiated classes of the modules will be those that inherit of the expected parent class associated to their types (widget, dialog, setting).

In other words, each module must contains one class that inherits from PluginWidget or PluginDialog or PluginSettingsWidget.

These classes must be named in accordance to the name of the plugin directory followed by the corresponding type, in the CamelCase convention.

Example:

A plugin word_set could contain one module named widgets.py. This module contains almost one class named WordSetWidget that inherits from PluginWidget.


Plugin types in detail

PluginWidget example

The widgets module must contain a class called [Name]Widget which inherits from PluginWidget . The prefix [Name] of this class must be the same as the module Name capitalized. For instance, if the module name is felix, the class must be named FelixWidget. You can override methods descrive above bellow to react with the application.

Example:

from PySide2.QtWidgets import *
from cutevariant.gui import plugin

class FelixWidget(plugin.PluginWidget):
    LOCATION = DOCK_LOCATION
    def __init__(self, parent=None):
        super().__init__(parent)
        main_layout = QVBoxLayout()
        main_layout.addWidget(QPushButton("hello felix"))
        self.setLayout(main_layout)

    def on_register(self, mainwindow):
        '''call at startup when plugin is register to the mainview '''
        pass 

    def on_open_project(self, conn):
        '''call when opening a new project as sqlite connection '''
        pass
   
    def on_refresh(self):
        '''call each time the plugin is asked for refresh. For instance when a VQL has been updated '''
        pass



# You can test the plugin directly by running the script bellow 
if __name__ == "__main__":
    app = QApplication(sys.argv)
    plugin = FelixWidget()
    w = p.get_widget()
    w.show()
    app.exec_()

Widget Location

You can specify with LOCATION class attribute the region of the mainwindow where the widget will be installed. There are 3 possibles locations:DOCK_LOCATION, CENTRAL_LOCATION, FOOTER_LOCATION.

PluginSettingsWidget

If you create a class derived from PluginSettingsWidget, it will create an entry in settings dialog.

Example:

from cutevariant.gui import plugin, settings

class CityPane(settings.PageWidget):
     def load(self):
         return True
     def save(self):
         return True 

class StylePane(settings.PageWidget):
     def load(self):
         return True
     def save(self):
         return True 

class FelixSettingsWidget(plugin.SectionWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.add_settings_widget(CityPane())
        self.add_settings_widget(StylePane())