![]() |
rtVTK
0.6.0
|
Plugins are components that can be loaded into rtVTK at runtime to add a rendering algorithm to the program. Your plugin can use any rendering algorithm that you would like to write. There are only a few restrictions on plugins.
The interface for a plugin is defined in PluginInterface.h. You must make a myRendererInterface.cc file that includes PluginInterface.h and makes the calls into your plugin's class. Plugins have an idle function defined by the interface. This is useful for progressive renderers, so that you can watch it as it converges instead of a black screen until the image is finally converged. You must remember though that you need to have any renderers that you plan on having run with such a renderer must also define their own idle function.
Example of how plugins interact: glWidget.h side-by-side with PluginInterface.h
Examples of plugin: glGhost.h and glGhostInterface.cc or rlRenderer.h and reRendererInterface.cc
QObject
and the Q_OBJECT
macro must be called as the first thing in the class declaration. For more information on this, visit the Qt Documentation on Q_OBJECT. QGridLayout
is passed to the function parameter. If you want your plugin to make use of Qt elements they should be added to this QGridLayout
in the plugin class constructor. QGridLayout
, please use the following line in your plugin's interface code so that a blank tab is not given for your plugin: DECLSPEC const bool requiresTab = false;
QGridLayout
, in your plugins destructor you must remove each Qt element from the QGridLayout
and then delete the pointers to those Qt elements. You must not delete the QGridLayout
from your destructor! Example signal/slot connection for a push button:
connect(myPushButton, SIGNAL(pressed()), this, SLOT(slotMyPushButtonPressed()));
sgnlTimerEvent
: public slots with no arguments in your plugin class definition are listed by the Timer Management dialog box, allowing for the rtVTK user to set up custom timers. If your plugin has features that make sense to allow the user to be able to invoke on an interval, in addition to the QLayout, be sure to have a slot with no arguments to invoke the code. For example, rlRenderer has a forward and a backward button. The slots advance and regress tree correspond to those buttons and are able to be invoked by timers. claimKeyCombo
and releaseKeyCombo
: Qt attaches a key shortcut to an action so that your plugin can respond to key strokes. All shortcut key combos must be claimed before using by calling MainWindow::claimKeyCombo
, which will return true if claiming it was successful. An analogy for this procedure would be a library of books. A person checks out a library book. The person possesses the library book. No one can check out the book or read the book until it is returned by the person who checked it out. When the person returns the book, other library patrons can now check out the book. Let plugins be the library patrons and shortcuts be the books. A shortcut can only be checked out (claimed) by maximum of one plugin at any time. No other plugin can use that shortcut until it is checked back in (released). rtVTK::MainWindow is the librarian in this analogy, making sure that books (or plugins) can only be checked out if they are available.
Why the checkout system? Qt doesn't like QShortcuts that don't have unique key sequences. When a key sequence is detected and there are multiple QShortcuts to trigger, Qt doesn't know which to run first, and so, for safety reasons, it refuses to run either and instead announces the conflict. It is perfectly acceptable for a programmer to connect multiple slots to a single QShortcut with a unique key sequence. The goal is to avoid conflicts of key sequences. To accomplish this behavior, we ask that plugin authors claim and release their key sequences to prevent Qt shortcut conflicts.
If your plugin makes use of any shortcuts, please document which ones so other plugin authors will be aware of it and be able to design to avoid shortcut conflicts and failed key sequence claims.
Example shortcut claiming:
QShortcut* myShortcut;
QKeySequence myKeySeq(tr("Ctrl+r"));
if(mainWindowPtr->claimKeyCombo(this, myKeySeq))
{
// The new shortcut must be a child of the MainWindow.
myShortcut = new QShortcut(myKeySeq, mainWindowPtr);
// Typically, you will want your shortcut to be application wide.
myShortcut->setContext(Qt::ApplicationShortcut);
// Qt connection of the shortcut to the local slot.
connect(myShortcut, SIGNAL(activated()),
this, SLOT(slotMyLocalPluginFcn()));
}
else
{
// Ground the pointer if it failed to be claimed.
myShortcut = 0;
}
Example of shortcut releasing (typically preformed during a destructor):
// Disconnect shortcut only if the pointer isn't null.
if(myShortcut != 0)
{
myShortcut->setEnabled(false);
disconnect(myShortcut, SIGNAL(activated()),
this, SLOT(slotMyLocalPluginFcn()));
if(mainWindowPtr->releaseKeyCombo(this, "Ctrl+r"))
{
// If key combo was released successfully, delete the dynamic shortcut.
delete myShortcut;
}
}
getTakenKeyCombos
: returns the address of the std::set being used to store the list of key combos that are currently claimed at that moment during runtime. This can be useful if you wish to search through the set on your own. Modifying the data in the data structure has been disallowed.
getGLW()
. Here are a few common slots and signals:slotRender()
: anytime your plugin needs to start rendering from scratch, it should emit a signal to rtVTK::glWidget's slotRender()
so that rtVTK::glWidget can begin running through the visualization pipeline. Be advised that this is equivalent to how a camera change caused by a mouse drag restarts the rendering, which will lose all of the calculations for progressive renderers up to that point that had been done during idling. sgnlMousePressEvent(QMouseEvent*)
: anytime the mouse is clicked inside the draw area this signal will fire. You can get relative x, y coordinates of the click. sgnlMouseMoveEvent(QMouseEvent*)
: anytime the mouse is moved this signal is fired. You can get the move distance from this signal. sgnlMouseReleaseEvent(QMouseEvent*)
: whenever the mouse button is released this signal will fire. This is useful for finding the end of a drag.