Cube GUI Plugin User Guide  (CubeGUI 4.6, revision ff50a50d)
How to develop a Cube GUI Plugin, road map and examples
Step by step example for CubePlugin

The following sections describe the steps that are required to create a plugin. For simplicity, a separate project is created and the generated binary will to be copied to the plugin directory of the given cube installation.

Files of the simple cube plugin project:

Qt project file

To create a cube plugin, a makefile and source files have to be generated. The makefile can be generated automatically from a Qt project file

First we specify the path to the "cube-config" script of the cube installation. This script delivers correct flags for compiling and linking.

CUBELIB_CONFIG = @CUBE_CUBELIB@
INCLUDEPATH += $$system($$CUBEGUI_CONFIG --include) $$system($$CUBELIB_CONFIG --include)
LIBS += $$system($$CUBEGUI_CONFIG --ldflags) $$system($$CUBEGUI_CONFIG --libs)
TEMPLATE = lib
CONFIG += plugin
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
HEADERS = SimpleExample.h
SOURCES = SimpleExample.cpp
TARGET = $$qtLibraryTarget(SimpleExamplePlugin)

qmake && make will build the first plugin example libExamplePluginSimple.so. The plugin will be copied to the plugin directory, e.g. /opt/cube/lib64/plugins.

SimpleExample.h

The example describes a minimal cube plugin, which is inserted as an additional tab next to the SystemTree. It shows the text of the recently selected tree item. The complete source of the example can be found in $CUBE_INSTALL_PREFIX/share/doc/cube/example/gui/plugin-example.

Every cube plugin has to derive from cubepluginapi::CubePlugin. To use Qt's signal and slot mechanism it also has to derive from QObject. If the plugin should be added as a tab next to a tree widget, it has to derive from cubegui::TabInterface.

class SimpleExample : public QObject, public cubepluginapi::CubePlugin, cubepluginapi::TabInterface

The class header is followed by the following macro definitions:

class SimpleExample : public QObject, public cubepluginapi::CubePlugin, cubepluginapi::TabInterface
{
Q_OBJECT
Q_INTERFACES( cubepluginapi::CubePlugin )
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA( IID "SimpleExamplePlugin" ) // unique plugin name
#endif

The class SimpleExample has to implement the pure virtual methods from cubepluginapi::CubePlugin and cubegui::TabInterface.

public:
SimpleExample();
// CubePlugin implementation
virtual bool
cubeOpened( cubepluginapi::PluginServices* service );
virtual void
cubeClosed();
virtual QString
name() const;
virtual void
version( int& major,
int& minor,
int& bugfix ) const;
virtual QString
getHelpText() const;
// TabInterface implementation
virtual QString
label() const;
virtual QWidget*
widget();

SimpleExample.cpp

SimpleExample.cpp

For Qt versions < 5.0, Q_EXPORT_PLUGIN2 is used to export the plugin. The first argument is a unique name for the plugin, the second the name of the class.

using namespace cubepluginapi;
using namespace simpleexampleplugin;
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2( SimpleExamplePlugin, SimpleExample ); // ( PluginName, ClassName )
#endif

The function cubeOpened(PluginServices* service) is the starting point of our plugin. Allocation of data and GUI objects should be done here, not in the constructor. This allows to free the resources, if the plugin is deactivated.

Here we create the main widget, which should be added as a system tab. Our plugin derives from TabInterface, so service->addTab(SYSTEMTAB, this) can be called.

If the user selects a tree item, service will emit a corresponding signal. To react on this event, the signal has to be connected to the slot treeItemIsSelected() of our plugin class.

The function returns true, if the plugin should be started. It it returns false, the plugin is closed and deleted.

The function cubeClosed() is called if the cube file is closed or if the plugin is unloaded by the user. All resources which have been allocated in cubeOpened have to be deleted here.

bool
SimpleExample::cubeOpened( PluginServices* service )
{
this->service = service;
widget_ = new QWidget();
qlabel_ = new QLabel( "example string" );
QVBoxLayout* layout = new QVBoxLayout();
widget_->setLayout( layout );
layout->addWidget( qlabel_ );
service->addTab( SYSTEM, this );
connect( service, SIGNAL( treeItemIsSelected( cubepluginapi::TreeItem* ) ),
this, SLOT( treeItemIsSelected( cubepluginapi::TreeItem* ) ) );
return true; // initialisation is ok => plugin should be shown
}
void
SimpleExample::cubeClosed()
{
delete widget_;
}

Each plugin has to set a version number. If several plugins with the same identifier (see function name()) exist, the one with the highest version number will be loaded.

void
SimpleExample::version( int& major, int& minor, int& bugfix ) const
{
major = 1;
minor = 0;
bugfix = 0;
}

This function returns the unique plugin name. Only one plugin with this name will be loaded.

QString
SimpleExample::name() const
{
return "Simple Example";
}

The following function returns a text to describe the plugin. It will be used by help menu of the cube GUI.

QString
SimpleExample::getHelpText() const
{
return "Just a simple example.";
}

The following two functions contain the implementation of TabInterface.

The function widget() returns the QWidget that will be placed into the tab, which has been created with service->addTab in initialize().

QWidget*
SimpleExample::widget()
{
return widget_;
}

The function label() returns the label of the new tab.

QString
SimpleExample::label() const
{
return "Example Plugin Label";
}

This method is a slot, which is called if a tree item is selected. The argument provides information about the selected item. With item->getDisplayType(), the location (METRIC, CALL, SYSTEM) can be identified.

void
SimpleExample::treeItemIsSelected( TreeItem* item )
{
QString txt = item->getName() + " " + QString::number( item->getValue() );
qlabel_->setText( txt );
}


Cube Writer Library    Copyright © 1998–2021 Forschungszentrum Jülich GmbH, Jülich Supercomputing Centre
Copyright © 2009–2015 German Research School for Simulation Sciences GmbH, Laboratory for Parallel Programming