Embedded Components Tutorial - Page 6
[ Page 1 |
2 |
3 |
4 |
5 |
6 |
7 ]
Finishing Off With KAction
The aKtion embedded component needs only one thing, now -- it's Play,
Stop, Forward, and Backward buttons displayed on Konqueror's toolbar
and View menu.
This is done by creating "actions" corresponding to those, well,
actions. The resulting actions (encapsulated in the KAction class)
can then be "plugged" or unplugged into toolbar or menubars or pretty
much anywhere else. The location of these actions will be described
in an XML file.
As with everything else, this takes only a few lines of code.
Here is the aktion_part.h file with the necessary changes in bold:
aktion_part.h
#ifndef __aktion_part_h__
#define __aktion_part_h__
#include <kparts/browserextension.h>
#include <klibloader.h>
class KInstance;
class KXAnim;
class AktionBrowserExtension;
class KAction;
class AktionFactory : public KLibFactory
{
Q_OBJECT
public:
AktionFactory();
virtual ~AktionFactory();
virtual QObject* create(QObject* parent = 0, const char* name = 0,
const char* classname = "QObject",
const QStringList &args = QStringList());
static KInstance *instance();
private:
static KInstance *s_instance;
};
class AktionPart: public KParts::ReadOnlyPart
{
Q_OBJECT
public:
AktionPart(QWidget *parent, const char *name);
virtual ~AktionPart();
virtual bool closeURL();
protected:
virtual bool openFile();
protected slots:
void slotPlay();
void slotStop();
void slotForward();
void slotBackward();
private:
KXAnim *widget;
AktionBrowserExtension *m_extension;
KAction *m_playAction;
KAction *m_stopAction;
KAction *m_forwardAction;
KAction *m_backwardAction;
};
class AktionBrowserExtension : public KParts::BrowserExtension
{
Q_OBJECT
friend class AktionPart;
public:
AktionBrowserExtension(AktionPart *parent);
virtual ~AktionBrowserExtension();
};
#endif
| | |
Thing To Remember:
Each real action ("play", "cut", "quit") in your application
should have exactly one corresponding KAction
|
|
Here is the aktion_part.cpp file with changes in bold:
aktion_part.cpp
#include "aktion_part.h"
#include <kinstance.h>
#include <klocale.h>
#include <kaboutdata.h>
#include <kaction.h>
#include "kxanim.h"
#include <qtimer.h>
extern "C"
{
/**
* This function is the 'main' function of this part. It takes
* the form 'void *init_lib<library name>()'. It always returns a
* new factory object
*/
void *init_libaktion()
{
return new AktionFactory;
}
};
/**
* We need one static instance of the factory for our C 'main'
* function
*/
KInstance *AktionFactory::s_instance = 0L;
AktionFactory::AktionFactory()
{
}
AktionFactory::~AktionFactory()
{
if (s_instance)
delete s_instance;
s_instance = 0;
}
QObject *AktionFactory::create(QObject *parent, const char *name, const char*,
const QStringList& )
{
QObject *obj = new AktionPart((QWidget*)parent, name);
emit objectCreated(obj);
return obj;
}
KInstance *AktionFactory::instance()
{
if ( !s_instance )
{
KAboutData about("aktion", I18N_NOOP("aKtion"), "1.99");
s_instance = new KInstance(&about);
}
return s_instance;
}
AktionPart::AktionPart(QWidget *parent, const char *name)
: KParts::ReadOnlyPart(parent, name)
{
setInstance(AktionFactory::instance());
// create a canvas to insert our widget
QWidget *canvas = new QWidget(parent);
canvas->setFocusPolicy(QWidget::ClickFocus);
setWidget(canvas);
m_extension = new AktionBrowserExtension(this);
// create our animation widget
widget = new KXAnim(this);
widget->setLoop(true);
widget->show();
// create and connect our actions
m_playAction = new KAction(i18n("Play"), QIconSet(BarIcon("tocar",
AktionFactory::instance())), 0, this,
SLOT(slotPlay()), actionCollection(),
"play");
m_stopAction = new KAction(i18n("Stop"), QIconSet(BarIcon("parar",
AktionFactory::instance())), 0, this,
SLOT(slotStop()), actionCollection(),
"stop");
m_backwardAction = new KAction(i18n("Backward"),
QIconSet(BarIcon("retroceder",
AktionFactory::instance())), 0, this,
SLOT(slotBackward()), actionCollection(),
"backward");
m_forwardAction = new KAction(i18n("Forward"), QIconSet(BarIcon("avanzar",
AktionFactory::instance())), 0, this,
SLOT(slotForward()), actionCollection(),
"forward");
setXMLFile("aktion_part.rc");
}
AktionPart::~AktionPart()
{
slotStop();
}
bool AktionPart::openFile()
{
widget->setFile(m_file);
widget->stop();
widget->show();
QTimer::singleShot(2000, this, SLOT(slotPlay()));
return true;
}
bool AktionPart::closeURL()
{
slotStop();
return true;
}
void AktionPart::slotPlay()
{
widget->play();
m_playAction->setEnabled(false);
m_stopAction->setEnabled(true);
m_forwardAction->setEnabled(true);
m_backwardAction->setEnabled(true);
}
void AktionPart::slotStop()
{
widget->stop();
m_playAction->setEnabled(true);
m_stopAction->setEnabled(false);
m_forwardAction->setEnabled(false);
m_backwardAction->setEnabled(false);
}
void AktionPart::slotForward()
{
widget->stepForward();
}
void AktionPart::slotBackward()
{
widget->stepBack();
}
AktionBrowserExtension::AktionBrowserExtension(AktionPart *parent)
: KParts::BrowserExtension(parent, "AktionBrowserExtension")
{
}
AktionBrowserExtension::~AktionBrowserExtension()
{
}
| | |
Using actions always follow the same steps:
- Create KAction with name, icon(s), keyboard shortcut, and slot
- Connect the action with any toolbars/menubars/etc that you want it
to display on using an XML file
Thing To Remember:
There are only two necessary steps to use actions with KParts
1. Create a KAction (or derived class) for each real action
2. Connect the KAction to the toolbar/menubars in an XML file
|
|
The first step is done with this line:
m_playAction = new KAction(i18n("Play"), QIconSet(BarIcon("tocar",
AktionFactory::instance())), 0, this,
SLOT(slotPlay()), actionCollection(),
"play");
This creates a new action with the following parameters:
Text to display - "Play"
Icon to display - tocar.png
Keyboard accel - none
SLOT parent - current widget
SLOT - slotPlay()
Action parent - the KParts action collection
action name - used to match XML description with action
As a side note, KDE has a number of standard actions available for
use. They take advantage of the fact that certain actions (like
"quit", "open document", etc) have standard text, icons, and keyboard
accelerators. These parameters are encapsulated into KStdAction
actions. You, as a developer using them, need only supply a SLOT to
connect to. aKtion does not use any standard actions, hence they are
not used here.
The second step (connecting the action to our widgets) is accomplished
with in this file:
aktion_part.rc
<!DOCTYPE kpartgui>
<kpartgui name="aktion">
<MenuBar>
<Menu name="view">
<Action name="play"/>
<Action name="stop"/>
<Action name="backward"/>
<Action name="forward"/>
</Menu>
</MenuBar>
<ToolBar name="Aktion-ToolBar">
<Action name="play"/>
<Action name="stop"/>
<Action name="backward"/>
<Action name="forward"/>
</ToolBar>
<StatusBar/>
</kpartgui>
| | |
You can see that each action has a corresponding Action item in the
XML. The names for the Menu and ToolBars are either specific or
generic depending on what you want them to do. If you use a reserved
name like "view" or "edit", then your actions will be plugged into an
existing menu or toolbar. If you use a new name like
"Aktion-ToolBar", then you will get a new toolbar.
You'll also need to add the following lines to your Makefile.am:
# this is where the menu and toolbar description file goes
partdir = $(kde_datadir)/aktion
part_DATA = aktion_part.rc
That's pretty much it!
As you saw, this code was pretty straight-forward. There really
wasn't anything specific to aKtion, here. Do check the KStdAction
actions before creating your own, however. Using those actions are
strongly encouraged.
[ Edit ]