Embedded Components Tutorial - Page 5
[ Page 1 |
2 |
3 |
4 |
5 |
6 |
7 ]
Making the Component Functional
The Plan
You're on the home stretch now. You have a fully working embedded
component -- you just need to make it do something!
This step is one of the shortest ones in this tutorial but will likely
be the hardest in real use. This is where you need to connect your
applications functionality to the KParts interface.
In the case of aKtion, nearly all of the actual "playing" code is
encapsulated in the KXAnim class. This made it very easy to use in a
KParts interface. All that was needed was to replace the QLabel
example with KXAnim and everything worked (mostly).
The Files
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 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();
private:
KXAnim *widget;
};
#endif
| | |
aktion_part.cpp
#include "aktion_part.h"
#include <kinstance.h>
#include <klocale.h>
#include <kaboutdata.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);
// create our animation widget
widget = new KXAnim(canvas);
widget->setLoop(true);
widget->show();
}
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();
}
void AktionPart::slotStop()
{
widget->stop();
}
| | |
Line by Line
There isn't much non-aKtion specific stuff to show in this step. The
two major chunks of code are in the constructor and in the
openFile method.
// create our animation widget
widget = new KXAnim(canvas);
widget->setLoop(true);
widget->show();
This creates our animation widget and sets some default parameters.
widget->setFile(m_file);
widget->stop();
widget->show();
QTimer::singleShot(2000, this, SLOT(slotPlay()));
And this actually plays the file. Some hackery needed to be done to
get it to play due to some timing problems with KXAnim.
And that's pretty much it!
Visible Result
Practical Matters
As said earlier, this is one of the shorted and simplest steps in this
example.. but could easily be the hardest in your own application. It
all depends on how much functionality is encapsulated in your "main"
view object.
The key to this step is to have one view object already in your
application in which all processing of the file takes place. If you
have several classes that all depend on each other with no central
"viewing" object, then you will have problems.
As a case study, KGhostView was one of the hardest programs to port to
the KParts system. The reason for this was that all of the UI
elements were scattered all over the application. There was no one
coherent interface to the UI aspects -- essentially no way for a third
party app to "view" the same thing that KGhostView was.
The solution to this was to create a view class that combined most of
the required UI elements in one place. After this was done, it was
trivial to plug this view into the KParts system.
Things To Remember:
The ease of integrating your application into the KParts
architecture depends almost entirely on how encapsulated your UI
elements are into one coherent interface. The less coherent, the more
problems you will have.
|
|
[ Edit ]